孙斌防火墙实验包过滤防火墙实验Word下载.docx
《孙斌防火墙实验包过滤防火墙实验Word下载.docx》由会员分享,可在线阅读,更多相关《孙斌防火墙实验包过滤防火墙实验Word下载.docx(17页珍藏版)》请在冰点文库上搜索。
3、在实验报告中写出程序关键算法和流程图,根据WinPcap常用库函数总结出基于WinPcap的嗅探器的程序框架,并附上程序界面或运行结果。
利用原有回调函数进行数据包捕获:
a)对ICMP数据包的嗅探:
b)对Udp数据包的嗅探:
c)对Tcp数据包的嗅探:
(五)思考题
1.WinPcap嗅探器的攻击机理如何?
捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;
在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;
在网络上发送原始的数据包;
收集网络通信过程中的统计信息。
2.WinPcap主要包括哪些模块,各模块的作用如何?
Winpcap是针对Win32平台上的抓包和网络分析的一个架构。
它包括一个核心态的包过滤器,一个底层的动态链接库(packet.dll)和一个高层的不依赖于系统的库(wpcap.dll)。
网络数据包过滤器(Netgroup
Packet
Filter,NPF)是Winpcap的核心部分,它是Winpcap完成困难工作的组件。
它处理网络上传输的数据包,并且对用户级提供可捕获(capture)、发送(injection)和分析性能(analysis
capabilities)。
NDIS(Network
Driver
Interface
Specification)是一个定义网络适配器(或者说成是管理网络适配器的驱动程序)与协议驱动(例如TCP/IP的实现)之间通信的规范。
NDIS最主要的目的是作为一个允许协议驱动发送和接收网络(LAN或WAN)上的数据包而不必关心特定的适配器或特定的Win32操作系统的封装。
3.结合自己设计系统,画出WinPcap数据包捕获流程。
附录:
//MyWincap.cpp:
定义控制台应用程序的入口点。
//
#include"
stdafx.h"
#include<
iostream>
usingnamespacestd;
#defineHAVE_REMOTE
pcap.h"
typedefunsignedcharbyte;
typedefstructip_address{
}ip_address;
/*IPv4首部*/
typedefstructip_header{
}ip_header;
/*UDP首部*/
typedefstructudp_header{
}udp_header;
/*TCP首部*/
typedefstructtcp_header{
}tcp_header;
/*ICMP首部*/
typedefstructicmp_header{
}icmp_header;
/*回调函数原型*/
voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);
voidoutputUDPMaeeage(udp_header*uh);
voidoutputTCPMaeeage(tcp_header*th);
voidoutputICMPMaeeage(icmp_header*icmh);
intmain()
{
u_intnetmask;
structbpf_programfcode;
pcap_if_t*alldevs;
pcap_if_t*d;
pcap_t*adhandle;
inti=0;
charerrbuf[PCAP_ERRBUF_SIZE];
/*获取本地机器设备列表*/
if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL/*authisnotneeded*/,&
alldevs,errbuf)==-1)
{
fprintf(stderr,"
Errorinpcap_findalldevs_ex:
%s\n"
errbuf);
exit
(1);
}
/*打印列表*/
for(d=alldevs;
d!
=NULL;
d=d->
next)
cout<
<
d->
name;
i++;
if(d->
description)
printf("
(%s)\n"
d->
description);
else
(Nodescriptionavailable)\n"
);
if(i==0)
printf("
\nNointerfacesfound!
MakesureWinPcapisinstalled.\n"
return0;
}
//pcap_t*pcap_open(
//constchar*source,//指定的网卡的名称
//intsnaplen,//帧的长度
//intflags,//网卡捕获的模式
//intread_timeout,//超时
//structpcap_rmtauth*auth,//是否要求认证
//char*errbuf//错误信息存储
//)
for(d=alldevs,i=0;
i<
2;
d=d->
next,i++);
if((adhandle=pcap_open(d->
name,1500,PCAP_OPENFLAG_PROMISCUOUS,1000,NULL,errbuf))==NULL)
\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n"
/*释放设备列表*/
pcap_freealldevs(alldevs);
return-1;
/*检查数据链路层,为了简单,我们只考虑以太网*/
if(pcap_datalink(adhandle)!
=DLT_EN10MB)
\nThisprogramworksonlyonEthernetnetworks.\n"
if(d->
addresses!
=NULL)
/*获得接口第一个地址的掩码*/
netmask=((structsockaddr_in*)(d->
addresses->
netmask))->
sin_addr.S_un.S_addr;
else
/*如果接口没有地址,那么我们假设一个C类的掩码*/
netmask=0xffffff;
intchosefilter;
cout<
"
请选择过滤器要求:
(1)ipandudp
(2)ipandtcp(3)ipandicmp{1-3}\n"
;
cin>
>
chosefilter;
while(chosefilter<
1||chosefilter>
3)
请选择-3中的数字!
!
\n"
cin>
stringchose;
switch(chosefilter)
case1:
chose="
ipandudp"
break;
case2:
ipandtcp"
case3:
ipandicmp"
//charpacket_filter[]=chose;
charpacket_filter[]="
//编译过滤器
if(pcap_compile(adhandle,&
fcode,packet_filter,1,netmask)<
0)
\nUnabletocompilethepacketfilter.Checkthesyntax.\n"
//设置过滤器
if(pcap_setfilter(adhandle,&
fcode)<
0)
\nErrorsettingthefilter.\n"
printf("
\nlisteningon%s...\n"
/*释放设备列表*/
pcap_freealldevs(alldevs);
/*开始捕捉*/
pcap_loop(adhandle,0,packet_handler,NULL);
/*不再需要设备列表了,释放它*/
//pcap_freealldevs(alldevs);
system("
pause"
return0;
}
/*回调函数,当收到每一个数据包时会被libpcap所调用*/
voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data)
structtm*ltime;
chartimestr[16];
ip_header*ih;
udp_header*uh;
tcp_header*th;
icmp_header*icmh;
u_intip_len;
time_tlocal_tv_sec;
/*获得IP数据包头部的位置*/
ih=(ip_header*)(pkt_data+14);
//以太网头部长度
/*获得UDP首部的位置*/
ip_len=(ih->
ver_ihl&
0xf)*4;
数据包:
时间和长度:
/*将时间戳转换成可识别的格式*/
local_tv_sec=header->
ts.tv_sec;
ltime=localtime(&
local_tv_sec);
strftime(timestr,sizeoftimestr,"
%H:
%M:
%S"
ltime);
/*打印数据包的时间戳和长度*/
%s.%.6dlen:
%d"
timestr,header->
ts.tv_usec,header->
len);
/*将网络字节序列转换成主机字节序列*/
switch(int(ih->
proto))
case1:
cout<
数据包类型:
ICMP:
icmh=(icmp_header*)((u_char*)ih+ip_len);
/*获得ICMP首部的位置*/
outputICMPMaeeage(icmh);
break;
case6:
TCP:
th=(tcp_header*)((u_char*)ih+ip_len);
/*获得TCP首部的位置*/
outputTCPMaeeage(th);
case17:
UDP:
uh=(udp_header*)((u_char*)ih+ip_len);
/*获得UDP首部的位置*/
outputUDPMaeeage(uh);
/*打印IP地址和UDP端口*/
源IP地址:
int(ih->
saddr.byte1);
cout<
'
.'
saddr.byte2);
saddr.byte3);
saddr.byte4);
目的IP地址:
daddr.byte1);
daddr.byte2);
daddr.byte3);
daddr.byte4);
\n\n"
}