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

来源:互联网 发布:qq群刷花软件 编辑:程序博客网 时间:2024/06/04 23:14

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

定义需要的变量

pcap_if_t * alldevs;pcap_if_t *d;pcap_t * adhandle;//定义包捕捉句柄char errbuf[PCAP_ERRBUF_SIZE];//错误缓冲最小为256pcap_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扫描了

0 0
原创粉丝点击