[网络分析] 1 获取网络适配器列表

该系列文章是依据本人平时对网络分析技术的学习,归纳总结,所做的学习笔记。如有错误或待改善之处,请留下您宝贵的意见或建议。

 

该系列文章主要介绍WinPcap的编程以及相关的源码分析,程序的编写用的是纯C语言,并且希望读者拥有良好的网络及网络协议的知识我们已经在第一篇文章中介绍了VS下的开发环境配置。前面的几节,首先我们运用WinPcap提供的几个API,进行一些简单的编程,实现几个基本的、简单的功能。

 

这一节,介绍获取网络适配器列表

 

相关函数描述:

pacp_findalldevs_ex(char *source,  struct pcap_rmtauth *auth,  pacp_if_t **alldevs,  char *errorbuf)  //返回所找到的适配器列表
pacp_freealldevs(pacp_if_t **alldevs)  //释放设备列表所占用的空间

相关结构体描述:

1.      pcap_if_t结构体

typedef struct pcap_if pcap_if_t;
struct pcap_if {
	struct pcap_if *next;
	/*如果不为NULL,则指向列表的下一个元素。如果为NULL,则为列表的末尾*/
	char *name;
	/*描述设备名称的字符串指针*/
	char *description;
	/*如果不为NULL,则指向描述设备的一个可读字符串*/
	struct pcap_addr *addresses;
	/*一个指向接口地址列表第一个元素的指针*/
	bpf_u_int32 flags;
	/*回环标记*/
};

2.      pcap_addr_t结构体

typedef pcap_addr pcap_addr_t;
struct pcap_addr {
	struct pcap_addr *next; 	//指向下一个元素的指针
	struct sockaddr *addr; 		//IP地址
	struct sockaddr *netmask; 	//子网掩码
	struct sockaddr *broadaddr; //广播地址
	struct sockaddr *dstaddr; 	//P2P目标地址
};

代码:

#define WIN32
#define HAVE_REMOTE

#include <stdio.h>
#include "pcap.h"

main()
{
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int i=0;
    char errbuf[PCAP_ERRBUF_SIZE];
    
    /* 获取本地机器设备列表 */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
        exit(1);
    }
    
    /* 打印设备列表 */
    for(d= alldevs; d != NULL; d= d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }
    
    /* 如果没有找到设备接口,确认WinPcap已安装,退出 */
    if (i == 0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return;
    }

    /* 不再需要设备列表了,释放 */
    pcap_freealldevs(alldevs);
}

注意:

1.    pcap_findalldevs_ex函数和其他函数一样,一旦发生错误,errbuf参数将写入错误信息。

2.    不是所有的操作系统都支持WinPcap提供的网络接口。因此,如果想编写一个可以移植的应用程序,就必须考虑什么情况下description为NULL。

3.    当设备使用结束后,需要调用pcap_freealldevs函数释放设备列表所占用的资源。

 

 

以下是获取已安装设备的高级信息:

#define WIN32
#define HAVE_REMOTE

#include <stdio.h>
#include "pcap.h"
#include <winsock.h>
#include <windows.h>

/* 打印给定接口的所有有效信息*/
void ifprint(pcap_if_t *d);
/*把一个数字IP地址转换为一个字符串*/
char *iptos(u_long in);

int main()
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	char errbuf[PCAP_ERRBUF_SIZE + 1];
	char source[PCAP_ERRBUF_SIZE + 1];

	/*选择要获取设备列表的源*/
	printf("Enter the device you want to list:\n"
		"rpcap://                 ==> lists interfaces in the local machine\n"
		"rpcap://hostname:port ==> lists interfaces in a remote machine\n"
		"                          (rpcapd daemon must be up and running\n"
		"                          and it must accept 'null' authentication)\n"
		"file://foldername     ==> lists all pcap files in the give folder\n\n"
		"Enter your choice: ");

	fgets(source, PCAP_ERRBUF_SIZE, stdin);
	source[PCAP_ERRBUF_SIZE] = '\0';

	/*获取接口列表*/
	if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
	{
		fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}

	/*遍历列表,打印出每个条目的信息*/
	for (d = alldevs; d; d = d->next)
	{
		ifprint(d);
	}

	/*释放接口列表*/
	pcap_freealldevs(alldevs);

	system("pause");
	return 1;
}

void ifprint(pcap_if_t *d)
{
	pcap_addr_t *a;
	char ip6str[128];

	/*打印名称(Name)*/
	printf("\tName:%s\n", d->name);

	/*打印描述(Description)*/
	if (d->description)
		printf("\tDescription: %s\n", d->description);

	/*打印环回地址(Loopback Address)*/
	printf("\tLoopback: %s\n",
		(d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no");

	/*打印IP地址(IP addresses)*/
	for (a = d->addresses; a; a = a->next)
	{
		printf("\tAddress Family: #%d\n", a->addr->sa_family);
		if (a->addr->sa_family == AF_INET)
		{
			printf("\tAddress Family Name: AF_INET\n");
			if (a->addr)
				printf("\tAddress: %s\n",
				iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
			if (a->netmask)
				printf("\tNetmask: %s\n",
				iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
			if (a->broadaddr)
				printf("\tBroadcast Address: %s\n",
				iptos(((struct sockaddr_in*)a->broadaddr)->sin_addr.s_addr));
			if (a->dstaddr)
				printf("\tDestination Address: %s\n",
				iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
		}
		else
		{
			printf("\tAddress Family Name: Unknown\n");
		}
	}
	printf("\n");
}

#define IPTOSBUFFERS	12
char *iptos(u_long in)
{
	static char output[IPTOSBUFFERS][3 * 4 + 3 + 1];
	static short which;
	u_char *p;

	p = (u_char *)∈
	which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
	_snprintf_s(output[which], sizeof(output[which]),
		sizeof(output[which]), "%d.%d.%d.%d",
		p[0], p[1], p[2], p[3]);
	return output[which];
}

函数pcap_findalldevs_ex()除了获取本地适配器信息外,还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值