winpcap/npcap 提高抓包效率 发UDP包失败

最近使用winpcap在win7下编写网络抓包程序,记录一下。

winpcap是比较老的网络抓包库,在win7和win10上依赖都不是很好,看网上有针对的win10版本的winpcap安装包,这里分享了win10下的winpcap安装包和编译好的库以及winpcap的源程序,连接如下win10pcap安装包
关于win10下重新编译wpcap可参考另外一篇,主要记录了遇到的问题win7编译wpcap

言归正传,本文目的是为了记录下如何提高winpcap的抓包效率,先描述下问题。
问题描述:在PC端使用winpcap编写抓UDP包程序,千兆网卡,另一端是FPGA编写的数据发送端,带宽可达到800M/s,安装官方给的用例实现,存在以下问题。

  • 数据发送失败
  • 丢包非常严重

1、数据发送失败
使用winpcap编写的发送UDP数据的功能,在本地使用wireshark可以抓到包,但在另一端无法收到,wireshark也抓不到,分析的原因是数据包没有送出网卡,无论调用pcap_sendpacket函数还是pcap_sendqueue_transmit都发送不成功,最终将winpcap替换为Npcap,发送数据成功。有次看来还是winpcap的驱动在win7或者win10上依然存在bug。关于Npcap的详细信息可以查看官网Npcap,其实就是优化后的winpcap。
关于组UDP包的代码

//以太网数据头结构如下
#define ETHER_ADDR_LEN 6
typedef struct ether_header{
	u_char ether_dhost[ETHER_ADDR_LEN];
	u_char ether_shost[ETHER_ADDR_LEN];
	u_short ether_type;	//如果上一层为IP协议。则ether_type的值就是0x0800
}ether_header;
/* 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{
	unsigned   char		ihl : 4;				//ip   header   length    
	unsign
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WinPcapWindows平台下的网络封捕获库,可以用来取网络数据并进行分析处理,提供了对括IP、TCP、UDP、ICMP等协议的支持,同时还支持ARP、RARP等协议的取和解析。 在使用WinPcap进行ARP抓包解析时,需要先安装WinPcap库,并在代码中引入头文件pcap.h。接下来,可以使用pcap_open_live函数打开一个网络接口,并设置过滤规则进行抓包。在抓包的过程中,可以使用pcap_next_ex函数读取每一个数据,并对其进行解析,获取ARP协议头部信息。 以下是一个简单的WinPcap编程实现ARP抓包解析的示例代码: ```c++ #include <stdio.h> #include <pcap.h> #include <arpa/inet.h> #include <netinet/in.h> #include <net/ethernet.h> #include <netinet/if_ether.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <netinet/ip_icmp.h> void arp_packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); int main(int argc, char *argv[]) { char *dev, errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; struct bpf_program fp; bpf_u_int32 mask; bpf_u_int32 net; // 获取第一个网络接口 dev = pcap_lookupdev(errbuf); if (dev == NULL) { printf("pcap_lookupdev failed: %s\n", errbuf); return 1; } // 获取网络接口的IP地址和子网掩码 if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { printf("pcap_lookupnet failed: %s\n", errbuf); return 1; } // 打开网络接口 handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { printf("pcap_open_live failed: %s\n", errbuf); return 1; } // 设置过滤规则,只取ARP数据 if (pcap_compile(handle, &fp, "arp", 0, net) == -1) { printf("pcap_compile failed: %s\n", pcap_geterr(handle)); return 1; } if (pcap_setfilter(handle, &fp) == -1) { printf("pcap_setfilter failed: %s\n", pcap_geterr(handle)); return 1; } // 开始循环抓包,直到用户中断 pcap_loop(handle, -1, arp_packet_handler, NULL); // 关闭网络接口 pcap_close(handle); return 0; } void arp_packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { struct ether_header *eth_header; struct ether_arp *arp_header; char *src_mac, *dst_mac, *src_ip, *dst_ip; // 解析以太网头部 eth_header = (struct ether_header *) packet; src_mac = ether_ntoa((struct ether_addr *) eth_header->ether_shost); dst_mac = ether_ntoa((struct ether_addr *) eth_header->ether_dhost); // 解析ARP协议头部 arp_header = (struct ether_arp *) (packet + sizeof(struct ether_header)); src_ip = inet_ntoa(*(struct in_addr *) &arp_header->arp_spa); dst_ip = inet_ntoa(*(struct in_addr *) &arp_header->arp_tpa); // 打印ARP数据信息 printf("ARP packet:\n"); printf("\tSource MAC: %s\n", src_mac); printf("\tDestination MAC: %s\n", dst_mac); printf("\tSource IP: %s\n", src_ip); printf("\tDestination IP: %s\n", dst_ip); } ``` 在以上代码中,先使用pcap_lookupdev函数获取第一个网络接口,并使用pcap_lookupnet函数获取该接口的IP地址和子网掩码。然后,使用pcap_open_live函数打开该接口,并使用pcap_compile和pcap_setfilter函数设置过滤规则,只取ARP数据。 在抓包的过程中,使用pcap_loop函数循环处理每一个数据,并调用arp_packet_handler函数进行解析和处理。在arp_packet_handler函数中,首先解析以太网头部和ARP协议头部,然后打印出这些信息。 需要注意的是,在解析ARP协议头部时,需要将ARP协议头部的地址转换为字符串形式,可以使用inet_ntoa函数将IP地址转换为字符串,使用ether_ntoa函数将MAC地址转换为字符串。 以上是一个简单的WinPcap编程实现ARP抓包解析的示例代码,可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值