winpcap 快速入门 实现抓包&&发包

winpcap 快速入门 抓包&&发包

一、 概述

本博客将叙述几个关键的winpcap api

研习完本博客,可以最终实现抓包/发包操作

环境描述:

  • 系统: windows 8.1

  • 编译器: visaul stiduo 2015

  • pcap 执行版本: 4.1.3

  • pcap 开发包版本: 4.1.2

环境配置:

传送门:winpcap在visual stiduo 2015上进行配置

二、API介绍

int pcap_findalldevs_ex

使用目的

主要用于获得所有本地的网络接口

参数介绍

  • char *source: 关于lcoal/remote的设定,如果是查找本地的网路设备,填写PCAP_SRC_IF_STRING

  • struct pcap_rmtauth *auth: 权限设置,一般填NULL

  • pcap_if_t **alldevs: 保存扫描结果。struct pcapift保存了设备的信息/描述

winpcap 快速入门 实现抓包&&发包_第1张图片

  • char *errbuf: 如果函数出错,则错误信息保存在这里

返回值

0 : 成功执行
-1 : 执行失败

示例

    pcap_if_t * allDevs;
    pcap_if_t * dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allDevs, errbuf) > 0) {
        printf("pcap_findallDevs_ex failed\n");
    }
    for (dev = allDevs; dev->next != NULL; dev = dev->next) {
        printf("----------------------------\n");
        printf("name %s\n", dev->name);
        printf("description :%s\n", dev->description);
    }

结果截图

winpcap 快速入门 实现抓包&&发包_第2张图片

pcap_t* pcap_open

使用目的

主要用于对指定的网络设备进行抓包/发包

参数介绍

  • const char *source: 填充pcap_if_t -> name, 用于指定网络设备

  • int snaplen: 最大接受数据包的大小

  • int flags: 网络设备的监听模式,一般设置为混杂模式PCAP_OPENFLAG_PROMISCUOUS,即只要经过该网络设备的数据包都会被捕获

  • int read_timeout: 抓到包之后,并不是立即返回,而是再允许其他的包进入。此参数可能存在系统不支持

  • struct pcap_rmtauth * auth: 权限,一般传入NULL

  • char * errbuf: 如果函数出错,存储错误信息

返回值

pcap_t * : 执行成功

NULL : 执行失败,错误信息填充在errbuf

int pcap_next_ex()

主要用途

抓包(抓一次,抓一个)

参数介绍

  • pcap_t * p: 指定抓包的网络设备,即pcap_open的返回值

winpcap 快速入门 实现抓包&&发包_第3张图片

  • struct pcap_pkthdr ** pkt_header: 抓到包的描述,由winpcap自动生成

  • const u_char ** pkt_data: 存储完整的包数据

返回值

1: 成功执行

0 : 超时,此时pkt_header,pkt_data所指向的包并不是有效的

-1 : 出现错误

-2 : 读取离线包时,出现了EOF结束符

int pcap_sendpacket()

主要用途

发包

参数介绍

  • pcap_t * p: 指定网络设备,使用此网络设备进行发包

  • u_char * buf: 数据包

  • int size: 数据包的大小

返回值

0 : 发送成功

-1 : 发送失败

三、综合示例

抓包演示:将抓到的包数据进行打印

#include 
#include 
#include 
#define HAVE_REMOTE
int main() {
pcap_if_t * allDevs;
pcap_if_t * dev;
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allDevs, errbuf) > 0) {
printf("pcap_findallDevs_ex failed\n");
}

int i = 0;
//找到连接到internet的网络设备,根据自己电脑的环境自行更改i的终值
/*windows下,要使用descroption近似为
  Network adapter 'Realtek PCIe GBE Family Controller' on local host
的网络设备 */
for (dev = allDevs, i = 0; i< 4; dev = dev->next, i++);

pcap_t * handler;
if (NULL == (handler = pcap_open(dev->name, 65535, PCAP_OPENFLAG_PROMISCUOUS, 3000, NULL, errbuf))) {
//设置接受的包大小为65535,即可以接受所有大小的包
printf("err in pcap_open : %s", errbuf);
}

pcap_pkthdr *pkt_header;
const u_char *pkt_data;
for (int j = 0; j < 5; j++) {
printf("%d --------\n", j);
if (1 == pcap_next_ex(handler, &pkt_header, &pkt_data)) {
for (int k = 0; k < 66; k++) {//输出每个包的前66个byte数据
if (k % 15 == 0 && k != 0)//输出美观
printf("\n");
printf("%02x ", *(pkt_data + k));
}
}
printf("\n");
}

getchar();

}

结果截图

winpcap 快速入门 实现抓包&&发包_第4张图片

发包演示

根据网络协议分层,数据包的格式为“|ethernet|ip|tcp/udp|http|”

具体的网络数据包,博主不打算讲,毕竟是winpcap快速入门,可能后续会推出网络数据包解析的博文

此处的数据包 packet 为博主从wireshare上复制的一个tcp syn的包,发送成功,则wireshark会接到数据大致相同的tcp synack包。如果要在自己的电脑上实现发包,需要自己使用wireshark抓取一个简单的包,复制其中的数据,填充至以下代码中的 packet变量中,然后进行发包测试

#include 
#include 
#include 
#define HAVE_REMOTE
int main() {
    pcap_if_t * allDevs;
    pcap_if_t * dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allDevs, errbuf) > 0) {
        printf("pcap_findallDevs_ex failed\n");
    }
    for (dev = allDevs; dev->next != NULL; dev = dev->next) {
        printf("----------------------------\n");
        printf("name %s\n", dev->name);
        printf("description :%s\n", dev->description);
    }
    int i = 0;
    //找到连接到internet的网络设备
    for (dev = allDevs, i = 0; i< 4; dev = dev->next, i++);

    pcap_t * handler;
    if (NULL == (handler = pcap_open(dev->name, 65535, PCAP_OPENFLAG_PROMISCUOUS, 3000, NULL, errbuf))) {
        printf("err in pcap_open : %s", errbuf);
    }

    unsigned char packet[] = { 0x14,0x14,0x4b,0x80,0x40,0x81,0x54,0xee,   0x75,0x5e,0x6f,0xa8,0x08,0x00,
        0x45,0x00, 0x00,0x34,0x77,0x44,0x40,0x00,  0x80,0x06,0x76,0xaf,0x0a,0x0a,0x2d,0xe9, 0x6f,0x0d,0x65,0xd0,
        0xc3,0x67,0x00,0x50,0xaf,0xae,0x8c,0x23,0x00,0x00,0x00,0x00,0x80,0x02,0x20,0x00,0x42,0xb6,0x00,0x00,0x02,0x04,0x05,0xb4,0x01,0x03,0x03,0x08,0x01,0x01,0x04,0x02 };

    if (1 != pcap_sendpacket(handler, packet, sizeof(packet))) {
        printf("pcap_sendpacket failed");
    }
    getchar();

}

结果截图

winpcap 快速入门 实现抓包&&发包_第5张图片

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