WinPcap网络编程入门——1. 获取设备列表

WinPcap网络编程入门——1. 获取设备列表

系列教程章节直达:
Winpcap网络编程入门——1. 获取设备列表;


上节中我们简单介绍了 WinPcap 的相关资料,配置好了开发环境,现在就让我们正式开始网络编程开发吧!

1. 基本开发流程

WinPcap 开发网络应用程序的大致流程:首先获取主机安装的网络设备列表,然后选择并激活某个网络设备,封装或过滤数据包,发送或解析数据包,本节我们将以解析数据包为例来逐层深入,基本开发流程如图:
基本开发流程

2. 使用 pcap_findalldevs_ex() 检索设备列表

pcap_findalldevs_ex() 是 WinPcap 提供的用以查找主机网络适配器功能的函数,它是 pcap_findalldevs() 函数的升级版,现在基本都选择使用 ex 版本,它不仅能查找本地的设备,还能查找远程的设备,关于此函数的定义如下:

// 函数原型:
int pcap_findalldevs_ex(char* source,  struct pcap_rmtauth *auth,  pcap_if_t** alldevs,   char* errbuf);
/* 参数说明
* source:指定是本地适配器还是远程适配器
* auth:身份验证信息,可以为NULL
* alldevs:存放获取的适配器数据,如果查找失败,其值为NULL
* errbuf:存放查找失败的相关错误信息
*/
// 返回值:成功返回0,失败返回-1

看了函数定义之后是不是感觉这个很简单呢,只需要调用函数然后就可以获取到设备信息,是的!就是这么简单,当然,还有一点需要注意:
可以看到参数 alldevs的类型是 pcap_if_t类型的二级指针,这里需要说明,pcap_findalldevs_ex()函数在获取到设备信息之后会将详细信息存储在一个结构体pcap_if_t中,(注意,单个设备时一个结构体,多个设备就是多个结构体的链接,即链表,这是个非常基本的概念,不懂的话查一下链表的相关知识)它的定义如下:

struct pcap_if_t
{
	struct pcap_if_t *next;		// 如果不为空,就指向下一个元素
	char *name;					// 设备名称
	char *description;			// 设备描述
	struct pcap_addr *addresses;// 接口地址列表
	bpf_u_int32 flags;			// 标志位,标志是否 loopback 设备
}

从中可以看出,我们需要建立一个pcap_if_t类型的指针来存储调用函数获取到的设备信息,然后直接通过指针就可以访问指定设备的相关信息,由此可以写出伪代码如下:

pcap_if_t *alldevs;	// 指向获取到设备列表的第一个设备,即链表头
pcap_findalldevs_ex(***, ***, alldevs, ***);	// 调用函数来查找设备
printf("%s\n", alldevs->name);			// 输出第一个设备的名称
printf("%s\n", alldevs->description);	// 输出第一个设备的描述信息
if(alldevs 链表中有多个设备)
	alldevs = alldevs->next;	// 获取下一个设备
	// 重复上面的输出代码,输出此设备的相关信息

同样,从pcap_if_t结构体的定义中可以看到,在结构体里面又定义了一个名为pcap_addr的结构体,用来存储接口地址列表,pcap_addr的定义如下:

struct pcap_addr
{
	struct pcap_addr *next;			// 如果不为空,则指向下一个元素
	struct sockaddr *addr;			// 接口IP地址
	struct sockaddr *netmask;		// 接口网络掩码
	struct sockaddr *broadaddr;		// 接口广播地址
	struct sockaddr *dstaddr;		// 接口 P2P 目的地址
}

这个结构体的列表中包含:

  • 该接口的地址列表
  • 网络掩码的列表(每个网络掩码对应地址列表中的一项)
  • 广播地址的列表(每个广播地址对应地址列表中的一项)
  • 目标地址的列表(每个目标地址对应地址列表中的一项)

3. 实现获取设备列表

经过了以上的分析,我们大概知道了pcap_findalldevs_ex()函数的基本用法以及对于信息的存储机制,下面我们就来实现一下这个程序吧,具体的解释都在代码的注释里,要详细阅读代码哟 ~

#define WIN32  						// 在vs中编程时,必须要加这一行,否则vs不会自动识别平台
#include <stdio.h>
#include <pcap.h>
#pragma comment(lib, "wpcap.lib")

main()
{
	pcap_if_t* alldevs, * d;		// alldevs 存储查找到的设备链表的链表头,d 为遍历 alldevs 链表时的游标
	int i = 0;						// 设备序号,在后面的循环中会用到
	char errbuf[PCAP_ERRBUF_SIZE];	// 如果查找失败,相关错误信息会存储到这个里面
	// 从本地计算机检索可用设备列表
	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
	{
		// 查找失败,输出失败信息
		fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
		exit(1);		// 如果查找失败,程序直接终止
	}
	// 如果查找成功,alldevs 中已经存储了设备信息链表头的地址,直接遍历输出即可
	// 输出设备列表
	for (d = alldevs; d != NULL; d = d->next)
	{
		printf("%d.%s", ++i, d->name);					// 输出设备名称,设备序号依次加1
		if (d->description)
		{
			printf("(%s)\n", d->description);			// 输出设备描述信息(如果有的话)
		}
		else {
			printf("(No description available)\n");
		}
	}
	if (i == 0)		// 如果设备序号还是0的话,说明没有查找到设备
	{
		printf("\nNo interfaces found! Make sure Winpcap is installed.\n");
		return;
	}
	// 释放设备
	pcap_freealldevs(alldevs);
}

完整代码就是这样,如果有其他问题欢迎下方评论区相见。


系列教程章节直达:
Winpcap网络编程入门——1. 获取设备列表;

  • 12
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值