Bonjour à tous

Je m'initie aux joies aux combien palpitantes des RAW SOCKET sous Linux (compilateur gcc). Comme exercice je me suis dis "Et si je recréait la fonction ping", alors ce fut le début de mes longues péripéties

Vacant de site internet en forum je me décide à poster mon code -qui ne marche pas- ici.

Voici mon zouli 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
93
94
95
96
 
#include <stdio.h>
 
#include <linux/ip.h>
#include <linux/icmp.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
 
 unsigned short in_cksum(unsigned short *addr, int len)
        {
            register int sum = 0;
            u_short answer = 0;
            register u_short *w = addr;
            register int nleft = len;
 
            while (nleft > 1)
              {
                  sum += *w++;
                  nleft -= 2;
              }
 
            if (nleft == 1)
              {
                  *(u_char *) (&answer) = *(u_char *) w;
                  sum += answer;
              }
 
            sum = (sum >> 16) + (sum & 0xffff);       
            sum += (sum >> 16);         
            answer = ~sum;           
            return (answer);
      }
 
int main(){
 
        int sock, optval;
        char *packet, *buffer;
 
        struct icmphdr *icmp;
 
        struct sockaddr_in peer;
        struct iphdr *ip;
 
 
        ip = (struct iphdr *) malloc(sizeof(struct iphdr));
        icmp     = (struct icmphdr *) malloc(sizeof(struct icmphdr));
        packet  = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)
);
        buffer  = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)
);
 
 
        ip = (struct iphdr *) packet;
        icmp = (struct icmphdr *) (packet + sizeof(struct iphdr));
 
 
        ip->ihl     = 5;
        ip->version = 4;
        ip->tos     = 0;
        ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr);
        ip->id      = htons(getuid());
        ip->ttl      = 255;
        ip->protocol = IPPROTO_ICMP;
        ip->saddr    = inet_addr("127.0.0.1");
        ip->daddr    = inet_addr("127.0.0.1");
 
 
        sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
        setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(int));
 
        icmp->type = ICMP_ECHO;
        icmp->code = 0;
        icmp->un.echo.id = 0;
        icmp->un.echo.sequence = 0;
        icmp->checksum = 0;
 
        icmp->checksum = in_cksum((unsigned short *)icmp,sizeof(struct icmphdr)
);
 
        ip->check    = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
 
 
 
        peer.sin_family = AF_INET;
        peer.sin_addr.s_addr = inet_addr("127.0.0.1");
 
        sendto(sock,packet,ip->tot_len,0,(struct sockaddr *)&peer,sizeof(struct
 sockaddr));
 
        recv(sock,buffer,sizeof(struct iphdr)+sizeof(struct icmphdr),0);
        printf("Received the ECHO REPLY\n");
 
        close(sock);
        return 0;
}
A la question "en quoi mon code plante" je répondrais que le packet icmp n'est pas correctement forgé.

En effet en lançant le programme avec un tcpdump -i lo -X dans une autre console le packet forgé ne ressemble en rien à un packet classique de ping (il est même indiqué "h-len error" ou quelque'chose de similaire).

Ou ais-je péché ?


PS : je précise que ce n'est pas tout a fait mon code. Ce qui change dans le mien ce sont les ips qui ne sont pas des variables entre "" mais des variables à proprement parlé (char * IP).
PS2 : comme ce code me fait l'erreur quand même je me dis que ca ne viens pas de moi


Merci à toutes les âmes aventureuses qui oseront remonter des tréfonds de l'abysse des bugs de mon code les quelques monstres qui s'y cache

PS 3: je prends tout ca avec humour parce'que je pense que la prochaine étape est la suppression physique du PC