Salut,
J'ai fait un mini sniffer sous Ubuntu.Et j'ai quelques questions.Je vous donne le code pour commencer, tout n'est pas encore finit (notamment pour les en tête TCP).

Headers.h : Vous pouvez me dire si les commentaires sont correct, car j'essaye de réecrire a ma façon la signification de chaque champs.
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
#ifndef HEADERS_H_INCLUDED
#define HEADER_H_INCLUDED
 
/** En-tête IP **/
typedef struct ipheader
{
    unsigned char   iph_ver;      /** version IP (4) **/
    unsigned char   iph_tos;      /** type of service **/
    unsigned short  iph_totlen;  /** total Lenght **/
    unsigned short  iph_id;      /** identification du paquet en cas de fragmentation **/
    unsigned short  iph_off;     /** offset, Numéro des fragments d'un paquet **/
    unsigned char   iph_ttl;      /** time to live, décrémenter a haque passage d'un routeur **/
    unsigned char   iph_protocol; /** Type de protocol assicier a l'enttête IP **/
    unsigned short  iph_sum;     /** checksum, sert a vérifier la validité du paquet **/
    unsigned short  iph_srcAddr; /** Addresse Source **/
    unsigned short  iph_dtsAddr; /** Adresse de destination **/
} IPHDR;
 
/**********************************************************************************************************/
 
/** En tête ICMP **/
typedef struct icmpheader
{
    unsigned char   icmph_type;         /** Type et code represente l'erreur renvoyer par ICMP **/
    unsigned char   icmph_code;
    unsigned short  icmp_sum;           /** checksum, vérifie la validité du paquet ICMP **/
    unsigned short  icmph_id;           /** Identification, définit l'émétteur.Conseillez de mettre le PID de l'application utilisée **/
    unsigned short  icmph_seq;          /** Séquence, numéro des paquet afin de vérifie si il y a ueu pertes **/
    unsigned long   icmph_timestamp;    /**  ???????? **/
} ICMPHDR;
 
/************************************************************************************************************/
 
/** En tête UDP **/
typedef struct udpheader
{
    unsigned short udph_srcport;    /** Port source **/
    unsigned short udph_dstport;    /** Port de destination **/
    unsigned short udph_len;        /** Longueur de l'entête udp + longueur des données **/
    unsigned short udph_sum;        /** checksum, Validité des paquet udp **/
} UDPHDR;
 
/*************************************************************************************************************/
 
/** En tête TCP **/
typedef struct tcpheader
{
    unsigned short tcph_srcport;    /** Port source **/
    unsigned short tcph_dstport;    /** Port destination **/
    unsigned int tcph_seqnum;       /** sequence number, définit le N° du paquet**/
    unsigned int tcph_acknum;       /** Numéro d'aquitement, valide la réceptiuon d'un paquet.exple acknum = 10, signifie que tous les paquet < 10 on était reçut . **/
    unsigned char tcph_unused;      /** Champ réservé pour le futur, mit a 0 car pas utilisé pour le moment . **/
    unsigned char tcph_off;         /** Offset, Nombre de mots de 32 bits dans l'entête TC.Cad q'uil définit ou les données commencent **/
    unsigned char tcph_flag;        /** Flags, ACK, SYN, URG ect... **/
 
#define FL_FIN  0x01
#define FL_SYN  0X02
#define FL_RST  0X04
#define FL_PSH  0X08
#define FL_ACK  0x10
#define FL_URG  0X20
#define FL_ECE  0x40
#define FL_CWR  0x80
 
    unsigned short tcph_win;        /** Windows, nbre d'octets a partir du N° de séquence que le récepteur est capable de recevoir . **/
    unsigned short tcph_sum;        /** checksum, validité des paquet tcp **/
    unsigned short tcph_urg;        /** Pointer sur un poaquet de donnée urgent, donne sa position avec le décalage par rapport au N° de sequence **/
} TCPHDR;
 
#endif
main.c : faite pas attention au ligne commentées, c'est juste por moi.
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
120
121
122
123
124
125
126
127
128
129
130
/* #include <sys/types.h>    */
/* #include <sys/socket.h>   */
/* #include <netinet/in.h>   */
/* #include <net/ethernet.h> */
 
#include <unistd.h>             /** pour sleep() **/
#include <arpa/inet.h>          /** PF_PACKET, SOCK_RAW, htons(), inet_ntoa(), IPPROTO_xxx **/
#include <netpacket/packet.h>   /** struct sockaddr_ll **/
#include <linux/if_ether.h>     /** ETH_P_ALL **/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "Headers.h"
 
/** - pourquoi pas de bind
    -  pourquoi cast en int pour header ip et icmp ***/
 
 
int main(void)
{
    int sockfd;
    int recvret = 0;
    char packet[8192];
    char addrIP[16];
    struct sockaddr_ll sin;
    socklen_t serverLen = sizeof(sin);
 
    /* int one = 1             ; */
    /* const int *val = &one   ; */
    /* char addrIP[16]         ; */
 
    /*strncpy(addrIP, "192.168.0.6", 16)      ;*/
 
    /** contexte d'adressage **/
    sin.sll_family      = PF_PACKET           ;
 
    if( (sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
    {
        perror("socket() : ");
        exit(1);
    }
 
    /*if( bind(sockfd, (struct sockaddr *)&sin, serverLen) == -1)
    {
        perror("bind() : ");
        exit(1);
    } */
 
    /** if( setsockopt(sockfd, "?????", )) pour le mode promiscuous **/
 
    /** pointers des protocoles **/
    IPHDR   *ip     = (IPHDR *)packet;
    ICMPHDR *icmp   = (ICMPHDR *)(sizeof(IPHDR) + packet);
    UDPHDR  *udp    = (UDPHDR *)(sizeof(IPHDR) + packet);
    TCPHDR  *tcp    = (TCPHDR *)(sizeof(IPHDR) + packet);
 
 
    /** Boucle infinit recvfrom() **/
    printf("Scan en cours :\n\n");
 
    while(1)
    {
        if( (recvret = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&sin, &serverLen) ) )
            sleep(1);
        else if(!recvret)
        {
            perror("recv() : ");
            exit(1);
        }
 
        /** Affichage infos IP **/
        printf("\t\t------NEW PACKET------\n\n");
        printf("\t\t------IP HEADER------\n\n");
 
        printf("TOS         : %d\n",    (int)ip->iph_tos);
        printf("Len         : %d\n",    ip->iph_totlen);
        printf("ID          : %d\n",    ip->iph_id);
        printf("OffSet      : %d\n",    ip->iph_off);
        printf("TTL         : %d\n",    (int)ip->iph_ttl);
        printf("Protocole   : %d\n",    (int)ip->iph_protocol);
        printf("Checksum    : %02x\n",  ip->iph_sum);
        printf("IP SRC      : %s\n",    inet_ntoa( ( *(struct in_addr *)&ip->iph_srcAddr) ) );
        printf("IP_DST      : %s\n",    inet_ntoa( ( *(struct in_addr *)&ip->iph_dtsAddr) ) );
        printf("-------------------------\n\n");
 
        /** Infos pour chaque protocole **/
 
        switch(ip->iph_protocol)
        {
            case IPPROTO_ICMP :
            {
                printf("ICMP HEADER\n\n");
                printf("Type        : %d\n",    (int)icmp->icmph_type);
                printf("Code        : %d\n",    (int)icmp->icmph_code);
                printf("Checksum    : %02x\n",  icmp->icmp_sum);
                printf("ID          : %d\n",    (int)icmp->icmph_id);
                printf("SeqNum      : %d\n",    (int)icmp->icmph_seq);
                printf("timestamp   : %ld\n",   icmp->icmph_timestamp);
                break;
            }
 
            case IPPROTO_UDP :
            {
                printf("UDP HEADER\n\n");
                printf("SRC Port    : %d\n",    (int)udp->udph_srcport);
                printf("DST Port    : %d\n",    (int)udp->udph_dstport);
                printf("Len         : %d\n",    (int)udp->udph_len);
                printf("Checksum    : %02x\n",  udp->udph_sum);
                break;
 
            }
 
            default :
            {
                printf("Protocol Inconnu : %d\n", (int)ip->iph_protocol);
                break;
            }
        }
 
        memset(packet, 0, sizeof(packet));
 
    }
 
    /** Swicth pour infos selon protocoles **/
 
    /** Bien faire memset a la fin de l loop **/
 
    return EXIT_SUCCESS;
}
Donc pour le moment 2 questions :

1- pourquoi pas de bind() ? on utilise une structure sockadrr_ll ok, mais quelques explication serait le bien venu.

2 - pourquoi des cast en int pour les headers ? en fait plus précisement, pour le default du swicth par exple.Dans le header IP, le type de protocol est un unsigned char, alors pourquoi il réclame un int lorsque je veut l'afficher ?

Voila question peut être simple, mais bon il y a pas de question c..n je pense, donc autant les posées

Merci bien, bon week end .

A+++.