IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

TCP Raw Socket


Sujet :

Réseau C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4
    Points : 4
    Points
    4
    Par défaut TCP Raw Socket
    Bonjour tout le monde,

    J'ai codé en C, un programme qui forge un paquet TCP avec le flag SYN activé. Mais lorsque je sniffe le paquet avec Wireshark, il me dit que le checksum est invalide, qu'aucun flag n'est activé et il me sort un port de destination/source bidon. Je ne vois pas d'ou cela peut venir ni comment résoudre ça. J'ai essayé d'enlever le define __FAVOR_BSD pour voir si cela changeait et que nenni. J'ai fais des recherches et j'ai vu que soi disant il n'y avait pas besoin de faire un checksum du paquet TCP, il sera fait automatiquement par le kernel. J'ai vu aussi une option HDRINCL, mais ça ne change rien, au contraire ça envoi un paquet TCP mais entièrement vide, sans aucune information.

    Voici une capture d'écran : Wireshark.
    Et voici le code source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #include <arpa/inet.h>
    #include <string.h>
    #include <netinet/ip.h>
    #define __FAVOR_BSD
    #include <netinet/tcp.h>
     
    unsigned short int checksum (unsigned short int *buffer, int size);
     
    int main (void) {
    	srand(time(NULL));
    	int sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
     
    	struct sockaddr_in sin;
    	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(80);
    	memset(&(sin.sin_zero), 0, 8);
     
    	char datagram[4096];
    	struct ip* iph = (struct ip*) datagram;
    	struct tcphdr* tcph = (struct tcphdr*) datagram + sizeof(struct ip);
    	memset(datagram, 0, 4096);
     
    	iph->ip_hl = 5;
    	iph->ip_v = 4;
    	iph->ip_tos = 0;
    	iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
    	iph->ip_id = htonl(54321);
    	iph->ip_off = 0;
    	iph->ip_ttl = 255;
    	iph->ip_p = 6;
    	iph->ip_sum = 0;
    	iph->ip_src.s_addr = inet_addr("127.0.0.1");
    	iph->ip_dst.s_addr = inet_addr("127.0.0.1");
     
    	tcph->th_sport = htons(80);
    	tcph->th_dport = htons(80);
    	tcph->th_seq = random();
    	tcph->th_ack = 0;
    	tcph->th_x2 = 0;
    	tcph->th_off = 0;
    	tcph->th_flags = TH_SYN;
    	tcph->th_win = htonl(65535);
    	tcph->th_sum = 0;
     
    	iph->ip_sum = checksum((unsigned short int*) datagram, iph->ip_len >> 1);
    	sendto(sock, datagram, iph->ip_len, 0, (struct sockaddr*)&sin, sizeof(sin));
     
    	return 0;
    }
     
    unsigned short int checksum (unsigned short int *buffer, int size) {
    	unsigned long int sum = 0;
     
    	while (size > 1) {
    		sum += *buffer++;
    		size -= sizeof(unsigned short int);
    	}
     
    	if (size) {
    		sum += *(char*)buffer;
    	}
     
    	sum  = (sum >> 16) + (sum & 0xffff);
    	sum += (sum >> 16);
     
    	return (unsigned short int)(~sum);
    }
    Merci par avance de votre aide.

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Après des heures j'ai enfin réussi à envoyer un paquet TCP SYN valide.
    Pour les interessés, voici le code source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    #include <stdlib.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <netinet/ip.h>
    #define __FAVOR_BSD
    #include <netinet/tcp.h>
     
    struct fake_tcphdr {
    	struct in_addr source;
    	struct in_addr destination;
    	unsigned char useless;
    	unsigned char protocol;
    	unsigned short int length;
    	struct tcphdr tcp;
    };
     
    #ifndef __u16
    #define __u16 u_int16_t
    #endif
    #ifndef __u32
    #define __u32 u_int32_t
    #endif
     
    __u16 checksum(__u16 *buffer, int nbytes);
     
    int main (void) {
    	srand(time(NULL));
     
    	struct ip              ip;
    	struct tcphdr          tcp;
    	struct sockaddr_in     sin;
    	struct fake_tcphdr     ftcp;
     
    	int sock;
    	const int on = 1;
     
    	u_char *packet;
    	packet = (u_char*)malloc(sizeof(struct ip) + sizeof(struct tcphdr));
     
    	ip.ip_hl = sizeof(struct ip) / sizeof(unsigned long);
    	ip.ip_v = 4;
    	ip.ip_tos = 0;
    	ip.ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr));
    	ip.ip_id = htons((rand() % (65535 - 1 + 1)) + 1);
    	ip.ip_off = 0;
    	ip.ip_ttl = 255;
    	ip.ip_p = 6;
    	ip.ip_sum = 0;
    	ip.ip_src.s_addr = inet_addr("127.0.0.1");
    	ip.ip_dst.s_addr = inet_addr("127.0.0.1");
    	ip.ip_sum = checksum((__u16*)&ip, sizeof(ip));
     
    	tcp.th_sport = htons((rand() % (65535 - 1 + 1) + 1));
    	tcp.th_dport = htons(0);
    	tcp.th_seq = 0;
    	tcp.th_off = sizeof(struct tcphdr) / 4;
    	tcp.th_flags = 0x02;
    	tcp.th_win = htons(512);
    	tcp.th_sum = 0;
     
    	ftcp.source = ip.ip_src;
    	ftcp.destination = ip.ip_dst;
    	ftcp.useless = 0;
    	ftcp.protocol = IPPROTO_TCP;
    	ftcp.length = htons(sizeof(struct tcphdr));
    	ftcp.tcp = tcp;
    	tcp.th_sum = checksum((__u16*)&ftcp, sizeof(ftcp));
     
    	memcpy(packet, &ip, sizeof(ip));
    	memcpy(packet + sizeof(ip), &tcp, sizeof(tcp));
     
    	if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
    		perror("Socket");
    		exit(1);
    	}
     
    	if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
    		perror("Hdrincl");
    		exit(1);
    	}
     
    	memset(&sin, 0, sizeof(sin));
    	sin.sin_family = PF_INET;
    	sin.sin_addr.s_addr = ip.ip_dst.s_addr;
     
    	if (sendto(sock, packet, sizeof(struct ip) + sizeof(struct tcphdr), 0, (struct sockaddr*)&sin, sizeof(struct sockaddr)) < 0) {
    		perror("Send to");
    		exit(1);
    	}
     
    	memset(&packet, 0, sizeof(packet));
    	free(packet);
     
    	return 0;
    }
     
    __u16 checksum (__u16 *buffer, int nbytes) {
    	__u32 sum;
    	__u16 oddbyte;
     
    	sum = 0;
     
    	while (nbytes > 1) {
    		sum += *buffer++;
    		nbytes -= 2;
    	}
     
    	if (nbytes == 1) {
    		oddbyte = 0;
    		*((__u16*)&oddbyte) = *(__u16*)buffer;
    		sum += oddbyte;
    	}
     
    	sum  = (sum >> 16) + (sum & 0xffff);
    	sum += (sum >> 16);
     
    	return (__u16)~sum;
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. tcp syn sans reponse raw socket winpcap (c)
    Par Shark9 dans le forum Développement
    Réponses: 35
    Dernier message: 20/08/2012, 08h54
  2. requêtes http en pur raw socket TCP et UDP
    Par pam76 dans le forum Réseau
    Réponses: 2
    Dernier message: 27/10/2011, 13h13
  3. Raw socket "bogus tcp header length"
    Par Marnage dans le forum Réseau
    Réponses: 3
    Dernier message: 04/08/2008, 19h27
  4. raw socket et protocole TCP/IP
    Par robertmouac dans le forum Développement
    Réponses: 3
    Dernier message: 09/03/2005, 23h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo