精华内容
下载资源
问答
  • winpcap教程

    千次阅读 2012-02-24 08:59:51
    winpcap教程 循序渐进学习使用WINPCAP(一) 一些需要知道的细节描述(前言): 这一部分展示了如何使用WINPCAP-API的不同的功能,它作为一个使用指南被划分为一系列的课时来带领读者循序渐进的体会PCAP...

    winpcap教程


    循序渐进学习使用WINPCAP(一)

    一些需要知道的细节描述(前言):
    这一部分展示了如何使用WINPCAP-API的不同的功能,它作为一个使用指南被划分为一系列的课时来带领读者循序渐进的体会PCAP的程序设计的

    魅力:从简单的基本功能(如获取网卡的列表,数据包的捕获等)到统计和收集网络流量等高级功能。

    在这里将提供一些简单但完整的代码作为参考:所有的这些原代码都有和它相关的详细信息的连接以便单击这些功能和数据结构时能够即使跳转到相关的文献。

    这些例子是用C语言写的,所以在学习之前首先要有一定的C语言的基础,当然PCAP作为一个网络底层的驱动,要想学好它也必须具备一定的网络方面的知识。



    (一)得到网络驱动列表

    用PCAP写应用程序的第一件事往往就是要获得本地的网卡列表。PCAP提供了pcap_findalldevs()这个函数来实现此功能,这个API返回一个pcap_if结构的连表,连表的每项内容都含有全面的网卡信息:尤其是字段名字和含有名字的描述以及有关驱动器的易读信息。

    得到网络驱动列表的程序如下:

    #include "pcap.h"

    main()
    {
      pcap_if_t *alldevs;
      pcap_if_t *d;
      int i=0;
      char errbuf[PCAP_ERRBUF_SIZE];
     
      /* 这个API用来获得网卡 的列表 */
      if (pcap_findalldevs(&alldevs, errbuf) == -1)
      {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
      }
     
      /* 显示列表的响应字段的内容 */
      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;
      }

      /* We don't need any more the device list. Free it */
      pcap_freealldevs(alldevs);
    }



    有关这段程序的一些说明:
    首先pcap_findalldevs()同其他的libpca函数一样有一个errbuf参数,当有异常情况发生时,这个参数会被PCAP填充为某个特定的错误字串。

    再次,UNIX也同样提供pcap_findalldevs()这个函数,但是请注意并非所有的系统都支持libpcap提供的网络程序接口。所以我门要想写出合适

    的程序就必须考虑到这些情况(系统不能够返回一些字段的描述信息),在这种情况下我门应该给出类似"No description available"这样的

    提示。

    最后结束时别忘了用pcap_freealldevs()释放掉内存资源。


    原文如下:

    Obtaining the device list


    The first thing that usually a WinPcap based application needs is a list of suitable network adapters. Libpcap provides the pcap_findalldevs() function for this purpose: this function returns a linked list of pcap_if structures, each of which contains comprehensive information about an adapter. In particular the fields name and description contain the name and a human readable description of the device.
    The following code retrieves the adapter list and shows it on the screen, printing an error if no adapters are found.


    #include "pcap.h"

    main()
    {
      pcap_if_t *alldevs;
      pcap_if_t *d;
      int i=0;
      char errbuf[PCAP_ERRBUF_SIZE];
     
      /* 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;
      }

      /* We don't need any more the device list. Free it */
      pcap_freealldevs(alldevs);
    }


    Some comments about this code.

    First of all, pcap_findalldevs(), like other libpcap functions, has an errbuf parameter. This parameter points to a string filled by libpcap with a description of the error if something goes wrong.

    Second, note that pcap_findalldevs() is provided by libpcap under Unix as well, but remember that not all the OSes supported by libpcap provide a description of the network interfaces, therefore if we want to write a portable application, we must consider the case in which description is null: we print the string "No description available" in that situation.

    Note finally that we free the list with pcap_freealldevs() once when we have finished with it.

    Let's try to compile and run the code of this first sample. In order to compile it under Unix or Cygwin, simply issue a:

    gcc -o testaprog testprog.c -lpcap

    On Windows, you will need to create a project, following the instructions in the "Using WinPcap in your programs " section of this manual. However, I suggest you to use the WinPcap developer's pack (available at the WinPcap website, http://winpcap.polito.it/ ), that provides a lot of properly configured example apps, all the code presented in this tutorial and all the projects, includes and libraries needed to compile and run the samples.

    Assuming we have compiled the program, let's try to run it. On my WinXP workstation, the result is

    1. {4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
    2. {5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)

    As you can see, the name of the network adapters (that will be passed to libpcap when opening the devices) under Windows are quite unreadable, so the description near them can be very useful to the user.

    dahubaobao 2004-11-18 00:54
    循序渐进学习使用WINPCAP(二)

    在第一章中演示了如何获得已存在适配器的静态信息。实际上WinPcap同样也提供其他的高级信息,特别是 pcap_findalldevs()这个函数返回的每个 pcap_if结构体都同样包含一个pcap_addr结构的列表,他包含:
    一个地址列表,一个掩码列表,一个广播地址列表和一个目的地址列表。
    下面的例子通过一个ifprint()函数打印出了pcap_if结构的的所有字段信息,该程序对每一个pcap_findalldevs()所返回的pcap_if结构循环调用ifprint()来显示详细的字段信息。


    #include "pcap.h"
    #ifndef WIN32
    #include
    #include
    #else
    #include
    #endif

    void ifprint(pcap_if_t *d);
    char *iptos(u_long in);

    int main()
    {
    pcap_if_t *alldevs;
    pcap_if_t *d;
    char errbuf[PCAP_ERRBUF_SIZE+1];

    /* 获得网卡的列表 */
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
      fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
      exit(1);
    }

    /* 循环调用ifprint() 来显示pcap_if结构的信息*/
    for(d=alldevs;d;d=d->next)
    {
      ifprint(d);
    }

    return 1;
    }

    /* Print all the available information on the given interface */
    void ifprint(pcap_if_t *d)
    {
    pcap_addr_t *a;

    /* Name */
    printf("%s\n",d->name);

    /* Description */
    if (d->description)
      printf("\tDescription: %s\n",d->description);

    /* Loopback Address*/
    printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

    /* IP addresses */
    for(a=d->addresses;a;a=a->next) {
      printf("\tAddress Family: #%d\n",a->addr->sa_family);

    /*关于 sockaddr_in 结构请参考其他的网络编程书*/
      switch(a->addr->sa_family)
      {
        case AF_INET:
        printf("\tAddress Family Name: AF_INET\n");//打印网络地址类型
        if (a->addr)//打印IP地址
          printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
        if (a->netmask)//打印掩码
          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
        if (a->broadaddr)//打印广播地址
          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
        if (a->dstaddr)//目的地址
          printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
        break;
        default:
        printf("\tAddress Family Name: Unknown\n");
        break;
      }
    }
    printf("\n");
    }

    /* 将一个unsigned long 型的IP转换为字符串类型的IP */
    #define IPTOSBUFFERS   12
    char *iptos(u_long in)
    {
      static char output[IPTOSBUFFERS][3*4+3+1];
      static short which;
      u_char *p;

      p = (u_char *)∈
      which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
      sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
      return output[which];

    }





    展开全文
  • WinPcap 教程

    千次阅读 2012-12-24 14:19:45
    WinPcap 教程  原文出处:http://winpcap.polito.it/docs/man/html/index.html  作者:  Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino  http://winpcap.polito.it  ...

    WinPcap 教程 
    原文出处:http://winpcap.polito.it/docs/man/html/index.html 

    作者: 
    Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino 
    http://winpcap.polito.it 

    译者: 
    记忆碎片 (val_cong@htomail.com) 
    http://www.s8s8.net 

    概述: 
    这篇教程将会指引读者逐步了解WinPcap编程, 从简单的基础函数(获取网络接口列表, 捕捉数据包)到更高级的内容(处理发送队列, 网络流量统计). 教程中包括一些代码片断, 以及一些简单但完整的例子, 读者可以参考这些例子更好的理解教程的内容. 这些例子全部用C语言写成, 所以基本的C语言编程知识是必要. 同时, 因为这篇教程的内容是与底层网络紧密相连的, 所以笔者假设读者已经具备有关网络和协议的相关知识. 

    译者的话: 
    WinPcap是一套免费的, 基于Windows的网络接口API, 它在底层网络操作方面对程序员很有帮助. 这篇文档翻译自 "WinPcap Documentation 3.0" 中的 "WinPcap tutorial: a step by step guide to program WinPcap" 一部分. 这篇教程对初学者的帮助很大, 尤其是简短清晰的例子, 但这篇教程只是整个文档的一小部分, 我认为你仍然需要参考文档的其它部分来了解各种结构等信息. 教程中注有前缀 "Y-" 的部分是译者为了让读者更明白作者的意思添加的, 原文中没有. 

    1. 获取网络接口列表 

    通常, 一个基于WinPcap的应用程序所要做的第一件事, 就是获得适合的网络接口的列表. Libpcap中的pcap_findalldevs()函数就是干这活的: 这个函数然回一个pcap_if结构的列表, 每个元素都记录了一个接口的信息. 其中, name和description以人类可以阅读的形式, 记录了设备的信息. 
    下面的源代码输出可用的网络接口的列表, 并且在没有找到任何借口的情况下输出错误信息: 
    #include "pcap.h" 
    main() 

    pcap_if_t *alldevs; 
    pcap_if_t *d; 
    int i=0; 
    char errbuf[PCAP_ERRBUF_SIZE]; 

    /* 取得列表 */ 
    if (pcap_findalldevs(&alldevs, errbuf) == -1) 

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


    /* 输出列表 */ 
    for(d=alldevs;d;d=d->next) 

    printf("%d. %s", ++i, d->name); 
    if (d->description) 
    printf(" (%s)\n", d->description); 
    else 
    /* Y- 没有有效的描述 */ 
    printf(" (No description available)\n"); 


    if(i==0) 

    /* Y- 没有有效的接口, 可能是因为没有安装WinPcap */ 
    printf("\nNo inte***ces found! Make sure WinPcap is installed.\n"); 
    return; 


    /* 我们不再需要列表了, 释放 */ 
    pcap_freealldevs(alldevs); 

     


    我们来看看这段代码. 

    首先, 和其他的libpcap函数一样, pcap_findalldevs(), 有一个错误缓冲区(errbuf)参数. 这个参数是一个字符串指针, 一旦发生错误,libpcap将会在这里填入错误描述. 然后, 请注意, pcap_findalldev系统下的s()函数同时也被UNIX下的libpcap所支持, 但是并不是所有的操作系统都支持"网络接口描述"(description)这一项. 所以, 如果我们想写一个可以移植的的应用程序,那么我们必须要为描述为"空"(null)的情况做好准备:遇到这种情况我们就输出一个"没有有效的描述"的消息. 

    最后我们通过pcap_freealldevs()函数来释放接口列表. 

    现在让我们编译并运行我们的第一个WinPcap程序. 如果你使用UNIX或者Cgywin的话, 你只需要以下命令: 

    gcc -o testaprog testprog.c -lpcap 

    在Windows环境中(Y - 如果你使用Microsoft Visual C++), 你需要建立一个工程, 按照"Using WinPcap in your programs " 一节中说明来做. 
    不过, 我仍然建议你参照Winpcap开发者包(WinPcap developer's pack)中的例子, 那些例子包括了所以配置完善的工程, 以及全部你所需要的库和包含文件. 
    (Y - 你可以在本章最后找到Microsoft Visual C++ 的配置方法) 

    假设现在你已经成功编译了程序, 我们就来运行它. 在我的WinXP工作站上, 输出结果是: 
    1. {4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter) 
    2. {5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI) 

    就如你所看到的, 网络接口的名称(当打开这个接口时, 需要传递这个名称给libpcap库)在windows环境下几乎是没有办法读懂的(Y-严重同意), 所以输出一个描述对于你的用户来说是非常有帮助的. 


    附注: Microsoft Visual C++ 工程的设置 
    1. 下载并安装 WinPcap, 推荐的版本是3.0 
    2. 从 http://winpcap.polito.it 下载 WinPcap Developer's Pack 并解压缩 
    3. 用 Microsoft Visual C++ 建立一个空工程 (empty project) 
    4. 复制源代码 
    5. 把 Winpcap Developer's Pack 中的 Includes 目录添加为新的包含文件目录 
    6. 添加库 wpcap.lib 和 wsock32.lib

     

    此篇文章来自【http://blog.163.com/szlear@126/blog/static/63703031200571000160/

    展开全文
  • Winpcap 教程

    2011-09-14 20:23:00
    原文出处:http://winpcap.polito.it/docs/man/html/index.html  作者:  Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino
    原文出处:http://winpcap.polito.it/docs/man/html/index.html  
    作者:  
    Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino  

    http://winpcap.polito.it  

    本文转载自协议分析网http://www.cnpaf.net/Class/winpcap/200610/16289.html

    概述:  
    这篇教程将会指引读者逐步了解WinPcap编程, 从简单的基础函数(获取网络接口列表, 捕捉数据包)到更高级的内容(处理发送队列, 网络流量统计). 教程中包括一些代码片断, 以及一些简单但完整的例子, 读者可以参考这些例子更好的理解教程的内容. 这些例子全部用C语言写成, 所以基本的C语言编程知识是必要. 同时, 因为这篇教程的内容是与底层网络紧密相连的, 所以笔者假设读者已经具备有关网络和协议的相关知识.  
    译者的话:  
    WinPcap是一套免费的, 基于Windows的网络接口API, 它在底层网络操作方面对程序员很有帮助. 这篇文档翻译自 "WinPcap Documentation 3.0" 中的 "WinPcap tutorial: a step by step guide to program WinPcap" 一部分. 这篇教程对初学者的帮助很大, 尤其是简短清晰的例子, 但这篇教程只是整个文档的一小部分, 我认为你仍然需要参考文档的其它部分来了解各种结构等信息. 教程中注有前缀 "Y-" 的部分是译者为了让读者更明白作者的意思添加的, 原文中没有.  
    1. 获取网络接口列表  
    通常, 一个基于WinPcap的应用程序所要做的第一件事, 就是获得适合的网络接口的列表. Libpcap中的pcap_findalldevs()函数就是干这活的: 这个函数返回一个pcap_if结构的列表, 每个元素都记录了一个接口的信息. 其中, name和description以人类可以阅读的形式, 记录了设备的信息.  
    下面的源代码输出可用的网络接口的列表, 并且在没有找到任何借口的情况下输出错误信息:  

    代码   
    #include "pcap.h"  
    main()  
    {  
    pcap_if_t *alldevs;  
    pcap_if_t *d;  
    int i=0;  
    char errbuf[PCAP_ERRBUF_SIZE];  
    /* 取得列表 */  
    if (pcap_findalldevs(&alldevs, errbuf) == -1)  
    {  
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);  
    exit(1);  
    }  
    /* 输出列表 */  
    for(d=alldevs;d;d=d->next)  
    {  
    printf("%d. %s", ++i, d->name);  
    if (d->description)  
    printf(" (%s)\n", d->description);  
    else  
    /* Y- 没有有效的描述 */  
    printf(" (No description available)\n");  
    }  
    if(i==0)  
    {  
    /* Y- 没有有效的接口, 可能是因为没有安装WinPcap */  
    printf("\nNo interfaces found! Make sure WinPcap is installed.\n");  
    return;  
    }  
    /* 我们不再需要列表了, 释放 */  
    pcap_freealldevs(alldevs);  
    }  
      
    我们来看看这段代码.  
    首先, 和其他的libpcap函数一样, pcap_findalldevs(), 有一个错误缓冲区(errbuf)参数. 这个参数是一个字符串指针, 一旦发生错误,libpcap将会在这里填入错误描述. 然后, 请注意, pcap_findalldev系统下的s()函数同时也被UNIX下的libpcap所支持, 但是并不是所有的操作系统都支持“网络接口描述”(description)这一项. 所以, 如果我们想写一个可以移植的的应用程序,那么我们必须要为描述为“空”(null)的情况做好准备:遇到这种情况我们就输出一个“没有有效的描述”的消息.  
    最后我们通过pcap_freealldevs()函数来释放接口列表.  
    现在让我们编译并运行我们的第一个WinPcap程序. 如果你使用UNIX或者Cgywin的话, 你只需要以下命令:  
    gcc -o testaprog testprog.c -lpcap  
    在Windows环境中(Y - 如果你使用Microsoft Visual C++), 你需要建立一个工程, 按照"Using WinPcap in your programs " 一节中说明来做.  
    不过, 我仍然建议你参照Winpcap开发者包(WinPcap developer’s pack)中的例子, 那些例子包括了所以配置完善的工程, 以及全部你所需要的库和包含文件.  
    (Y - 你可以在本章最后找到Microsoft Visual C++ 的配置方法)  
    假设现在你已经成功编译了程序, 我们就来运行它. 在我的WinXP工作站上, 输出结果是:  
    1. {4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)  
    2. {5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)  
    就如你所看到的, 网络接口的名称(当打开这个接口时, 需要传递这个名称给libpcap库)在windows环境下几乎是没有办法读懂的(Y-严重同意), 所以输出一个描述对于你的用户来说是非常有帮助的.  

    附注: Microsoft Visual C++ 工程的设置  
    1. 下载并安装 WinPcap, 推荐的版本是3.0  
    2. 从 http://winpcap.polito.it 下载 WinPcap Developer’s Pack 并解压缩  
    3. 用 Microsoft Visual C++ 建立一个空工程 (empty project)  
    4. 复制源代码  
    5. 把 Winpcap Developer’s Pack 中的 Includes 目录添加为新的包含文件目录  
    6. 添加库 wpcap.lib 和 wsock32.lib  
    原文出处:http://winpcap.polito.it/docs/man/html/index.html  
    作者:  
    Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino  
    http://winpcap.polito.it  
    2. 获取设备的高级信息  
    上一课我们介绍了如何获取一个设备的基本信息(比如设备名称和设备描述). 实际上, WinPcap 也可以为我们提供关于接口的更多信息. 由 pcap_findalldevs() 函数返回的 pcap_if 结构也包含了一个 pcap_addr 结构的列表, 它记录了以下信息:  
    1. 接口的地址列表  
    2. 接口的掩码列表 (与地址列表一一对应)  
    3. 接口的广播地址列表 (与地址列表一一对应)  
    4. 目标地址列表 (与地址列表一一对应)  
    下面例子中的 ifprint() 函数将会输出 pcap_if 结构的全部内容. 它包括了 pcap_findalldevs() 函数所返回的所有元素. ( Y- 全部有效接口)  

    代码   

    /*  
    * Copyright (c) 1999 - 2002  
    * Politecnico di Torino. All rights reserved.  [Page]
    *  
    * Redistribution and use in source and binary forms, with or without  
    * modification, are permitted provided that: (1) source code distributions  
    * retain the above copyright notice and this paragraph in its entirety, (2)  
    * distributions including binary code include the above copyright notice and  
    * this paragraph in its entirety in the documentation or other materials  
    * provided with the distribution, and (3) all advertising materials mentioning  
    * features or use of this software display the following acknowledgement:  
    * ``This product includes software developed by the Politecnico  
    * di Torino, and its contributors.’’ Neither the name of  
    * the University nor the names of its contributors may be used to endorse  
    * or promote products derived from this software without specific prior  
    * written permission.  
    * THIS SOFTWARE IS PROVIDED ``AS IS’’ AND WITHOUT ANY EXPRESS OR IMPLIED  
    * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF  
    * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  
    */  
    #include "pcap.h"  
    #ifndef WIN32  
    #include  
    #include  
    #else  
    #include  
    #endif  
    void ifprint(pcap_if_t *d);  
    char *iptos(u_long in);  
    int main()  
    {  
    pcap_if_t *alldevs;  
    pcap_if_t *d;  
    char errbuf[PCAP_ERRBUF_SIZE+1];  
    /* 获得设备列表 */  
    if (pcap_findalldevs(&alldevs, errbuf) == -1)  
    {  
    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);  
    exit(1);  
    }  
    /* 遍历所有元素 */  
    for(d=alldevs;d;d=d->next)  
    {  
    ifprint(d);  
    }  
    return 1;  
    }  
    /* Print all the available information on the given interface */  
    void ifprint(pcap_if_t *d)  
    {  
    pcap_addr_t *a;  
    /* 名称 */  
    printf("%s\n",d->name);  
    /* 描述 */  
    if (d->description)  
    printf("\tDescription: %s\n",d->description);  
    /* 回环地址 */  
    printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");  
    /* IP 地址 */  
    for(a=d->addresses;a;a=a->next) {  
    printf("\tAddress Family: #%d\n",a->addr->sa_family);  
    switch(a->addr->sa_family)  
    {  
    case AF_INET:  
    printf("\tAddress Family Name: AF_INET\n");  
    if (a->addr)  
    /* Y- IP 地址 */  
    printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));  
    if (a->netmask)  
    /* Y- 掩码 */  
    printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));  
    if (a->broadaddr)  
    /* Y- 广播地址 */  
    printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));  
    if (a->dstaddr)  
    /* Y - 目标地址 */  
    printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));  
    break;  
    default:  
    /* 未知 */  
    printf("\tAddress Family Name: Unknown\n");  
    break;  
    }  
    }  
    printf("\n");  
    }  
    /* 来自 tcptracert, 把数字IP地址转换为点格式 */  
    #define IPTOSBUFFERS 12  
    char *iptos(u_long in)  
    {  
    static char output[IPTOSBUFFERS][3*4+3+1];  
    static short which;  
    u_char *p;  
    p = (u_char *)∈  
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);  
    sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);  
    return output[which];  
    }  
    原文出处: http://winpcap.polito.it/docs/man/html/index.html  
    作者:  
    Loris Degioanni (degioanni@polito.it), NetGroup, Politecnico di Torino  
    http://winpcap.polito.it  
    3. 打开一个接口并捕捉流量  
    现在我们已经知道如何获取一个接口的有关信息了, 我们可以来点真家伙了 -- 打开一个接口并捕捉流量. 在这一课里, 我们会编译一个程序, 它将捕捉网络中所有的数据包并输出他们的一些相关信息。我们使用函数 
    pcap_open_live() 来打开一个捕捉设备. 这里, 我们需要解释一下 snaplen, promisc 和 to_ms 参数.  
    ( Y- 函数原型: pcap_t * pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf) )  
    "snaplen" 参数指定了要捕捉的数据包的部分. 在某些操作系统中 (如 xBSD 和 Win32), 驱动程序提供了只捕捉每个数据包其中一部分的可能性: 这样就降低了要处理的数据的量, 从而提高了捕捉程序的效率. 在例子中,
     我们使用一个高出 MTU 最大值的值 (65536) 以确保可以捕捉到整个数据包.  [Page]
    "promisc" 表明接口将会被设置为混杂模式
    . 一般情况下, 接口只处理目标地址为自己的数据; 到其他主机的数据包将会被忽略. 然而当一个接口处于混杂模式时, 它将会处理全部的流量: 也就是说, 在共享媒介 ( Y- 才疏学浅, 不知道怎么翻译好 ), 例如非交换型以太网 ( Y- 比如基于集线器的网络 )中, WinPcap 可以捕捉到所有主机的数据包. 混杂模式是多数捕捉程序的默认模式, 所以我们在例子中也采用这种模式.  
    "to_ms" 用以设置超时
    , 单位是毫秒. 一个从接口读取 ( Y- 捕捉) 的操作, (例如 pcap_dispatch() 或者 pcap_next_ex()), 如果没有捕捉到数据包, 那么在超过指定的时间以后就会返回. 进一步说, 如果接口处在静态模式中, to_ms 也定义了静态报告的间隔时间 (参阅 "Gathering Statistics on the network traffic " 以获取更多信息). 设置 to_ms 为 0, 则说明永远不会超时, 如果没有数据包到达, 那么捕捉操作将会永远不会返回, 而将其值设置为 -1 则会立刻返回.  

    代码   
    #include "pcap.h"  
    /* 数据包处理函数声明 */  
    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); 
    main()  
    {  
    pcap_if_t *alldevs;  
    pcap_if_t *d;  
    int inum;  
    int i=0;  
    pcap_t *adhandle;  
    char errbuf[PCAP_ERRBUF_SIZE];  
    /* 获取设备列表 */  
    if (pcap_findalldevs(&alldevs, errbuf) == -1)  
    {  
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);  
    exit(1);  
    }  
    /* 数据列表 */  
    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");  
    /* 释放设备列表 */  
    pcap_freealldevs(alldevs);  
    return -1;  
    }  
    /* 转到选择的设备 */  
    for(d=alldevs, i=0; i< inum-1;d=d->next, i++);  
    /* 打开设备 */  
    if ( (adhandle= pcap_open_live(d->name, //设备名  
    65536, // 捕捉完整的数据包  
    1, // 混在模式  
    1000, // 读入超时  
    errbuf // 错误缓冲  
    ) ) == NULL)  
    {  
    /* Y- 打开失败*/  
    fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");  
    /* 释放列表 */  
    pcap_freealldevs(alldevs);  
    return -1;  
    }  
    printf("\nlistening on %s...\n", d->description);  
    /* 我们已经不需要设备列表了, 释放它 */  
    pcap_freealldevs(alldevs);  
    /* 开始捕捉 */  
    pcap_loop(adhandle, 0, packet_handler, NULL);  
    return 0;  
    }  

    /* 处理数据包的回调函数*/  
    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) 
    {  
    struct tm *ltime;  
    char timestr[16];  
    /* 转换时间戳为可以阅读的格式 */  
    ltime=localtime(&header->ts.tv_sec);  
    strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);  
    printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);  
    }  
      
    一旦接口被打开, pcap_dispatch() 或者 pcap_loop() 函数将会开始捕捉. 这两个函数非常相似, pcap_dispatch() 将会在超时后直接返回, 而 pcap_loop() 则一定要等到一定数量的数据包被处理了以后才会返回 (Y- 第二个参数指定了要处理的数据包的数量, 0 为无限, 在这里, 我们设置的超时对 pcap_loop() 不起作用.) 在本例中, pcap_loop() 已经足够我们使用了, 而 pcap_dispatch() 一般应用在更复杂的程序里.  
    这两个函数都有一个回调参数, 只想一个处理数据包的函数, 如本例中的 packet_handler. 每当有新的数据包到来的时候, libpcap将会调用这个函数来处理数据包, libpcap也会提供这个数据包的一些信息: 一个首部, 包含了时间戳和长度信息 (Y-header 参数); 真实数据包 (Y- pkt_data参数), 包括各种协议首部. 请注意, MAC CRC一般不会出现, 因为当设备(网卡)进行帧确认操作时, 它就已经被移除了. 同时, 大部分网卡将会丢弃错误的 CRC, 所以 WinPcap 基本上也不能捕捉他们.  
    上面的例子只输出每个数据包时间戳以及长度 (来自 pcap_pkthdr header). 
    展开全文
  • WinPcap教程(1):获取网卡列表演示了如何获得网卡的基本信息(如设备名称和描述信息)。实际上,WinPcap还可以提供更多其他高级信息。特别地,pcap_findalldevs_ex()返回的pcap_if结构包含了一个pcap_addr结构列表,...

    WinPcap教程(1):获取网卡列表演示了如何获得网卡的基本信息(如设备名称和描述信息)。实际上,WinPcap还可以提供更多其他高级信息。特别地,pcap_findalldevs_ex()返回的pcap_if结构包含了一个pcap_addr结构列表,包括:

    -          网卡的地址列表

    -          网络掩码列表(其中每项和地址列表中的一项对应)

    -          广播地址列表(其中每项和地址列表中的一项对应)

    -          目的地地址列表(其中每项和地址列表中的一项对应)

     

    更进一步,pcap_findalldevs_ex()也可以返回远程网卡相关信息以及指定的本地目录中的pcap文件列表。

     

    下面的示例代码提供了一个打印pcap_if结构完整内容的函数ifprint()。它被pcap_findalldevs_ex()所返回的每一项(译注:即pcap_if结构)调用。

    /*

     * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)

     * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)

     * All rights reserved.

     *

     * Redistribution and use in source and binary forms, with or without

     * modification, are permitted provided that the following conditions

     * are met:

     *

     * 1. Redistributions of source code must retain the above copyright

     * notice, this list of conditions and the following disclaimer.

     * 2. Redistributions in binary form must reproduce the above copyright

     * notice, this list of conditions and the following disclaimer in the

     * documentation and/or other materials provided with the distribution.

     * 3. Neither the name of the Politecnico di Torino, CACE Technologies

     * nor the names of its contributors may be used to endorse or promote

     * products derived from this software without specific prior written

     * permission.

     *

     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

     *

     */

     

    #include <stdio.h>

     

    #include "pcap.h"

     

    #ifndef WIN32

        #include <sys/socket.h>

        #include <netinet/in.h>

    #else

        #include <winsock.h>

    #endif

     

     

    // Function prototypes

    void ifprint(pcap_if_t *d);

    char *iptos(u_long in);

    char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);

     

     

    int main()

    {

      pcap_if_t *alldevs;

      pcap_if_t *d;

      char errbuf[PCAP_ERRBUF_SIZE+1];

      char source[PCAP_ERRBUF_SIZE+1];

     

      printf("Enter the device you want to list:/n"

                "rpcap://              ==> lists interfaces in the local machine/n"

                "rpcap://hostname:port ==> lists interfaces in a remote machine/n"

                "                          (rpcapd daemon must be up and running/n"

                "                           and it must accept 'null' authentication)/n"

                "file://foldername     ==> lists all pcap files in the give folder/n/n"

                "Enter your choice: ");

     

      fgets(source, PCAP_ERRBUF_SIZE, stdin);

      source[PCAP_ERRBUF_SIZE] = '/0';

     

      /* Retrieve the interfaces list */

      if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)

      {

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

        exit(1);

      }

     

      /* Scan the list printing every entry */

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

      {

        ifprint(d);

      }

     

      pcap_freealldevs(alldevs);

     

      return 1;

    }

     

     

     

    /* Print all the available information on the given interface */

    void ifprint(pcap_if_t *d)

    {

      pcap_addr_t *a;

      char ip6str[128];

     

      /* Name */

      printf("%s/n",d->name);

     

      /* Description */

      if (d->description)

        printf("/tDescription: %s/n",d->description);

     

      /* Loopback Address*/

      printf("/tLoopback: %s/n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

     

      /* IP addresses */

      for(a=d->addresses;a;a=a->next) {

        printf("/tAddress Family: #%d/n",a->addr->sa_family);

     

        switch(a->addr->sa_family)

        {

          case AF_INET:

            printf("/tAddress Family Name: AF_INET/n");

            if (a->addr)

              printf("/tAddress: %s/n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));

            if (a->netmask)

              printf("/tNetmask: %s/n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));

            if (a->broadaddr)

              printf("/tBroadcast Address: %s/n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));

            if (a->dstaddr)

              printf("/tDestination Address: %s/n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));

            break;

     

          case AF_INET6:

            printf("/tAddress Family Name: AF_INET6/n");

            if (a->addr)

              printf("/tAddress: %s/n", ip6tos(a->addr, ip6str, sizeof(ip6str)));

           break;

     

          default:

            printf("/tAddress Family Name: Unknown/n");

            break;

        }

      }

      printf("/n");

    }

     

     

     

    /* From tcptraceroute, convert a numeric IP address to a string */

    #define IPTOSBUFFERS    12

    char *iptos(u_long in)

    {

        static char output[IPTOSBUFFERS][3*4+3+1];

        static short which;

        u_char *p;

     

        p = (u_char *)&in;

        which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);

        _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);

        return output[which];

    }

     

    char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)

    {

        socklen_t sockaddrlen;

     

        #ifdef WIN32

        sockaddrlen = sizeof(struct sockaddr_in6);

        #else

        sockaddrlen = sizeof(struct sockaddr_storage);

        #endif

     

     

        if(getnameinfo(sockaddr,

            sockaddrlen,

            address,

            addrlen,

            NULL,

            0,

            NI_NUMERICHOST) != 0) address = NULL;

     

        return address;

    }

     

    此文章来自于【http://blog.csdn.net/pathuang68/article/details/4291667

    展开全文
  • WinPcap教程(3):打开网卡抓包

    千次阅读 2009-06-23 19:58:00
    前篇:WinPcap教程(2):获取设备高级信息 我们已经知道如何获取网卡信息了,现在让我们开始进行真正的开发工作,即打开一个网卡并抓取数据包。本文中,我们将写一个程序来打印出流经网卡的每个包的相关信息。 打开...
  • 在这一节中讲述了,如何给予WinPcap获取网络适配器列表。主要通过函数pcap_findalldevs_ex(),它返回一个pcap_if结构的链表,每一个pcap_if结构保存一个适配器的信息,遍历输出所有的适配器信息后,要记得调用pcap_...
  • 通常,编写基于WinPcap应用程序的第一件事情,就是获得已连接的网络适配器列表。 libpcap和WinPcap都提供了pcap_findalldevs_ex()函数来实现这个功能。这个函数返回一个pcap_if结构的链表,每个这样的结构都包含了...
  • Winpcap教程(高级应用)

    千次阅读 2009-10-20 15:21:00
    循序渐进学习使用WINPCAP(五)WinPcap或libpca最强大的特点之一就是数据流的过滤引擎。它提供一种高效的方法来只捕获网络数据流的某些数据而且常常和系统的捕获机制相集成。过滤数据的函数是pcap_compile() 和 pcap...
  • Winpcap教程(获取数据包)

    千次阅读 2009-10-20 15:11:00
    循序渐进学习使用WINPCAP(一)一些需要知道的细节描述(前言):这一部分展示了如何使用WINPCAP-API的不同的功能,它作为一个使用指南被划分为一系列的课时来带领读者循序渐进的体会PCAP的程序设计的魅力:从简单的...
  • 它是以教程的方式来组织的,并细分为一系列的课程,以step-by-step的方式,向读者介绍如何利用WinPcap编程,从基本的功能(获取网卡列表,抓包等等)到最高级的功能(处理发送队列和收集网络流量统计数据)。   代码...
  • 尽管WinPcap从名字上来看表明他的主要目的是捕获数据包,但是他还为原始网络提供了一些其他的功能,其中 之一就是用户可以发送数据包,这也就是本节的主要内容。需要指出的是原来的libpcap并不提供数据包 的发 ...
  • 事 实上,WinPcap提供了其他更高级的信息。 特别需要指出的是,由pcap_findalldevs_ex()返回的每一个pcap_if结构体都包含一个pcap_addr结构体,这个结构体由如下元素组成: 一个地址列表一个掩码列表(each of ...
  • 注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将 CRC 删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap 没法捕获到它们。 if ( (adhandle= pcap...
  • WinPcap或libpca最强大的特点之一就是数据流的过滤引擎。它提供一种高效的方法来只捕获网络数据流的某些数据而且常常和系统的捕获机制相集成。过滤数据的函数是pcap_compile() 和 pcap_setfilter()来实现的。 ...
  • WINPCAP为我们提供了很多API来将流经网络的数据包保存到一个堆文件并读取堆的内容。这一节将讲述如何使用所有的这些API。 这种文件的格式很简单,但包含了所捕获的数据报的二进制内容,这种文件格式也是很多网络...
  • 这一部分展示了如何使用WINPCAP-API的不同的功能,它作为一个使用指南被划分为一系列的课时来带领读者循序渐进的体会PCAP的程序设计的 魅力:从简单的基本功能(如获取网卡的列表,数据包的捕获等)到统计和收集...
  • 本文所实现的功能和效果和上一讲的非常相似,但本文将用pcap_next_ex()函数代替上文的pcap_loop() 函数。 pcap_loop() 函数是基于回调的原理来进行数据捕获,这是一种精妙的方法,并且在某些场合中,它是一种很好...
  • 到达并被确认后网卡就把它删除了,同样需要注意的是大多数网卡会丢掉冗余码出错的数据包,所以WinPcap一 般不能够捕获这些出错的数据报。 刚才的例子里从pcap_pkthdr中提取出了每个数据报的时间戳和长度并...
  • WinPcap教程(1):获取网卡列表

    千次阅读 2009-06-22 15:56:00
    它是以教程的方式来组织的,并细分为一系列的课程,以step-by-step的方式,向读者介绍如何利用WinPcap编程,从基本的功能(获取网卡列表,抓包等等)到最高级的功能(处理发送队列和收集网络流量统计数据)。 代码片段...
  • Winpcap使用教程

    2014-11-21 20:16:34
    Winpcap使用教程附VS2010程序,绝对是个好东东。
  • Winpcap 开发教程

    2017-12-22 11:53:29
    一、Winpcap开发包能干嘛? 获取可用网卡的列表 获取网卡的信息,包括数量,名字,地址 嗅探抓包 向网络发数据包 将从网卡获取的网络流保存到磁盘 对已经抓取的包进行使用高级语言进行过滤 跨平台,在windows下用...
  • winpcap开发教程

    2014-01-13 16:11:39
    winpcap是网络抓包库,可方便快捷的开发sniffer相关应用
  • winpcap使用教程

    热门讨论 2008-12-10 17:57:59
    winpcap使用教程,其中包含九个章节,(9个。doc),和一个C++程序实例包。有兴趣者可以看看。
  • winpcap学习教程

    2015-05-23 12:30:23
    通常,编写基于WinPcap应用程序的第一件事情,就是获得已连接的网络适配器列表。libpcap和WinPcap都提供了 pcap_findalldevs_ex() 函数来实现这个功能: 这个函数返回一个 pcap_if结构的链表,每个这样的结构都...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 160
精华内容 64
关键字:

winpcap教程