通信网络实验——sniffer(嗅探器)设计与兑现
通信网络实验——sniffer(嗅探器)设计与实现
编译:
在终端中键入命令$ make进行编译,生成可执行文件arpsniffer。
一.实验目的
利用WINPCAP,实现数据包的捕获与初步的数据分析。
二.实验报告
1.详细描述实验过程。
2.给出实现方案的设计,及调试中遇到的问题。
实验环境:Fedora 16 Linux , gcc 4.6.3
实验准备:安装libpcap库
实验前先下载并安装libpcap库。
在http://www.tcpdump.org/网站上下载libpcap-1.2.1.tar.gz压缩包,使用命令$ tar -zxvf libpcap-1.2.1.tar.gz进行解压。
进入解压目录$ cd libpcap-1.2.1/。
安装libpcap前,先安装bison和flex以及libnids
命令$ sudo yum install bison flex libnids
进行libpcap源码编译及安装。命令:
$./configure $make $sudo make install
实验步骤:
使用libpcap库编写代码。此处实现了一个简单的ARP协议嗅探器。该嗅探器可以实现对ARP数据包的捕获和简单分析,比如提取源主机MAC和IP地址和目的主机MAC和IP地址,数据链路层协议类型和网络层协议类型以及判断是ARP请求还是回复。
代码:
/********************************************************* * Simple ARP Sniffer * To compile: gcc arp_sniffer.c -o arpsniffer -lpcap * Run as Root * Author: DuanCong * Date: 2012/12/23 * *****************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<pcap.h> #include<unistd.h> /*ARP Header,(assuming Ethernet+IPv4)*/ #define ARP_REQUEST 1 /*ARP Request*/ #define ARP_REPLY 2 /*ARP Reply*/ typedef struct arphdr{ u_int16_t htype;/*Hardware Type*/ u_int16_t ptype;/*Protocal Type*/ u_char hlen; /*Hardware Address Length*/ u_char plen; /*Protocal Address Length*/ u_int16_t oper; /*Operation Code*/ u_char sha[6]; /*Sender Hardware Address*/ u_char spa[4]; /*Sender IP Address*/ u_char tha[6]; /*Target Hardware Address*/ u_char tpa[4]; /*Target IP Address*/ }arphdr_t; #define MAXBYTES2CAPTURE 2048 int main(int argc,char** argv) { int i=0; bpf_u_int32 netaddr=0,mask=0; /*To Store Network address and netmask*/ struct bpf_program filter; /*Place to store the BPF filter program*/ char errbuf[PCAP_ERRBUF_SIZE];/*Error buffer*/ pcap_t *descr =NULL; /*Network interface handler*/ struct pcap_pkthdr pkthdr; /*Packet infomation(timestamp,size)*/ const unsigned char *packet=NULL;/*Received raw data*/ arphdr_t *arpheader=NULL; /*Pointer to the ARP Header*/ memset(errbuf,0,PCAP_ERRBUF_SIZE); if(argc != 2) { printf("USAGE: arpsniffer <interface>\n"); exit(1); } /*Open network device for packet capture*/ descr = pcap_open_live(argv[1],MAXBYTES2CAPTURE,0,512,errbuf); /*Look up info from the capture device*/ pcap_lookupnet(argv[1],&netaddr,&mask,errbuf); /*Compiles the filter expression into a BPF filter program*/ pcap_compile(descr,&filter,"arp",1,mask); /*Load the filter program into the packet capture device*/ pcap_setfilter(descr,&filter); while(1) { packet=pcap_next(descr,&pkthdr); /*Get one packet*/ if(NULL==packet) continue; printf("\n\nPayload:\n"); for (i=0;i<pkthdr.len;i++) { if(isprint(packet[i])) printf("%c ",packet[i]); else printf(". "); if((i%16==0 && i!=0) || i==pkthdr.len-1) printf("\n"); } arpheader = (struct arphdr*)(packet+14);/*Point to the ARP header*/ printf("Received Packet Size: %d bytes\n",pkthdr.len); printf("Hardware type: %s\n",(ntohs(arpheader->htype)==1)?"Ethernet":"Unknown"); printf("Protocal type: %s\n",(ntohs(arpheader->ptype)==0x0800)?"IPv4":"Unknown"); printf("Operation: %s\n",(ntohs(arpheader->oper)==ARP_REQUEST)?"ARP Request":"ARP Reply"); /*If is Ethernet and IPv4,print packet contents*/ if(ntohs(arpheader->htype)==1 && ntohs(arpheader->ptype)==0x0800) { printf("Sender MAC: "); for(i=0;i<6;i++) printf("%02X:",arpheader->sha[i]); printf("\nSender IP: "); for(i=0;i<4;i++) printf("%d.",arpheader->spa[i]); printf("\nTarget MAC: "); for(i=0;i<6;i++) printf("%02X:",arpheader->tha[i]); printf("\nTarget IP: "); for(i=0;i<4;i++) printf("%d.",arpheader->tpa[i]); printf("\n"); } } return 0; }
编译:
编写makefile如下
arpsniffer:arp_sniffer.o cc -o arpsniffer arp_sniffer.o -lpcap arp_sniffer.o:arp_sniffer.c cc -c arp_sniffer.c -lpcap
在终端中键入命令$ make进行编译,生成可执行文件arpsniffer。
运行:
终端中键入sudo ./arpsniffer wlan0
说明:此处使用的是无线网卡wlan0,故以此网卡作为输入参数,并必须以root权限运行程序。网卡查看如下:
运行程序:
程序打印信息中,Payload是数据包的实际载荷,Received Packet Size是包的大小,Hardware type是数据链路层协议类型,Protocal type是网络层协议类型,另外还有ARP是请求还是回复,以及MAC地址和IP地址。
更多捕获的数据: