使用winpcap开发网络抓包工具

前言:
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它用于windows系统下的直接的网络编程。进行过网络方面学习的都知道,wireshark软件是基于winpcap的,winpcap可直接开发基于网络底层协议的应用程序,例如arp,以后会写一篇arp的开发、应用和防御
功能需求:
1、截取主机A发送给主机B的消息
2、获取消息保存到文件
3、将消息下发到主机B
4、截取接收主机B消息
5、获取消息保存到文件
6、将消息转发到主机A
程序设计
1、由于winpcap是基于网卡的数据获取,所以先获取正确的网卡
2、打开选择的网卡设备
设计一个获取主机A消息的线程和一个获取主机B消息的线程。
相关接口介绍
1、int pcap_findalldevs(pcap_if_t **, char *);//获取所有网络设备,保存于pcap_if_t 指向的内存空间
2、void pcap_freealldevs(pcap_if_t *); // 清空所有网络设备
3、pcap_t *pcap_open(const char *source, // 获取的设备名
int snaplen, //要捕捉的数据包的部分
int flags, // 模式
int read_timeout,// 超时时间
struct pcap_rmtauth *auth, // 远程机器验证
char *errbuf);// 错误缓冲池

4、void pcap_close(pcap_t *);//关闭设备
5、int pcap_compile(//编译过滤规则
pcap_t *,
const char *,
int,
bpf_u_int32);

6、int pcap_setfilter(pcap_t *, struct bpf_program *);// 设置过滤规则
7、int pcap_next_ex(// 从interface或离线记录文件获取一个报文
pcap_t *,
struct pcap_pkthdr **, // 报文头,包含mac地址
const u_char **);//报文内容

程序设计
main.cpp

#include "pcap.h"
#include "vector"

using namespace std;

int main()
{
    vector<string> vecDevName;
    vecDevName.clear();
    pcap_if_t *alldevs;
    char errbuf[PCAP_ERRBUF_SIZE];

    /*查询网卡设备*/
    if(pcap_findalldevs(&alldevs, errbuf) == -1)
    {       
        /* At this point, we don't need any more the device list. Free it */
        pcap_freealldevs(alldevs);
        return -1;  
    }
    while (alldevs->next != NULL)
    {
        printf("%s:%s \n", alldevs->name, alldevs->description);
        vecDevName.push_back(alldevs->name);
        alldevs = alldevs->next;
    }

    // 打开网络设备
    pcap_t *adhandle;
    /* Open the device */

    /* 打开设备 */
    if ( (adhandle= pcap_open(vecDevName[0].c_str(),          // 设备名
        65536,            // 要捕捉的数据包的部分 
        // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
        PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
        1000,             // 读取超时时间
        NULL,             // 远程机器验证
        errbuf            // 错误缓冲池
        ) ) == NULL)
    {
        // fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        return -1;
    }

    // 编译过滤规则
    bpf_u_int32 NetMask=0xffffff;
    struct bpf_program fcode;
    char szFilter[256];
    sprintf(szFilter, "ip host 192.168.1.254");
    //compile the filter
    if(pcap_compile(adhandle, &fcode, szFilter, 1, NetMask) < 0)
    {
        //strTip.Format("Error compiling filter: wrong syntax:%s", szFilter);
        pcap_close(adhandle);
        return -3;
    }
    // 设置过滤规则
    if(pcap_setfilter(adhandle, &fcode) < 0)
    {
        pcap_close(adhandle);
        return -4;
    }

    int res;
    struct pcap_pkthdr *header;
    const u_char *pkt_data;
    time_t local_tv_sec;
    struct tm *ltime;
    char timestr[16];
    while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0)
    {
        if(res == 0)
            continue;

        /* 将时间戳转换成可识别的格式 */
        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);
    }
    return 0;
}

你可能感兴趣的:(计算机网络)