[Socket RAW] Problème entête UDP
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:
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.