在pcap_creat和pcap_set_rfmon之后使用pcap库pcap_loop中的处理程序不起作用

时间:2013-12-20 11:44:07

标签: c pcap

#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> 

struct usf
 {
  u_int8_t  dest[6];    /* destination eth addr */
  u_int8_t  source[6];  /* source ether addr    */
  u_int16_t type;
  u_int8_t  tst[6]; /* source ether addr    */
 };

 u_int16_t handle_ethernet
      (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet);

 void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,
                  const u_char* packet)
 {
   printf ("in my_callback function\n");
   u_int16_t type = handle_ethernet(args,pkthdr,packet);
   if(type == ETHERTYPE_IP)
   {/* handle IP packet */
   }else if(type == ETHERTYPE_ARP)
   {/* handle arp packet */
   }
   else if(type == ETHERTYPE_REVARP)
   {/* handle reverse arp packet */
   }
 }

 u_int16_t handle_ethernet
     (u_char *args,const struct pcap_pkthdr* pkthdr,
      const u_char* packet)
 {
   struct usf *eptr;  /* net/ethernet.h */
   /* lets start with the ether header... */
   eptr = (struct usf *) packet;
   fprintf(stdout,"ethernet header source: %s\n"
          ,ether_ntoa((const struct ether_addr *)&eptr->source));
   fprintf(stdout," destination: %s \n"
         ,ether_ntoa((const struct ether_addr *)&eptr->dest));
   fprintf(stdout," tst : %s\n "
         ,ether_ntoa((const struct ether_addr *)&eptr->tst));
   /* check to see if we have an ip packet */
   if (ntohs (eptr->type) == ETHERTYPE_IP)
   {
     fprintf(stdout,"(IP)");
   }else  if (ntohs (eptr->type) == ETHERTYPE_ARP)
   {
     fprintf(stdout,"(ARP)");
    }else  if (ntohs (eptr->type) == ETHERTYPE_REVARP)
    {
      fprintf(stdout,"(RARP)");
    }else {
      fprintf(stdout,"(?)");
      exit(1);
    }
  return eptr->type;
 }

 int main(int argc,char **argv)
 { 
   char *dev; // interface name ex: wlan0
   char errbuf[PCAP_ERRBUF_SIZE];
   pcap_t* descr;
   struct bpf_program fp;      /* hold compiled program     */
   bpf_u_int32 maskp;          /* subnet mask               */
   bpf_u_int32 netp;           /* ip                        */
   u_char* args = NULL;

   if(argc < 2){ 
    fprintf(stdout,"Usage: %s numpackets \"options\"\n",argv[0]);
    return 0;
   }
   /* grab a device to peak into... */
   //    dev = pcap_lookupdev(errbuf);
   dev = "wlan0";
   if(dev == NULL)
   { printf("%s\n",errbuf); exit(1); }
   /* ask pcap for the network address and mask of the device */
   pcap_lookupnet(dev,&netp,&maskp,errbuf);// return the ip of wlan0 and netmask 
   /* open device for reading. NOTE: defaulting to
    * promiscuous mode*/
   descr = pcap_create(dev,errbuf);
   // descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
   if(descr == NULL)
   { printf("pcap_open_live(): %s\n",errbuf); exit(1); }
   if(pcap_set_rfmon(descr,1)!=0 )
   {
     printf("monitor mode enabled: %s\n",errbuf); exit(1); 
   }
   pcap_activate(descr);
   if(argc > 2)
   {
     if(pcap_compile(descr,&fp,argv[2],0,netp) == -1)
     { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }

     if(pcap_setfilter(descr,&fp) == -1)
     { fprintf(stderr,"Error setting filter\n"); exit(1); }
   }
   int i=    pcap_loop(descr,atoi(argv[1]),my_callback,args);
   if(i==-1) 
   { 
     printf("error in pcap_loop\n"); exit(1); 
   }
   else if (i==0)
   {
     printf("   0    \n"); exit(1); 
   }
   else if (i==-2)
   {
     printf("   -2    \n"); exit(1); 
   }
   fprintf(stdout,"\nfinished\n");
   return 0;
 }

所有我需要做的就是将我的卡接口转换为监控模式以嗅探信标帧以达到一些好的目的但是当在pcap_creat和pcap_set_rfmon之后使用pcap库时,pcap_loop中的处理程序无法工作,所以任何人都可以帮助我知道什么问题是??

2 个答案:

答案 0 :(得分:0)

您可以使用libiw获取/设置有关无线接口​​的信息( iwconfig命令使用此信息)。

答案 1 :(得分:0)

无法保证pcap_activate()成功。您应检查错误并在失败时报告错误:

int status;

    ...

status = pcap_activate(descr);
if (status < 0)
{
  fprintf(stderr, "pcap_activate failed: %s\n", pcap_statustostr(status));
  exit(1);
}