本篇博客主要记录如何使用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地址,就能进行发送了。