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;
}
_______________________________________________
Wireshark-dev mailing list
Wireshark-dev@wireshark.org
http://www.wireshark.org/mailman/listinfo/wireshark-dev

Reply via email to