tcpdump mailing list archives

Capturing WLAN packets with libpcap


From: "David Lopez" <David.Lopez () cit ie>
Date: Fri, 8 Dec 2006 11:36:55 -0000

Hello

 

I'm David, a PhD student

I'm developing a small sniffer for my project. I'm using libpcap

 

I built a sniffer for capturing ethernet packets on the cable and it is
working fine.

Now, I would like to use this sniffer for capturing 802.11 WLAN packets.


When I use this sniffer for capturing  802.11 WLAN packets on my
adapter, it looks ok, but when I try to get the MAC and IP addresses,
they are wrong.

I supposse that I should eliminate first the WLAN envelopment or
something like tath

 

I would like to know if you can give a clue or if you have some example
code.

 

Here you have my code:

 

#include <pcap.h>

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netinet/if_ether.h> 

#include <net/ethernet.h>

#include <netinet/ether.h> 

#include <netinet/ip.h> 

 

 

/* tcpdump header (ether.h) defines ETHER_HDRLEN) */

#ifndef ETHER_HDRLEN 

#define ETHER_HDRLEN 14

#endif

 

/*

 * Structure of an internet header, naked of options.

 *

 * Stolen from tcpdump source (thanks tcpdump people)

 *

 * We declare ip_len and ip_off to be short, rather than u_short

 * pragmatically since otherwise unsigned comparisons can result

 * against negative integers quite easily, and fail in subtle ways.

 */

struct my_ip {

 u_int8_t ip_vhl;  /* header length, version */

#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)

#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)

 u_int8_t ip_tos;  /* type of service */

 u_int16_t ip_len;  /* total length */

 u_int16_t ip_id;  /* identification */

 u_int16_t ip_off;  /* fragment offset field */

#define IP_DF 0x4000   /* dont fragment flag */

#define IP_MF 0x2000   /* more fragments flag */

#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */

 u_int8_t ip_ttl;  /* time to live */

 u_int8_t ip_p;  /* protocol */

 u_int16_t ip_sum;  /* checksum */

 struct in_addr ip_src,ip_dst; /* source and dest address */

};

 

 

main()

{

    pcap_if_t *alldevs;

    pcap_if_t *d;

    pcap_t *p;

    pcap_t *adhandle; 

    int i=0;

    int inum;

    int res;

    int datalink;

    char errbuf[PCAP_ERRBUF_SIZE];

    char timestr[16];

    struct tm *ltime;

    struct pcap_pkthdr *header;

    struct ether_header *eptr; 

    const struct my_ip* ip;

    u_char *pkt_data;

    u_short ether_type;

 

        

    /* Retrieve the device list */

    if (pcap_findalldevs(&alldevs, errbuf) == -1)

    {

        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);

        exit(1);

    }

 

 

    

    /* Print the list */

    for(d=alldevs; d; d=d->next)

    {

        printf("%d. %s", ++i, d->name);

        if (d->description)

            printf(" (%s)\n", d->description);

        else

            printf(" (No description available) \n");

 

    }

    

    if(i==0)

    {

        printf("\nNo interfaces found! Make sure WinPcap is
installed.\n");

        return -1;

    }

    

    printf("Enter the interface number (1-%d):",i);

    scanf("%d", &inum);

    

    if(inum < 1 || inum > i)

    {

        printf("\nInterface number out of range.\n");

        /* Free the device list */

        pcap_freealldevs(alldevs);

        return -1;

    }

    

    /* Jump to the selected adapter */

    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);

    

    /* Open the adapter */

    if ( (adhandle= pcap_open_live(d->name, // name of the device

        65536,     // portion of the packet to capture. 

        // 65536 grants that the whole packet will be captured on all
the MACs.

        1,         // promiscuous mode

        1000,      // read timeout

        errbuf     // error buffer

        ) ) == NULL)

    {

        fprintf(stderr,"\nUnable to open the adapter. %s is not
supported by WinPcap\n");

        /* Free the device list */

        pcap_freealldevs(alldevs);

        return -1;

    }

    

    printf("\nlistening on %s... \n", d->name);

 

 if(datalink=pcap_datalink(adhandle)<0){

  printf("\nDatalink Error: %s\n",errbuf);

 }

 

 printf("\nDatalink=%s\n\n", pcap_datalink_val_to_name(datalink));

 

    

    

    /* At this point, we don't need any more the device list. Free it */

    pcap_freealldevs(alldevs);

    

    /* Retrieve the packets */

    while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){

        

        if(res == 0)

            /* Timeout elapsed */

            continue;

        

        /* convert the timestamp to readable format */

        ltime=localtime(&header->ts.tv_sec);

        strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);

        

        printf("%s,%.6d; len:%d; ", timestr, header->ts.tv_usec,
header->len);

 

/////////////////////////////////////////// MAC

 

       /* lets start with the ether header... */

       eptr = (struct ether_header *) pkt_data;

       ether_type = ntohs(eptr->ether_type);

 

       /* check to see if we have an ip packet */

       if (ether_type == ETHERTYPE_IP)

       {

           fprintf(stdout,"Type(IP); ");

       }else  if (ether_type == ETHERTYPE_ARP)

       {

           fprintf(stdout,"Type(ARP); ");

       }else  if (eptr->ether_type == ETHERTYPE_REVARP)

       {

           fprintf(stdout,"Type(RARP); ");

       }else {

           fprintf(stdout,"Type(?); ");

       }

 

       /* Lets print SOURCE DEST TYPE LENGTH */

       fprintf(stdout,"MAC: ");

       fprintf(stdout,"%s/"

            ,ether_ntoa((struct ether_addr*)eptr->ether_shost));

       fprintf(stdout,"%s; "

            ,ether_ntoa((struct ether_addr*)eptr->ether_dhost));

 

 

/////////////////////////////////////////// IP

 

    u_int length = header->len;

    u_int hlen,off,version;

 

    int len;

 

    /* jump pass the ethernet header */

    ip = (struct my_ip*)(pkt_data + sizeof(struct ether_header));

    length -= sizeof(struct ether_header); 

 

    /* check to see we have a packet of valid length */

    if (length < sizeof(struct my_ip))

    {

        printf("truncated ip %d",length);

        return NULL;

    }

 

    len     = ntohs(ip->ip_len);

    hlen    = IP_HL(ip); /* header length */

    version = IP_V(ip);/* ip version */

 

    /* Check to see if we have the first fragment */

    off = ntohs(ip->ip_off);

    if((off & 0x1fff) == 0 )/* aka no 1's in first 13 bits */

    {/* print SOURCE DESTINATION hlen version len offset */

        fprintf(stdout,"IP: ");

        fprintf(stdout,"%s/",

                inet_ntoa(ip->ip_src));

        fprintf(stdout,"%s.\n",

                inet_ntoa(ip->ip_dst),

                hlen,version,len,off);

    }    /* check version */

    if(version != 4)

    {

      fprintf(stdout,"Unknown version %d\n",version);

    }

 

    /* check header length */

    if(hlen < 5 )

    {

        fprintf(stdout,"bad-hlen %d \n",hlen);

    }

 

    /* see if we have as much packet as we should */

    if(length < len)

        printf("truncated IP - %d bytes missing\n",len - length);

 

 

 

///////////////////////////////////////////

    }

    

    if(res == -1){

        printf("Error reading the packets: %s\n",
pcap_geterr(adhandle));

        return -1;

    }

    

    return 0;

}

 

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: