WinPcap实战(二)——接收ARP包
来源:互联网 发布:哪里有招聘网络写手 编辑:程序博客网 时间:2024/05/16 05:07
ARP帧结构
ARP帧结构(28B):硬件类型(2B,Ethernet:0x1)——上层协议类型(2B,IP:0x0800)——硬件地址长度(1B,0x6)——IP地址长度(1B,0x4)——操作(2B,请求: 0x1; 应答: 0x2)——源MAC地址(6B)——源IP地址(6B)——目的MAC地址(6B)——目的IP地址(6B)
依据ARP帧结构定义结构体
struct ArpHeader{ unsigned short hdtyp; //硬件类型 unsigned short protyp; //协议类型 unsigned char hdsize; //硬件地址长度 unsigned char prosize; //协议地址长度 unsigned short op; //操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。 u_char smac[6]; //源MAC地址 u_char sip[4]; //源IP地址 u_char dmac[6]; //目的MAC地址 u_char dip[4]; //目的IP地址};
源代码
#include "stdafx.h"#include "pcap.h"struct ArpHeader{ unsigned short hdtyp; //硬件类型 unsigned short protyp; //协议类型 unsigned char hdsize; //硬件地址长度 unsigned char prosize; //协议地址长度 unsigned short op; //操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。 u_char smac[6]; //源MAC地址 u_char sip[4]; //源IP地址 u_char dmac[6]; //目的MAC地址 u_char dip[4]; //目的IP地址};int main(){ pcap_if_t *alldevs; //所有网络适配器 pcap_if_t *d; //选中的网络适配器 int inum; //选择网络适配器 int i = 0; //for循环变量 pcap_t *adhandle; //打开网络适配器,捕捉实例,是pcap_open返回的对象 char errbuf[PCAP_ERRBUF_SIZE]; //错误缓冲区,大小为256 int res; //抓包函数pcap_next_ex返回值,1-成功、0:获取报文超时、-1:发生错误、-2: 获取到离线记录文件的最后一个报文 u_int netmask; //子网掩码 //ether proto protocol:如果数据包属于某些以太协议(protocol)类型, 则与此对应的条件表达式为真,协议字段可以是ARP char packet_filter[] = "ether proto \\arp"; //要抓取的包的类型,这里是抓取ARP包; struct bpf_program fcode; //pcap_compile所调用的结构体 struct tm *ltime; //和时间处理有关的变量 char timestr[16]; //和时间处理有关的变量 time_t local_tv_sec; //和时间处理有关的变量 struct pcap_pkthdr *header; //接收到的数据包的头部 const u_char *pkt_data; //接收到的数据包的内容 /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf); exit(1); } /* 打印列表 */ for (d = alldevs; d; d = d->next) { printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } if (i == 0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); return -1; } printf("Enter the interface number (1-%d):", i); scanf("%d", &inum); if (inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; } /* 跳转到已选中的适配器 */ for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++); /* 打开设备 */ if ((adhandle = pcap_open(d->name, // 设备名 65536, // 要捕捉的数据包的部分 // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 1000, // 读取超时时间 NULL, // 远程机器验证 errbuf // 错误缓冲池 )) == NULL) { fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* 释放设列表 */ pcap_freealldevs(alldevs); return -1; } /* 检查数据链路层,为了简单,我们只考虑以太网 */ if (pcap_datalink(adhandle) != DLT_EN10MB) { fprintf(stderr, "\nThis program works only on Ethernet networks.\n"); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; } if (d->addresses != NULL) /* 获得接口第一个地址的掩码 */ netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; else /* 如果接口没有地址,那么我们假设一个C类的掩码 */ netmask = 0xffffff; //编译过滤器 if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0) { fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n"); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; } //设置过滤器 if (pcap_setfilter(adhandle, &fcode) < 0) { fprintf(stderr, "\nError setting the filter.\n"); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; } printf("\nlistening on %s...\n", d->description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /*以上代码在WinPcap开发文档中都可以找到,解析ARP包的代码则要自己编写*/ /* 获取数据包 */ while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) { if (res == 0) /* 超时时间到 */ continue; //解析ARP包 ArpHeader* arph = (ArpHeader *)(pkt_data + 14); //类型 printf("报文类型:"); if (arph->op == 256) printf("请求报文\t"); else printf("应答报文\t"); //长度 printf("长度(B):%d\t", header->len); //时间 /* 将时间戳转换成可识别的格式 */ local_tv_sec = header->ts.tv_sec; ltime = localtime(&local_tv_sec); strftime(timestr, sizeof timestr, "%H:%M:%S", ltime); printf("时间:%s\n", timestr); //输出源IP printf("源IP:"); for (i = 0; i < 3; i++) { printf("%d.", arph->sip[i]); } printf("%d\t", arph->sip[3]); //输出目的IP printf("目的IP:"); for (i = 0; i < 3; i++) { printf("%d.", arph->dip[i]); } printf("%d\n", arph->dip[3]); //输出源MAC printf("源MAC:"); for (i = 0; i < 5; i++) { printf("%02x-", arph->smac[i]); } printf("%02x\t", arph->smac[5]); //输出目的MAC printf("目的MAC:"); for (i = 0; i < 5; i++) { printf("%02x-", *(pkt_data + i)); } printf("%02x\n", *(pkt_data + 5)); printf("----------------------------我是一只分隔线-----------------------------\n"); } if (res == -1) { //接收ARP包出错 printf("Error reading the packets: %s\n", pcap_geterr(adhandle)); return -1; } return 0;}
运行结果
程序在VS2015企业版里面运行无误,需要提前配置好WinPcap的编程环境
选择第三个网卡,开始监听网络
等待几分钟后,抓取到ARP包
传送门
发送ARP包:
http://blog.csdn.net/u013539342/article/details/48523933#t4
参考网址:http://blog.csdn.net/cqcre/article/details/40213911
WinPcap编程配置:http://www.findspace.name/easycoding/871
VS下This function or variable may be unsafe解决办法:
http://jingyan.baidu.com/article/49711c616b8a1ffa441b7cdc.html
1 0
- WinPcap实战(二)——接收ARP包
- WinPcap实战(一)——发送ARP包
- WinPcap发送接收裸包(二)
- 【WinPcap】——ARP欺骗
- 【WinPcap】自制抓包+分析+ARP攻击(二)
- WinPcap发送接收裸包(一)
- Windows下使用winpcap-2.2arp探测局域网内主机(接收并解析arp数据包)
- 接收ARP包
- QT---基于WinPcap的局域网络管理工具(主机扫描、包过滤、ARP攻击、端口扫描)
- 基于Winpcap的ARP攻击(Winpcap入门)
- 【WinPcap】自制抓包+分析+ARP攻击(一)
- 【WinPcap】自制抓包+分析+ARP攻击(三)
- 基于MFC+WinpCap构造ARP请求发送包
- ARP欺骗源码(基于WinPcap实现)
- ARP欺骗源代码(基于WinPcap实现)
- WinPcap权威指南(三):ARP协议
- Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信
- Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信
- MySQL获取表格信息
- 【NTT】 HDOJ 5279 YJC plays Minecraft
- GIT安装
- Altium Designer 封装 库文件导入 基础库设计 PCB设计 原理图设计
- iOS9 HTTP 不能正常使用的解决办法
- WinPcap实战(二)——接收ARP包
- JSON对象与字符串之间的转换
- 千万级的mysql数据库与优化方法
- CentOS7安装iptables防火墙
- 欢迎使用CSDN-markdown编辑器
- jquerymobile基础属性总结
- 程序员才能看懂的笑话
- UICollectionView
- http://www.cnblogs.com/king-77024128/articles/2666230.html