Bonjour,
j'ai quelques soucis avec les sockets raws, je veux envoyé une trame udp complète (dans le cadre d'un projet) mais définir moi même les entêtes (d'où mon choix pour les sock_raw).
Normalement si je parle en terme de réseau je devrais avoir entête Ethernet -> entête Ip -> Entête UDP -> Data, ici l'entête Ethernet on n'y a pas accès ( si on se place dans le domaine AF_INET).
Donc j'ai accès qu'au entête ip et udp, alors je rempli mes entêtes ip et udp, et lors de l'envoi avec un sendto j'envoi mon paquet entier ( entêtes + data ).
Et visiblement bah j'ai pas l'entête UDP que j'ai définit :s

J'ai beau retourné le problème dans tout les sens, je vois plus.

Voici mon code :
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
 
/* Constantes */
#define C_IP_DEST "192.168.145.128"
#define C_IP_SRC "192.168.145.129"
#define C_PORT 65000
#define C_TAILLE_PAQUET 50
 
/* Programme principal */
int main(void)
{ 
 	/* Initialisation des variables */
	int sock, optval,envoie;
        char *packet,*data;
 
        struct sockaddr_in peer;
        struct iphdr *ip;
	struct udphdr *udp;
 
 
	/* Allocation dynamique de la mémoire */
        ip 	= (struct iphdr *) malloc(sizeof(struct iphdr));//entete ip envoyer
        udp 	= (struct udphdr *) malloc(sizeof(struct udphdr));//entete udp envoyer
 
	data	= (char *) malloc(C_TAILLE_PAQUET*sizeof(char));
        packet  = (char *) malloc(sizeof(struct iphdr) + sizeof(struct udphdr) + C_TAILLE_PAQUET*sizeof(char));
 
	/* Paquet pointé sur les données à envoyer */
        ip = (struct iphdr *) packet;
	udp = (struct udphdr *) (packet + sizeof(struct iphdr)); 
	data = (char *) (packet  + sizeof(struct iphdr) + sizeof(struct udphdr));
 
 	 /* Création de la socket */
	sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
       	if (sock<0)
	{
		printf("Erreur création de socket\n");
		perror("Socket");
		exit(1);
	}
	else 
		printf ("Socket crée: \n");
 
 	/* Initialisation de la structure ip définie dans ip.h */
	/**http://www.srcdoc.com/linux_2.2.26/linux_2ip_8h-source.html**/
        ip->ihl     	= 0x5;
        ip->version 	= 4;
        ip->tos     	= 0;
        ip->id      	= getuid();
        ip->ttl      	= 255;
        ip->tot_len 	= sizeof(struct iphdr) + sizeof(struct udphdr) + C_TAILLE_PAQUET*sizeof(char);
        ip->protocol 	= IPPROTO_UDP;
        ip->saddr    	= inet_addr(C_IP_SRC);
        ip->daddr    	= inet_addr(C_IP_DEST);
    	ip->frag_off 	= htons(0 >> 3);//on remplie l'offset decaler des 3bit de flag
	ip->frag_off   |= 64;//on remplie le flag soit 64 soit htons(0x4000)
        ip->check    	= in_cksum((unsigned short *)icmp,sizeof(struct iphdr));
	/* Remarque : L'utilisateur doit fournir une entête ip avant les données proprement dites. */
 
 	/* Initialisation de la structure udp définie dans udp.h */
	/**http://www.srcdoc.com/linux_2.2.26/linux_2udp_8h-source.html**/
        udp->source     = htons(C_PORT);
        udp->dest 	= htons(C_PORT);
        udp->len    	= sizeof(struct udphdr) + C_TAILLE_PAQUET*sizeof(char);
        udp->check 	= 0;
 
	/* Modification des paramètres de la socket */
        setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(int));
 
	/* Initialisation de la strcture sockaddr_in */
        peer.sin_family = AF_INET;
        peer.sin_addr.s_addr = inet_addr(C_IP_DEST);
        peer.sin_port = htons(C_PORT);
 
	data = "Bonjour";
	/**envoie de la requete*/
        envoie=sendto(sock,packet,ip->tot_len,0,(struct sockaddr *)&peer,sizeof(struct sockaddr));
 
	/*controle l'envoie*/
       	if (envoie != ip->tot_len)
		printf("A envoyé %d octets au lieu de %d octects\n",envoie,ip->tot_len);
	else  
		printf("%d octets envoyé (%d) données)\n",envoie, C_TAILLE_PAQUET);
 
      	if (envoie <= 0)
		perror("Erreur sendto()");
 
	printf("\n\n");
	/* Libération des ressources */
        close(sock);
        free(packet);
        return 0;
}
Je n'ai pas mis la fonction in_cksum ni les includes qui ne sont pas utiles à la compréhension enfin je crois.

Alors si il y a une âme charitable pour m'aider à comprendre pourquoi ça n'envoie pas l'entête udp :d

Cordialement,
POSTEL Edouard.