`
eggbucket
  • 浏览: 186530 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

winpcap捕获数据包

    博客分类:
  • C++
 
阅读更多

//技术手册:http://www.ferrisxu.com/WinPcap/html/index.html



 

Winpcap配置编程环境以及出错处理
2011-04-20 11:58

Winpcap配置编程环境:

安装Winpcap,接着:
1> 从WWW.WINPCAP.ORG 上下载WINPCAP SDK -WpdPack,WinPcap SDk 里面包含库
文件,头文件,文档文件和一些例子。解压到一个指定的目录。解压缩后把Include 目录添
加到IDE 的包含文件中(VC6.0 Tools->Option->Directory; VS 2003/2005/2008 工具->选项->项目
和解决方案/ 项目->VC++ 目录); lib 目录添加为新的库文件目录( VC6.0
Tools->Option->Directory; VS 2003/2005/2008 工具->选项->项目和解决方案/项目->VC++目录);

添加wpcap.lib和ws2_32.lib(工程属性->链接器->输入->附加依赖项)

 


2> 如果一个源文件使用了WinPcap 提供的库函数,那么就需要在该文件开始的位置添加
pcap.h 包含文件(或者在引用的文件中),即#include “pcap.h”
也许会出现下面的错误:
fatal error C1083: 无法打开包括文件:“pcap.h”: No such file or directory
这个错误表明找不到pcap.h 文件,这个头文件在驱动程序安装完成后也是没有的,它是开
发包里面的一个头文件,所以,如果要运行程序还需要到官方网站上去下载WinPcap SDK,
并按步骤1 添加到项目中。
3> 在程序中添加wpcap.lib。如果出现下面错误
error LNK2019: 无法解析的外部符号_pcap_findalldevs_ex,该符号在函数XXX 中被引用,
如果发生上面的错误就表明缺少库文件, 需要添加wpcap.lib 到工程中(VC6.0
Project->Settings->Link->Object/library modules; VS 2003/2005/2008 项目->添加现有项->所有文件)

 

4> 新的版本里WinPcap 支持远程数据包获取,所以还应当添加预处理定义WPCAP和HAVE_REMOTE
添加时注意必须以如下图的格式为好:


否则会发生下面的错误

error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符
error C3861: “pcap_findalldevs_ex”: 找不到标识符
error C2065: “PCAP_OPENFLAG_PROMISCUOUS”: 未声明的标识符
error C3861: “pcap_open”: 找不到标识符

5> 如果还有问题,可以到WinPcaP 官方网站上找FAQ。

 

 

如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。
也可以不安装WinPcap驱动程序。但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下。(似乎有些问题)

pcap_open()
pcap_open() 为捕获/发送数据打开一个普通的源。pcap_open()能够替代所有的pcap_open_xxx()函数,它隐藏了不同的pcap_open_xxx()之间的差异,所以程序员不必使用不同的open函数。

pcap_open(source,snaplen,flags,read-timeout,auth,errbuf);

source:的是包含要打开的源名称的以’\0’结尾的字符串。源名称得包含新的源规范语法 (Source Specification Syntax),并且它不能为NULL。为了方便的使用源语法,请记住: (1)pcap_findalldevs_ex()返回的适配器(网卡)可以直接被pcap_open()使用;(2)万一用户想传递他自己的源字符串给 pcap_open(),pcap_createsrcstr()可以创建正确的源标识。

snaplen:需要保留的数据包的长度。对每一个过滤器接收到的数据包,第一个‘snaplen’字节的内容将被保存到缓冲区,并且传递给用户程 序。例如,snaplen等于100,那么仅仅每一个数据包的第一个100字节的内容被保存。简言之就是从每一个包的开头到snaplen的那段内容将被 保存。

flags:保存一些由于抓包需要的标志。Winpcap定义了三种标志:

l         PCAP_OPENFLAG_PROMISCUOUS:1,它定义了适配器(网卡)是否进入混杂模式(promiscuous mode)。

l         PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。

l         PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。

read_timeout:以毫秒为单位。read timeout被用来设置在遇到一个数据包的时候读操作不必立即返回,而是等待一段时间,让更 多的数据包到来后从OS内核一次读多个数据包。并非所有的平台都支持read timeout;在不支持read timeout的平台上它将被忽略。

auth:一个指向’struct pcap_rmtauth’的指针,保存当一个用户登录到某个远程机器上时的必要信息。假如不是远程抓包,该指针被设置为NULL。

errbuf:一个指向用户申请的缓冲区的指针,存放当该函数出错时的错误信息。

返回值是一个’pcap_t’指针(就是我们一般所说的网卡的指针),它可以作为下一步调用(例如pcap_compile()等)的参数,并且指定了一个已经打开的Winpcap会话。在遇到问题的情况下,它返回NULL并且’errbuf’变量保存了错误信息。

 

 

如何获取数据包的内容呢?

我们首先来看看包的结构:



 

 

 

当我们过滤掉:以太头,ip,tcp/udp 之后就是我们需要的数据包的内容了



源代码:

#include "stdafx.h"
#include<iostream>
using namespace std;
#include <pcap.h>
using namespace std;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <net.h>
#pragma comment(lib,"ws2_32.lib")
#define MAX_PRINT 80
#define MAX_LINE 16


#pragma once

 

typedef unsigned char u_int8_t;
typedef unsigned short int u_int16_t;
typedef unsigned int u_int32_t;
#define  ETH_ALEN 6

struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
 unsigned int ihl:4;
 unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
 unsigned int version:4;
 unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
 u_int8_t tos;
 u_int16_t tot_len;
 u_int16_t id;
 u_int16_t frag_off;
 u_int8_t ttl;
 u_int8_t protocol;
 u_int16_t check;
 u_int32_t saddr;
 u_int32_t daddr;
 /*The options start here. */
};

# ifdef __FAVOR_BSD
typedef u_int32_t tcp_seq;
/*
* TCP header.
* Per RFC 793, September, 1981.
*/
struct tcphdr
{
 u_int16_t th_sport;         /* source port */
 u_int16_t th_dport;         /* destination port */
 tcp_seq th_seq;             /* sequence number */
 tcp_seq th_ack;             /* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
 u_int8_t th_x2:4;           /* (unused) */
 u_int8_t th_off:4;          /* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDIAN
 u_int8_t th_off:4;          /* data offset */
 u_int8_t th_x2:4;           /* (unused) */
#  endif
 u_int8_t th_flags;
#  define TH_FIN        0x01
#  define TH_SYN        0x02
#  define TH_RST        0x04
#  define TH_PUSH       0x08
#  define TH_ACK        0x10
#  define TH_URG        0x20
 u_int16_t th_win;           /* window */
 u_int16_t th_sum;           /* checksum */
 u_int16_t th_urp;           /* urgent pointer */
};

# else /* !__FAVOR_BSD */
struct tcphdr
{
 u_int16_t source;
 u_int16_t dest;
 u_int32_t seq;
 u_int32_t ack_seq;
#  if __BYTE_ORDER == __LITTLE_ENDIAN
 u_int16_t res1:4;
 u_int16_t doff:4;
 u_int16_t fin:1;
 u_int16_t syn:1;
 u_int16_t rst:1;
 u_int16_t psh:1;
 u_int16_t ack:1;
 u_int16_t urg:1;
 u_int16_t res2:2;
#  elif __BYTE_ORDER == __BIG_ENDIAN
 u_int16_t doff:4;
 u_int16_t res1:4;
 u_int16_t res2:2;
 u_int16_t urg:1;
 u_int16_t ack:1;
 u_int16_t psh:1;
 u_int16_t rst:1;
 u_int16_t syn:1;
 u_int16_t fin:1;
#  else
#   error "Adjust your <bits/endian.h> defines"
#  endif
 u_int16_t window;
 u_int16_t check;
 u_int16_t urg_ptr;
};
#endif

#define ETH_P_802_3     0x0001          /* Dummy type for 802.3 frames  */
#define ETH_P_AX25      0x0002          /* Dummy protocol id for AX.25  */
#define ETH_P_ALL       0x0003          /* Every packet (be careful!!!) */
#define ETH_P_802_2     0x0004          /* 802.2 frames                 */
#define ETH_P_SNAP      0x0005          /* Internal only                */
#define ETH_P_DDCMP     0x0006          /* DEC DDCMP: Internal only     */
#define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
#define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
#define ETH_P_LOCALTALK 0x0009          /* Localtalk pseudo type        */
#define ETH_P_CAN       0x000C          /* Controller Area Network      */
#define ETH_P_PPPTALK   0x0010          /* Dummy type for Atalk over PPP*/
#define ETH_P_TR_802_2  0x0011          /* 802.2 frames                 */
#define ETH_P_MOBITEX   0x0015          /* Mobitex (
kaz@cafe.net )       */
#define ETH_P_CONTROL   0x0016          /* Card specific control frames */
#define ETH_P_IRDA      0x0017          /* Linux-IrDA                   */
#define ETH_P_ECONET    0x0018          /* Acorn Econet                 */
#define ETH_P_HDLC      0x0019          /* HDLC frames                  */
#define ETH_P_ARCNET    0x001A          /* 1A for ArcNet :-)            */
struct ethhdr {
 unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
 unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
 u_int16_t          h_proto;                /* packet type ID field */
} ;

 

/* 4字节的IP地址 */
typedef struct ip_address{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
}ip_address;

/* IPv4 首部 */
typedef struct ip_header{
    u_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)
    u_char  tos;            // 服务类型(Type of service)
    u_short tlen;           // 总长(Total length)
    u_short identification; // 标识(Identification)
    u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
    u_char  ttl;            // 存活时间(Time to live)
    u_char  proto;          // 协议(Protocol)
    u_short crc;            // 首部校验和(Header checksum)
    ip_address  saddr;      // 源地址(Source address)
    ip_address  daddr;      // 目的地址(Destination address)
    u_int   op_pad;         // 选项与填充(Option + Padding)
}ip_header;

/* UDP 首部*/
typedef struct udp_header{
    u_short sport;          // 源端口(Source port)
    u_short dport;          // 目的端口(Destination port)
    u_short len;            // UDP数据包长度(Datagram length)
    u_short crc;            // 校验和(Checksum)
}udp_header;



/* packet handler 函数原型 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[] = "dst host 192.168.0.1";//过了条件port 20 and ip and tcp dst host 127.0.0.1
struct bpf_program fcode;

    
    /* 获取本机设备列表 */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &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(d->name,          // 设备名
                              65536,            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
                                 PCAP_OPENFLAG_NOCAPTURE_RPCAP,//PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
                              1000,             // 读取超时时间
                              NULL,             // 远程机器验证
                              errbuf            // 错误缓冲池
                              ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        /* 释放设备列表 */
        pcap_freealldevs(alldevs);
        return -1;
    }
    


      /* 检查数据链路层,为了简单,我们只考虑以太网 */
    if(pcap_datalink(adhandle) != DLT_EN10MB)
    {
        fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
        /* 释放设备列表 */
        pcap_freealldevs(alldevs);
        return -1;
    }
    
    if(d->addresses != NULL)
        /* 获得接口第一个地址的掩码 */
        netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
    else
        /* 如果接口没有地址,那么我们假设一个C类的掩码 */
        netmask=0xffffff;


    //编译过滤器
    if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
    {
        fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
        /* 释放设备列表 */
        pcap_freealldevs(alldevs);
        return -1;
    }
    
    //设置过滤器
    if (pcap_setfilter(adhandle, &fcode)<0)
    {
        fprintf(stderr,"\nError setting the filter.\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;
}


/* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    /*struct tm *ltime;
    char timestr[16];
    time_t local_tv_sec;
    
    // 将时间戳转换成可识别的格式
    local_tv_sec = header->ts.tv_sec;
    ltime=localtime(&local_tv_sec);
    strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
    
    printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);*/

    struct tm *ltime;
    struct iphdr *ip;
    struct ethhdr *eth;
    struct tcphdr *tcp;

    char timestr[16];
    ip_header *ih;
    udp_header *uh;
    u_int ip_len;
    u_short sport,dport;
    time_t local_tv_sec;
    
    
    pkt_data=(pkt_data + sizeof(struct ethhdr) + sizeof(struct iphdr)+sizeof(struct tcphdr))-4;//-4 表示移动32位
    
    const char* target="corporation/login_corporation.yizhi?method=verify";
    
    if(!(strstr((char*)pkt_data,target)))
    {
        return;
    }


    if()

        oa/corporation/login_corporation.yizhi?method=verify
    cout<<pkt_data<<endl;

    

}

 

  • 大小: 65.7 KB
  • 大小: 70 KB
  • 大小: 61.4 KB
  • 大小: 31.5 KB
分享到:
评论

相关推荐

    WinPcap捕获数据包程序

    WinPcap捕获数据包程序是网络分析和监控领域中的一个重要工具,主要用于在Windows操作系统上抓取、过滤和分析网络数据包。这个程序基于WinPcap库,它是一个开源的系统级库,允许应用程序访问网络接口层的数据包,而...

    利用Winpcap捕获发送数据包.docx

    "Winpcap 捕获数据包" Winpcap 捕获数据包是指通过 Winpcap 库来捕获和发送数据包的过程。Winpcap 库提供了捕获数据包的功能,可以在数据链路层捕获数据包,提供最原始的信息。 Winpcap 捕获数据包的原理是在第一...

    winpcap编程捕获数据包

    WinPcap编程捕获数据包是网络编程领域中的一个重要概念,尤其对于网络监控、数据分析以及安全检测等应用来说,它是核心工具之一。WinPcap是一个开源库,它为Windows操作系统提供了底层网络访问能力,允许程序直接与...

    Winpcap捕获数据包

    在“Winpcap捕获数据包”的主题中,我们将深入探讨Winpcap的工作原理、捕包过程以及如何分析捕获到的数据包。 首先,Winpcap的工作机制基于Windows操作系统内核驱动,它提供了一个接口,使得应用程序能够绕过常规的...

    WinPcap捕获数据包源码

    我们现在用的windows xp都应该升级到了...而且在windows 里面不能用它截获所有流过你网卡的数据包,windows系统进行了限制,所以我就使用WinPcap做了个能截获所有数据包的程序。没有太多的注释,请自行查阅相关资料。

    winpcap数据包捕获系统

    下面是一个简单的C++代码示例,演示了如何使用WinPcap捕获局域网中的数据包: ```cpp #include #include void packet_handler(u_char* user, const struct pcap_pkthdr* pkthdr, const u_char* packet) { // 在...

    基于WinPcap的网络数据包捕获与分析(源码)

    基于WinPcap的网络数据包捕获与分析源码C++源码,包括文档详细解释

    libpcap(winpcap)捕获数据包与存储和读取

    ### libpcap(winpcap)捕获数据包与存储和读取 #### 环境:libpcap + Qt Creator 在计算机网络领域中,数据包捕获是一项非常重要的技术,它允许开发者和网络工程师捕获并分析通过网络传输的数据包。libpcap(在...

    基于Winpcap的数据包捕获相关论文

    WinpCap实现UDP网络数据包的分析与设计.pdf ...基于Winpcap的数据包捕获和协议分析系统的设计与实现.pdf 基于WinPcap的网络数据解析及其实现.pdf 使用Winpcap开发网络数据包分析器.pdf 以太网数据包捕获技术的研究.pdf

    c#捕获数据包(Winpcap)

    3. **初始化设备**:使用`Pcap.Net.DeviceCollection`获取所有可用的网络接口,并选择要捕获数据包的设备。可以使用`Device.Description`属性来显示设备的名称,供用户选择。 4. **设置捕获参数**:使用`...

    一个基于winpcap的数据包回放程序

    一个基于winpcap的数据包回放程序,c++编写,要求从本地打开pcap文件并且发送出去,同时捕获发送出去的数据并且打印出来 同一台主机收发 以太网数据,ARP协议 还有就是直接用mac地址收发 Win32控制台,就显示目的地址...

    WinPcap捕获网络数据包

    WinPcap捕获网络数据包是一项核心技术,尤其在网络安全、网络监控和协议分析等领域中扮演着重要角色。WinPcap是Windows平台上的一个开源库,它允许程序员直接访问网络接口层,实现对网络数据包的捕获和发送,提供了...

    利用WinPcap技术捕获数据包

    【WinPcap技术详解及其在网络数据包捕获中的应用】 WinPcap技术是网络数据包捕获领域的核心工具,尤其在网络入侵取证系统中扮演着关键角色。随着网络安全问题的日益严重,有效地捕获和分析网络数据包成为保障网络...

    winpcap下网络数据包捕获教程

    使用WinPcap捕获数据包主要包括以下几个步骤: - **安装WinPcap**: 在使用WinPcap之前,需要在系统上安装WinPcap库。WinPcap不仅可以捕获数据包,还支持发送自定义的数据包。 - **打开适配器**: 使用WinPcap API...

    WinPcap数据包捕获程序

    3. **初始化WinPcap**:在代码中调用`pcap_open_live()`函数,指定要捕获数据包的网络接口。 4. **设置过滤器**:如果需要,可以使用`pcap_compile()`和`pcap_setfilter()`来定义和应用过滤规则。 5. **开始捕获**:...

    利用WipCap捕获网络数据包并分析数据包,含源代码和工程文件,学习网络数据包捕获分析以及WinPcap的好程序

    2. **WinPcap API**:熟悉WinPcap提供的函数,如`pcap_open_live()`用于打开网络接口,`pcap_loop()`或`pcap_next()`用于捕获数据包。 3. **数据包过滤**:使用BPF(Berkeley Packet Filter)语法创建过滤规则,...

    winpcap数据包捕获

    以下是一些基本的步骤,用于在VC环境下使用WinPcap捕获数据包: 1. **安装WinPcap**: 首先,你需要在计算机上安装WinPcap库。这将同时安装必要的驱动程序和开发库,使你的VC项目能够链接到WinPcap。 2. **包含...

    基于WINPCAP ARP数据包捕获

    3. **设置捕获过滤器**:通过`pcap_setfilter()`函数,可以设定捕获数据包的过滤规则。例如,为了只捕获ARP数据包,我们可以设置一个表达式,如`arp`,这样WinPcap将只捕获ARP协议的数据包。 4. **开始捕获**:调用...

    winpcap发送数据包的例子

    WinPcap是一个强大的网络数据包捕获和网络分析工具,主要在Windows平台上使用。它允许应用程序访问网络接口的底层硬件,实现数据包的捕获、过滤、发送等功能。本示例将详细介绍如何利用WinPcap库来发送自定义的...

Global site tag (gtag.js) - Google Analytics