本篇博客主要记录如何使用winpcap实现发送数据包的功能,这里主要用到的函数是,pcap_sendpacket(),该函数的主要声明如下:
int pcap_sendpacket(pcap_t *, const u_char *, int)
这三个参数的含义分别是发送数据包的适配器、要发送的数据和缓冲的长度。需要注意的是,缓冲直接发送至网络,不会有任何的控制和加工。这就意味着程序需要构造正确的协议头,使得数据包更有意义。该函数的返回值为0表示发送成功,-1表示发送失败。winpcap也支持使用队列形式转发数据,这样,我们就能一次性发送多个数据包了。根据官方文档,我们可以看到这样一中结构体,pcap_send_queue,该结构体定义如下:
<pre name="code" class="cpp">#include <stdlib.h> #include <stdio.h> #define HAVE_REMOTE #include <pcap.h> int main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; u_char packet[100]; int i; /* 检查命令行参数的合法性 */ if (argc != 2) { printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]); return -1; } /* 打开输出设备 */ if ( (fp= pcap_open(argv[1], // 设备名 100, // 要捕获的部分 (只捕获前100个字节) PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 1000, // 读超时时间 NULL, // 远程机器验证 errbuf // 错误缓冲 ) ) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]); return -1; } /* 假设在以太网上,设置MAC的目的地址为 1:1:1:1:1:1 */ packet[0]=1; packet[1]=1; packet[2]=1; packet[3]=1; packet[4]=1; packet[5]=1; /* 设置MAC源地址为 2:2:2:2:2:2 */ packet[6]=2; packet[7]=2; packet[8]=2; packet[9]=2; packet[10]=2; packet[11]=2; /* 填充剩下的内容 */ for(i=12; i<100; i++) { packet[i]=i%256; } /* 发送数据包 */ if (pcap_sendpacket(fp, packet, 100 /* size */) != 0) { fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp)); return -1; } return 0; }
在这里,我们仅仅是进行最简单的数据包模拟转发功能,可以看到,我们仅仅只构造了以太网帧头,只添加了源mac地址和目的mac地址,就能进行发送了。