{ }
if((adhandle=pcap_open_live(d->name,1000,1,300,errbuf))==NULL) { }
if(pcap_datalink(adhandle)==DLT_EN10MB&&d->addresses!=NULL)
break;
cout<<\pcap_freealldevs(alldevs); //释放设备列表 return;
//以混杂模式打开网卡,以接受所有的帧
? 编译过滤器并设置过滤器,只捕获ARP数据包
char packet_filter[]=”ether proto \\\\arp”; //过滤,选择arp协议 if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0) { cout<<\ pcap_freealldevs(alldevs); return; }
//设置过滤器
if(pcap_setfilter(adhandle,&fcode)<0) { cout<<\ pcap_freealldevs(alldevs); return; }
? 循环捕获ARP包,并进行解析
while((result=pcap_next_ex(adhandle,&header,&pkt_data))>=0) {
输出ARP数据包的各个域的内容到文件和屏幕上 } ?
源程序
#include
#pragma comment(lib,\用到ntobs()
//等同于点击\打开object/library module编辑框后加入文件 #pragma comment(lib,\
#include \此头文件没有包含在VC中,需要另外加入 #include
#include
//注意到接收的数据包头中代表类型,数据长度的字段采用的是big-endian //所以对于2B/4B的数据要用ntohs()转换为本机形式 //ARP包结构 struct arppkt{ };
void packet_handler(const pcap_pkthdr *header,const u_char *pkt_data,ostream& out); void main(int argc,char *argv[ ]) {
if(argc!=2) { }
pcap_if_t *alldevs; pcap_if_t *d; pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE]; u_int netmask;
char packet_filter[]=\struct bpf_program fcode; struct pcap_pkthdr *header; const u_char *pkt_data;
if(pcap_findalldevs(&alldevs,errbuf)==-1) { }
for(d=alldevs;d;d=d->next)
cout<<\return;
cout<<\cout<<\_getch(); return;
unsigned short hdtyp; //硬件类型.值0001 unsigned short protyp; unsigned char hdsize; unsigned char prosize; unsigned short op; u_char smac[6]; u_char sip[4]; u_char dmac[6]; u_char dip[4];
{
{ }
if((adhandle=pcap_open_live(d->name,1000,1,300,errbuf))==NULL) { }
if(pcap_datalink(adhandle)==DLT_EN10MB&&d->addressess!=NULL)
break;
cout<<\pcap_freealldevs(alldevs); return;
if(d==NULL)
cout<<\ return; }
//获得子网掩码
netmask=((sockaddr_in *)(d->netmask))->sin_addr.s_un.s_addr; //编译过滤器,只捕获ARP包
if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0)
{ cout<<\ pcap_freealldevs(alldevs); return; }
//设置过滤器
if(pcap_setfilter(ashandle,&fcode)<0) { cout<<\ pcap_freealldevs(alldevs); return; }
cout<<\//显示提示信息及每项含义
ofstream fout(argv[1],ios::app); //日志记录文件 //为了查看日志时的方便,其中加入了日期记录 time_t t; time(&t);
fout.seekp(0,ios::end); if(fout.tellp()!=0) fout< fout<<\cout< <<\//释放设备列表 pcap_freealldevs(alldevs); int result; while((result=pcap_next_ex(adhandle,&header,&pkt_data))>=0) { if(result==0) continue; packer_handler(header,pkt_data,cout); packet_handler(header,pkt_data,fout); } } void packet_handler(const pcap_pkthdr *header,const u_char *pkt_data,ostream& out) { arpkt* arph = (arppkt *)(pkt_data +14); for(int i=0;i<3;i++) out< out< out< out.unsetf(ios::hex|ios::uppercase); for(i=0;i<3;i++) out< out.unsetf(ios::left); //输出目的MAC地址 out.fill('0'); out.setf(ios::uppercase); for(i=0;i<5;i++) out< out.unsetf(ios::hex|ios::uppercase); out< ltime=localtime(&header->ts.tv_sec); out.fill('0'); out< 五、相关扩展 本课程设计还可以在Linux环境下用rawsocket完成。 算法和代码提示: 1) 调用socket()打开协议簇为PF_PACKET的原始套接字,这样我们就可以收到数据 链路帧: int fd = socket(PF_PACKET,SOCK_RAM,htons(ETH_P_ALL)); 2) 对打开的套接字调用ioct1(),将网卡设置为混杂模式,这样我们就可以接受到局 域网中所有的包(包括目的地址不是本机的帧): struct ifreq req; memset (&req,0,sizeof(req)); strncpy(req.ifr_name,”eth0”,strlen(“eth0”)+1); ioctl(fd,SIOCGIFFLAS,&req); req.ifr_flags|=IFF_PROMISC; //设置为混杂模式 icotl(fd, SIOCGIFFLAGS,&req); 3) 利用recvfrom()接收包: recvform(fd,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&from_len); 4) 接收到包后,判断是否为ARP包,若是ARP包则进行处理,否则丢弃。 If( (ntohs(eth_header->ether_type)==0x0806) &&(ntohs(arp_header->ar_hrd)==0x0001) &&(ntohs(arp_header->ar_pro)==0x0800) &&(arp_header->ar_hln==0x06) &&(arp_header->ar_pln==0x04) &&( (ntohs(arp_header->ar_op)==0x01)|| (ntohs(arp_header->ar_op)==0x02))) { 对ARP数据包进行分析并打印 } 5) 算法在3、4步之间进行循环,直到强行退出为止。 六、心得体会 本次课程设计,完成了在xp环境下的解析ARP数据包。 在具体实现获取网络中的ARP数据包解析数据包的内容,并将其写入日志文件的过程中,是我更加清楚物理地址、IP地址的关联,源地址与目的地址的关系,以及二者对数据类型的格式要求。最重要的是通过这次的实际训练让我对ARP协议更加理解。 本次课程设计查阅了大量的案例,学到了很多知识,使我对计算机网络有了更深入的了解。我觉得这次课程设计我觉得收获挺大的。之前的学习仅限于书本,网络的很多东西都只知道其然而不知道其所以然。 课程设计是培养我们综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对我们实际工作能力的具体训练和考察过程。随着科学技术发展的日新月异,网络已经成为当今计算机发展中空前活跃的领域,在生活中可以说是无处不在,因此作为二十一世纪的计算机专业的大学生来说掌握网络组网技术是十分重要的。 七、参考资料 1. 谢希人著. 计算机网络(第四版)大连理工大学出版社2003 2. 宋凯等著. 计算机网络. 北京:清华大学出版社 2010 3. 吴功宜等著. 计算机网络课程设计. 北京:机械工业出版社2005.9 4. 李爱华等著. 面向对象程序设计(C++语言). 北京:清华大学出版社2010