Windows下使用winpcap-2.2arp探测局域网内主机(接收并解析arp数据包)

上篇文章我们成功发送了arp请求,这里我们就需要等待并看看能不能收到来自我们需探测ip的arp回复,如果收到,则该主机为活动的,因为这个等待arp返回需要等待一段时间,这里我之间写出来,实际用的时候,你们需要写成线程,并在发送arp请求之前调用。

定义需要的变量

	pcap_if_t * alldevs;
	pcap_if_t *d;
	pcap_t * adhandle;//定义包捕捉句柄
	char errbuf[PCAP_ERRBUF_SIZE];//错误缓冲最小为256
	pcap_addr_t *pAddr;
	struct bpf_program fcode;
	char packet_filter[] = "ether proto \\arp";
	int result;
	struct pcap_pkthdr * header;
	const u_char * pkt_data;
	struct in_addr temp;                                                                                                                                    <span style="white-space:pre">	</span>unsigned long netmask;         //子网掩码 
1.查找本机网卡,选择网卡,打开网卡,参考上一篇的解释,这里直接上代码

//
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
		cout << "Error in pcap_findalldevs: " << errbuf << endl;;
		 exit(1);
    }

	d = alldevs;
	if ((adhandle = pcap_open_live(d->name, 65536, 1, 1000, errbuf)) == NULL)
	{
		 /*打开失败*/
		cout << "打开失败." << d->name << "不被winpcap支持" << endl;
		 /* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}

2.获取子网掩码

pAddr = d->addresses;
	netmask = ((struct sockaddr_in*)pAddr->next->netmask)->sin_addr.S_un.S_addr;

3.编译过滤器,只捕获arp包

if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask)<0)
	{
		 printf("\nUnable to compile the packet filter.Check the syntax.\n");
		 pcap_freealldevs(alldevs);
		 return -1;
	}
4.设置过滤器

if (pcap_setfilter(adhandle, &fcode)<0)
	{
		printf("\nError setting the filter.\n");
		pcap_freealldevs(alldevs);
		return -1;
	}
5接收并解析收到的包,这里演示的是怎么接收和解析里面的信息,当我们需要实现arp扫描的时候,只需要将这些信息拿来和我们的源、目的、操作类型(arp应答的option为512,实际为2,因为option占2字节,网络字节序和本机是反的,即2在本机是0x0002,但网络上传过来是高字节和低字节是反的,这就解释了,为什么我们在构造数据包的时候,超过一字节(像short)就需要htons来转换,所以传过来的是0x0200,就是512)

while ((result = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0)
	{
		//循环解析ARP数据包

		if (result == 0)//返回0表示超时
		{
			cout << "未接收到arp数据包,该IP可能不处于活动状态" << endl;
			continue;
		}
		arp_packet* arph = (arp_packet *)pkt_data;
		if (arph->arp.sour_ip==inet_addr("192.168.218.128")&&arph->arp.dest_ip==inet_addr("192.168.218.1"))
		{
			
			temp.S_un.S_addr = arph->arp.sour_ip;
			cout << "源IP:" << inet_ntoa(temp) << endl;
			temp.S_un.S_addr = arph->arp.dest_ip;
			cout << "目的IP:" << inet_ntoa(temp) << endl;


			printf_s("源MAC:%.2x-%.2x - %.2x -%.2x -%.2x -%.2x\n", arph->arp.sour_addr[0], arph->arp.sour_addr[1],
				arph->arp.sour_addr[2], arph->arp.sour_addr[3], arph->arp.sour_addr[4], arph->arp.sour_addr[5]);
			printf_s("目的MAC:%.2x-%.2x - %.2x -%.2x -%.2x -%.2x\n", arph->arp.dest_addr[0], arph->arp.dest_addr[1],
				arph->arp.dest_addr[2], arph->arp.dest_addr[3], arph->arp.dest_addr[4], arph->arp.dest_addr[5]);

			cout << "包类型:" << arph->arp.option << endl;
		}

	}

至此我们就可以实现arp扫描了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值