• [^] # Re: Pas le but de libpcap

    Posté par . En réponse au message Le port source avc LIbpcap. Évalué à 0.

    Pour les trames UDP, tu peux le faire avec un truc de ce genre:

    void capture(pcap_t *p)
    {
     struct pcap_pkthdr hdr;
     const unsigned char * pload;
     const struct ethhdr * ethhdr;
     const struct iphdr * iphdr;
     const struct udphdr * udphdr;
     const unsigned char * data;
     struct in_addr inaddr;
     const int min_size = sizeof ethhdr[0] + sizeof iphdr[0] + sizeof udphdr[0];
     int data_len;
     struct pcap_buff * b;
     int seqnum;
     seqnum = 0;
     for (;;) {
     seqnum ++;
     pload = pcap_next(p, &hdr);
     if (pload == NULL)
     break;
     if (hdr.caplen != hdr.len) {
     fprintf(stderr, "[%d] capture was truncated (%d expected, %d captured)\n", seqnum, hdr.len, hdr.caplen);
     continue;
     }
     if (hdr.len < min_size) {
     fprintf(stderr, "[%d] Too small frame found (%d < %d)\n", seqnum, hdr.len, min_size);
     continue;
     }
     ethhdr = (struct ethhdr *)pload;
     if (ethhdr->h_proto != htons(ETH_P_IP)) {
     fprintf(stderr, "[%d] Unknown ethhdr->h_proto (%04x)\n", seqnum, ethhdr->h_proto);
     continue;
     }
     iphdr = (struct iphdr *)(pload + sizeof ethhdr[0]);
     if (iphdr->ihl != sizeof iphdr[0] / 4) {
     fprintf(stderr, "[%d] Invalid iphdr->ihl (%d != %d)\n", seqnum, iphdr->ihl * 4, sizeof iphdr[0]);
     continue;
     }
     if (iphdr->protocol != IPPROTO_UDP) {
     fprintf(stderr, "[%d] Only UDP is allowed (%#x found)\n", seqnum, iphdr->protocol);
     continue;
     }
     udphdr = (struct udphdr *)(pload + sizeof ethhdr[0] + sizeof iphdr[0]);
     data_len = htons(udphdr->len) - sizeof udphdr[0];
     if (data_len + min_size != hdr.len) {
     fprintf(stderr, "[%d] Invalid pload lenght ((%d - %d) + %d != %d)\n", seqnum, htons(udphdr->len), sizeof udphdr[0], min_size, hdr.len);
     continue;
     }
     data = pload + sizeof ethhdr[0] + sizeof iphdr[0] + sizeof udphdr[0];
     inaddr.s_addr = iphdr->saddr;
     printf("[%d] ip.saddr = <%s>, udp.source = <%d>\n", seqnum, inet_ntoa(inaddr), htons(udphdr->source));
     inaddr.s_addr = iphdr->daddr;
     printf("[%d] ip.daddr = <%s>, udp.dest = <%d>\n", seqnum, inet_ntoa(inaddr), htons(udphdr->dest));
     }
    }
    
    

    À la fin de la boucle:
    * iphdr pointe sur l'entête IP (où tu trouveras entre autre la source et destination ainsi que le type UDP, TCP etc.)
    * udphdr pointe sur l'entête UDP (où tu trouveras entre autre les ports source et destination)
    * data pointe sur les données (sic !)

    Si tu veux les ports TCP dans le cas des paquets TCP, tout comme l'entête UDP, pointer avec un struct udphdr et y lire "source" et "dest". Faut juste faire gaffe aux histoires d'offset pour la donnée, et aux htons des champs dans les structures.