winPcap_5_打开适配器并捕获数据包

系统 1795 0

 

  知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包。编写一个程序,将每一个 通过适配器的数据包 打印出来。

 

打开设备的函数是  pcap_open()

(Open a generic source in order to capture / send (WinPcap only) traffic.)

      pcap_t* pcap_open  ( 
      
        const
      
      
        char
      
       *
      
          source,

                     
      
      
        int
      
      
          snaplen,

                     
      
      
        int
      
      
          flags,

                     
      
      
        int
      
      
          read_timeout,

                     
      
      
        struct
      
       pcap_rmtauth *
      
          auth,

                     
      
      
        char
      
       *
      
          errbuf

                   )
      
    

 

  · snaplen 制定要捕获数据包中的哪些部分。 在一些操作系统中 (比如 xBSD 和 Win32), 驱动可以被配置成 只捕获数据包的初始化部分 : 这样可以减少应用程序间复制数据的量,从而提高捕获效率。本例中,我们将值定为65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。

  · flags : 最最重要的flag是用来指示适配器是否要被设置成 混杂模式 一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃 。 相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。 这意味着在一个共享媒介(比如总线型以太网),WinPcap能捕获其他主机的所有的数据包。 大多数用于数据捕获的应用程序都会将适配器设置成混杂模式 ,所以,我们也会在下面的范例中,使用混杂模式。 

  · read_timeout(to_ms): 指定 读取数据的超时时间 ,以毫秒计(1s=1000ms)。在适配器上进行读取操作(比如用 pcap_dispatch() pcap_next_ex() ) 都会在 to_ms 毫秒时间内响应,即使在网络上没有可用的数据包。 在统计模式下 to_ms 还可以用来定义 统计的时间间隔 。 将 to_ms 设置为0意味着没有超时,那么如果没有数据包到达的话,读操作将永远不会返回。 如果设置成-1,则情况恰好相反,无论有没有数据包到达,读操作都会立即返回。

Returns:
A pointer to a 'pcap_t' which can be used as a parameter to the following calls ( pcap_compile() and so on) and that specifies an opened WinPcap session. In case of problems, it returns NULL and the 'errbuf' variable keeps the error message.
Warning:
The source cannot be larger than PCAP_BUF_SIZE.

The following formats are not allowed as 'source' strings:

  • rpcap:// [to open the first local adapter]
  • rpcap://hostname/ [to open the first remote adapter] 

 

 

      
        int
      
       pcap_dispatch  ( pcap_t *
      
          p,  

  
      
      
        int
      
      
          cnt,  

  pcap_handler  callback,  

  u_char 
      
      *
      
          user   

 )
      
    

 

Collect a group of packets. 

 

      
        int
      
       pcap_loop  ( pcap_t *
      
          p,  

  
      
      
        int
      
      
          cnt,  

  pcap_handler  callback,  

  u_char 
      
      *
      
          user   

 ) 
      
    

 

Collect a group of packets.

 

pcap_dispatch()与pcap_loop()的区别:

  当适配器被打开,捕获工作就可以用 pcap_dispatch() pcap_loop() 进行。 这两个函数非常的相似, 区别就是 pcap_ dispatch() 当超时时间到了(timeout expires)就返回 (尽管不能保证) ,而 pcap_loop() 不会因此而返回 ,只有当 cnt 数据包被捕获,所以,pcap_loop()会在一小段时间内,阻塞网络的利用。 pcap_loop() 对于我们这个简单的范例来说,可以满足需求,不过, pcap_dispatch() 函数一般用于比较复杂的程序中。

这两个函数都有一个 回调 参数, packet_handler 指向一个可以接收数据包的函数 。 这个函数会在收到每个新的数据包并收到一个通用状态时被libpcap所调用 ( 与函数 pcap_loop() pcap_dispatch() 中的 user 参数相似),数据包的首部一般有一些诸如时间戳,数据包长度的信息,还有包含了协议首部的实际数据。 注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将CRC删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap没法捕获到它们。

上面的程序将每一个数据包的时间戳和长度从 pcap_pkthdr 的首部解析出来,并打印在屏幕上。

请注意,使用 pcap_loop() 函数可能会遇到障碍,主要因为它直接由数据包捕获驱动所调用。因此,用户程序是不能直接控制它的。另一个实现方法(也是提高可读性的方法),是使用 pcap_next_ex() 函数。有关这个函数的使用,请看 ( 不用回调方法捕获数据包 ).

 

      
        struct
      
      
          pcap_pkthdr{

    timeval    ts

    
      
      
        //
      
      
        time stamp
      
      
            bpf_u_int32    caplen

    
      
      
        //
      
      
        length of portion present
      
      
            bpf_u_int32    len

    
      
      
        //
      
      
        length this packet (off wire)
      
      

};
    

Detailed Description

Header of a packet in the dump file.

Each packet in the dump file is prepended with this generic header. This gets around the problem of different headers for different packet interfaces. 

 

        
           1
        
         #include 
        
          "
        
        
          pcap.h
        
        
          "
        
        
           2
        
        
          #pragma
        
         comment(lib, "wpcap.lib")


        
           3
        
        
          #pragma
        
         comment(lib, "Packet.lib")


        
           4
        
        
          #pragma
        
         comment(lib, "wsock32.lib")


        
           5
        
        
           6
        
        
           7
        
         #include 
        
          "
        
        
          pcap.h
        
        
          "
        
        
           8
        
        
           9
        
        
          /*
        
        
           packet handler 函数原型 
        
        
          */
        
        
          10
        
        
          void
        
         packet_handler(u_char *param, 
        
          const
        
        
          struct
        
         pcap_pkthdr *header, 
        
          const
        
         u_char *
        
          pkt_data);


        
        
          11
        
        
          12
        
        
          main()


        
        
          13
        
        
          {


        
        
          14
        
             pcap_if_t *
        
          alldevs;


        
        
          15
        
             pcap_if_t *
        
          d;


        
        
          16
        
        
          int
        
        
           inum;


        
        
          17
        
        
          int
        
         i=
        
          0
        
        
          ;


        
        
          18
        
             pcap_t *
        
          adhandle;


        
        
          19
        
        
          char
        
        
           errbuf[PCAP_ERRBUF_SIZE];


        
        
          20
        
        
          21
        
        
          /*
        
        
           获取本机设备列表 
        
        
          */
        
        
          22
        
        
          if
        
         (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -
        
          1
        
        
          )


        
        
          23
        
        
              {


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


        
        
          25
        
                 exit(
        
          1
        
        
          );


        
        
          26
        
        
              }


        
        
          27
        
        
          28
        
        
          /*
        
        
           打印列表 
        
        
          */
        
        
          29
        
        
          for
        
        (d=alldevs; d; d=d->
        
          next)


        
        
          30
        
        
              {


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


        
        
          32
        
        
          if
        
         (d->
        
          description)


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


        
        
          34
        
        
          else
        
        
          35
        
                     printf(
        
          "
        
        
           (No description available)\n
        
        
          "
        
        
          );


        
        
          36
        
        
              }


        
        
          37
        
        
          38
        
        
          if
        
        (i==
        
          0
        
        
          )


        
        
          39
        
        
              {


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


        
        
          41
        
        
          return
        
         -
        
          1
        
        
          ;


        
        
          42
        
        
              }


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


        
        
          45
        
             scanf(
        
          "
        
        
          %d
        
        
          "
        
        , &
        
          inum);


        
        
          46
        
        
          47
        
        
          if
        
        (inum < 
        
          1
        
         || inum >
        
           i)


        
        
          48
        
        
              {


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


        
        
          50
        
        
          /*
        
        
           释放设备列表 
        
        
          */
        
        
          51
        
        
                  pcap_freealldevs(alldevs);


        
        
          52
        
        
          return
        
         -
        
          1
        
        
          ;


        
        
          53
        
        
              }


        
        
          54
        
        
          55
        
        
          /*
        
        
           跳转到选中的适配器 
        
        
          */
        
        
          56
        
        
          for
        
        (d=alldevs, i=
        
          0
        
        ; i< inum-
        
          1
        
         ;d=d->next, i++
        
          );


        
        
          57
        
        
          58
        
        
          /*
        
        
           打开设备 
        
        
          */
        
        
          59
        
        
          if
        
         ( (adhandle= pcap_open(d->name,          
        
          //
        
        
           设备名
        
        
          60
        
        
          65536
        
        ,            
        
          //
        
        
           65535保证能捕获到不同数据链路层上的每个数据包的全部内容
        
        
          61
        
                 PCAP_OPENFLAG_PROMISCUOUS,    
        
          //
        
        
           混杂模式
        
        
          62
        
        
          1000
        
        ,             
        
          //
        
        
           读取超时时间
        
        
          63
        
                 NULL,             
        
          //
        
        
           远程机器验证
        
        
          64
        
                 errbuf            
        
          //
        
        
           错误缓冲池
        
        
          65
        
                 ) ) ==
        
           NULL)


        
        
          66
        
        
              {


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


        
        
          68
        
        
          /*
        
        
           释放设备列表 
        
        
          */
        
        
          69
        
        
                  pcap_freealldevs(alldevs);


        
        
          70
        
        
          return
        
         -
        
          1
        
        
          ;


        
        
          71
        
        
              }


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


        
        
          74
        
        
          75
        
        
          /*
        
        
           释放设备列表 
        
        
          */
        
        
          76
        
        
              pcap_freealldevs(alldevs);


        
        
          77
        
        
          78
        
        
          /*
        
        
           开始捕获 
        
        
          */
        
        
          79
        
             pcap_loop(adhandle, 
        
          0
        
        
          , packet_handler, NULL);


        
        
          80
        
        
          81
        
        
          return
        
        
          0
        
        
          ;


        
        
          82
        
        
          }


        
        
          83
        
        
          84
        
        
          85
        
        
          /*
        
        
           每次捕获到数据包时,libpcap都会自动调用这个回调函数 
        
        
          */
        
        
          86
        
        
          void
        
         packet_handler(u_char *param, 
        
          const
        
        
          struct
        
         pcap_pkthdr *header, 
        
          const
        
         u_char *
        
          pkt_data)


        
        
          87
        
        
          {


        
        
          88
        
        
          struct
        
         tm *
        
          ltime;


        
        
          89
        
        
          char
        
         timestr[
        
          16
        
        
          ];


        
        
          90
        
        
              time_t local_tv_sec;


        
        
          91
        
        
          92
        
        
          /*
        
        
           将时间戳转换成可识别的格式 
        
        
          */
        
        
          93
        
             local_tv_sec = header->
        
          ts.tv_sec;


        
        
          94
        
             ltime=localtime(&
        
          local_tv_sec);


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


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


        
        
          98
        
         }
      
打开适配器并捕获数据包.c

  *结果:

winPcap_5_打开适配器并捕获数据包

时间戳(精确到微妙),包长度;

 

timeval

The  timeval  structure is used to specify time values. It is associated with the Berkeley Software Distribution (BSD) file Time.h.

      
        struct
      
      
         timeval {

  
      
      
        long
      
          tv_sec;         
      
        //
      
      
         seconds 
      
      
        long
      
          tv_usec;        
      
        //
      
      
         and microseconds 
      
      

};
    

Members

tv_sec
Time value, in seconds.
tv_usec
Time value, in microseconds. 

 

localtime

Converts a time value and corrects for the local time zone.

      
        struct
      
       tm *localtime( 
      
        const
      
       time_t *timer );
    

 

 

      
        struct
      
      
         tm {

        
      
      
        int
      
       tm_sec;     
      
        /*
      
      
         seconds after the minute - [0,59] 
      
      
        */
      
      
        int
      
       tm_min;     
      
        /*
      
      
         minutes after the hour - [0,59] 
      
      
        */
      
      
        int
      
       tm_hour;    
      
        /*
      
      
         hours since midnight - [0,23] 
      
      
        */
      
      
        int
      
       tm_mday;    
      
        /*
      
      
         day of the month - [1,31] 
      
      
        */
      
      
        int
      
       tm_mon;     
      
        /*
      
      
         months since January - [0,11] 
      
      
        */
      
      
        int
      
       tm_year;    
      
        /*
      
      
         years since 1900 
      
      
        */
      
      
        int
      
       tm_wday;    
      
        /*
      
      
         days since Sunday - [0,6] 
      
      
        */
      
      
        int
      
       tm_yday;    
      
        /*
      
      
         days since January 1 - [0,365] 
      
      
        */
      
      
        int
      
       tm_isdst;   
      
        /*
      
      
         daylight savings time flag 
      
      
        */
      
      
        

        };
      
    

 

 

 

asctime, _wasctime

Converts a  tm  time structure to a character string.

      
        char
      
       *asctime( 
      
        const
      
      
        struct
      
       tm *
      
        timeptr );



wchar_t 
      
      *_wasctime( 
      
        const
      
      
        struct
      
       tm *timeptr );
    

 

Return Value

asctime  returns a pointer to the character string result;  _wasctime  returns a pointer to the wide-character string result. There is no error return value.

 

 

time

Gets the system time.

      time_t time( time_t *timer );
    

 

 

 

strftime, wcsftime

Format a time string.

      size_t strftime( 
      
        char
      
       *strDest, size_t maxsize, 
      
        const
      
      
        char
      
       *format, 
      
        const
      
      
        struct
      
       tm *
      
        timeptr );



size_t wcsftime( wchar_t 
      
      *strDest, size_t maxsize, 
      
        const
      
       wchar_t *format, 
      
        const
      
      
        struct
      
       tm *timeptr );
    

 

Return Value

strftime  returns the number of characters placed in  strDest  if the total number of resulting characters, including the terminating null, is not more than  maxsize .

wcsftime  returns the corresponding number of wide characters. Otherwise, the functions return 0, and the contents of  strDest  is indeterminate.

 

 

      
        void
      
       pcap_freealldevs  ( pcap_if_t *  alldevsp   )  
    

Free an interface list returned by  pcap_findalldevs() .  

 

winPcap_5_打开适配器并捕获数据包


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论