Winpcap实现arp协议的发送和解析
计算机网络课程设计中,老师要求用winpcap实现arp协议的发送和解析。我从0开始一点点琢磨最终实现了需要的功能。我中间踩了很多很多的坑,因此在此记录一下,希望也能够帮助更多的人。
环境的配置、头文件和宏定义
我的IDE是vs2019,熟悉的人都知道微软有“不合群”的尿性,它的产品总要与别人不一样,网上的代码粘到vs里就是不能运行。配置环境其实跟网上找的没什么区别,但是需要注意的是需要加上很多额外头文件,因为网上其他关于实现arp的文章中本机mac地址是需要手动输入的,而我是直接通过调用一些函数和API获取对应网卡的mac地址。
winpcap下载地址如下:https://www.winpcap.org/
我的头文件和宏定义如下:
#define WIN32
#define _CRT_SECURE_NO_WARNINGS
#include<pcap.h>
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Packet32.h>
#include<ntddndis.h>
#include<time.h>
当然要用到这里的一些头文件你需要按照网上的教程配置好目录。
网络适配器的获取
pcap_if_t* alldevs, * d; //用于存储网络设备
//pcap_if是一个结构体,包含了网络适配器的全部信息
int i = 0;//网络设备号数目
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs:%s\n", errbuf);
exit(1);
}
for (d = alldevs; d; d = d->next) {
//alldevs是一个链表!链表!链表!网卡信息的链表,每个网卡信息的结构体就是链表的一个节点
printf("%d. %s", ++i, d->name);
if (d->description)
printf("(%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0) {
printf("\n找不到指定接口.\n");
}
int nnnnn = i;
choose:
i = nnnnn;
printf("\n选择适配器号 (1-%d):", i);
int inum;
pcap_t* adhandle;
unsigned char* packet;
scanf("%d", &inum);//直接选择4号,4号是我的WiFi网卡
if (inum < 1 || inum > i) {
printf("超出范围.\n");
goto choose;
}
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
pcap_addr_t* a = d->addresses;
这一部分就是获取网卡信息。第一次接触的同学可能不理解输出的到底是什么。我给截一下图:

在我运行的结果中出现了五个网卡。没错,每台电脑都不止一个网卡,有有线网卡、WiFi网卡、蓝牙设备也算网卡,甚至如果你有Ubuntu虚拟机的话虚拟机也有网卡! 那么我们肯定需要知道到底哪个是我的WiFi网卡呢?毕竟我们发送arp肯定得用WiFi网卡。至少目前我觉得唯一的方法就是得知每个网卡的IP地址,然后看看哪个是我电脑的WiFi网卡。 然而现实是有些网卡没有IP地址!!!也就是不支持ipv4服务,不信的话你到命令行输入ipconfig/all,展现你电脑上所有的网卡,你会发现确实有网卡没有IP地址这个属性。此时你可能发现ipconfig展示出来的网卡数可能比你在程序里输出的网卡多。别问我,我也不知道为什么。。。
IP地址和mac地址的获取
unsigned int ip = 0;
unsigned char mac[6];
for (a = d->addresses; a; a = a->next) {
switch (a->addr->sa_family) {
case AF_INET: {
if (a->addr) {
ip = (((struct sockaddr_in*)a->addr)->sin_addr.s_addr);//取得ip
GetAdapterMacAddr(d->name, mac);//取得mac
}
break;
}
default: break;
}
}//获取对应网卡的ipv4的ip地址
if (ip == 0) {
printf("该网卡没有ipv4,请重新选择!\n");
goto choose;
}
a是什么呢?a是d->addresses,d是网卡信息,也就是说a是网卡的地址信息。a含有ip地址,子网掩码、p2p地址等若干地址,但就是没有mac地址!!我看起来像是a仅仅含有网络层地址,没有链路层的。这一部分其实非常复杂,我也很不理解。只知道addr的sa_family为AF_INTE的时候才表示这个是IP地址,不是子网掩码什么的,然后ip就可以等于后面一大串了。。后面一大串是啥我也不是很理解,但是一层一层的结构体点进去,会隐隐约约感觉这就是IP地址。。。
ip我定义的是一个无符号整

本文详述了使用Winpcap在VS2019环境下实现ARP协议的全过程,包括环境配置、网络适配器获取、IP及MAC地址提取、ARP包构建与解析等关键步骤,特别强调了IP地址正反转换与MAC地址获取的难点。
最低0.47元/天 解锁文章
1777

被折叠的 条评论
为什么被折叠?



