C语言学习历程–小项目篇–基于winpcap的UDP数据发送
开发环境介绍
1、操作系统:windows10(基于x64处理器)、IDE:vs 2019(微软官网个人免费版)、winpcap安装包及开发包
2、调试工具:wireshark、netassist
开发环境准备
1、关于winpcap的使用
首先,关于操作系统和vs 2019不必多说。
然后,开始有关winpcap的说明:
① winpcap安装包
去官网:http://www.winpcap.org (建议谷歌浏览器,翻译成中文挺准确的)
下载:Windows版本4.1.3 安装程序(最新的),点击绿色字即可下载
安装即可。
②下载winpcap pack
官网主页-发展历程-下载WinPcap 4.1.2 开发人员包;解压后放在一个你中意的地方
2、将开发包配置到vs 2019
①资源管理栏选定新建的项目-点击工具栏的项目-点击最下方的属性
②点击VC++目录-编辑包含目录-添加开发人员包的include的路径,如:D:\WpdPack\Include;再编辑库目录--添加lib路径,如:D:\WpdPack\Lib;
③点击C/C++-预处理器-预处理器定义-编辑添加:WPCAP、_XKEYCHECH_H、HAVE_REMOTE
④点击链接器-输入-附加依赖项-编辑添加packet.lib、wpcap.lib、ws2_32.lib
应用,确定即可。
3、wireshark没什么好说的,netassist就是一个UDP调试工具
开始工作
新建C文件,将代码拷入:
#define WIN32
#include"my.h"
void udp(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;
}
/* 打开输出设备 */
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;
}
/* 设置MAC的目的地址 */
//packet[1] = 0xff;
//packet[2] = 0xff;
//packet[3] = 0xff;
//packet[4] = 0xff;
//packet[5] = 0xff;
/* 设置MAC源地址*/
packet[6] = 0;
packet[7] = 0;
packet[8] = 0;
packet[9] = 0;
packet[10] = 0;
packet[11] = 0;
/* 填充类型 */
packet[12] = 8; packet[13] = 0;//上层协议类型
//IP头
packet[14] = 0x45;//IPv4 长度5
packet[15] = 0; //服务类型
packet[16] = 0; packet[17] = 0x56; //IP报的长度
packet[18] = 0x30; packet[19] = 0x18; //数据报的标识
packet[20] = 0; packet[21] = 0;
packet[22] = 0x80; //生存时间
packet[23] = 17; //UDP协议,这里可以百度查表
packet[24] = 0x83; packet[25] = 0x28;//校验和
packet[26] = 192; packet[27] = 168; packet[28] = 3; packet[29] = 3;//源IP
packet[30] = 192; packet[31] = 168; packet[32] = 3; packet[33] = 3;//目的IP
//UDP头
packet[34] = 0xD9; packet[35] = 0x03; //源端口号
packet[36] = 0xD9; packet[37] = 0x04; //目的端口号
packet[38] = 0; packet[39] = 0x42; //长度
//packet[40] = 0xD2; packet[41] = 0xD1; //校验和
packet[40] = 0xC6; packet[41] = 0x0A; //校验和
for (i = 42; i <100; i++) //此为数据内容
{
packet[i] = 0;
}
/* 发送数据包 */
if (pcap_sendpacket(fp, packet, 100 /* size */) != 0)
{
fprintf(stderr, "\nError sending the packet: \n");//, pcap_geterr(fp
return;
}
}
说明:注意将函数udp名字改为main;两个MAC地址根据需要填,我那个是错的不可正确运行;如果不会计算校验和可利用wireshark;其设置如下:编辑–首选项–protocols–IPv4或者UDP–勾选对应项;当你发出的UDP包被抓住时,校验和如果是错的就会变红,并在后面提示你正确的应该是什么,回去改一下你的程序就好了。筛选器设置:eth.addr eq 你的目的MAC地址 and udp.port==发送数据的端口。
使用方法:Debug运行,在项目目录里找到相应的.exe文件,copy路径。在命令提示符中运行,如:D:\vs2019project\Project1\Debug\Project1.exe
根据打印出的提示选择你的网卡设备,再次运行:D:\vs2019project\Project1\Debug\Project1.exe rpcap://\Device\NPF_{***********************}
大概就这样。
结果
在UDP调试工具上接收到你自己组的包。
参考资料
TCP-IP详解卷一:协议