winpcap抓包解析,捕获ip数据包分析
2020华科计算机网络实验
文末有完整代码,仅供参考。
1.实验目的随着计算机网络技术的飞速发展,网络对社会经济的贡献越来越大。可以说,计算机网络的发展已经成为现代社会进步的重要标志。与此同时,计算机犯罪、黑客攻击、病毒入侵等恶性事件也频繁发生。数据包捕获、监控和分析技术是网络安全维护的基础技术,也是网络入侵的核心手段。基于网络数据包拦截和协议分析,捕获网络上传输的数据包,可以获取网络上传输的非法信息,对维护网络安全具有重要作用。
这个实验的主要目的是:
理解协议在通信中的作用;掌握数据包捕获软件的开发;掌握协议分析的编程方法。利用你所学的知识制作一个流量统计软件。2.实验要求:软件功能:
Winpcap用于捕获数据包,可以根据需要过滤数据包。根据IP协议,分析每个数据包的PCI,并显示其协议结构和不同网络级别的具体信息。根据IP地址,统计源自该IP地址的流量,即捕获的数据包数量。3.实验设计1。协议栈分析由于TCP/IP协议采用分层结构,在传输数据时,是在网络数据发送端进行封装的过程,在数据接收端进行分解的过程。
数据封装过程如图3.1所示。
并且解析接收到的分组是上述封装的逆过程。
1.以太网协议在以太网的发展中,有很多种帧格式,其中Ethernet 格式应用最为广泛,现在几乎是以太网的标准,由RFC894定义。帧格式如图3.2所示。
ARP协议ARP/RARP协议是IP地址和MAC地址相互转换的协议。在网络通信中,链路层使用MAC地址进行实际数据通信,而网络层使用IP地址进行机器定位和寻址。APR协议将IP地址映射到MAC地址,RARP则相反。如图3.3所示。
协议IP协议是互联网的核心协议,工作在网络层,提供不可靠、无连接的数据传输服务。协议格式如图3.4所示。
ICMP(Internet Control Message Protocol)提供了大量的互联网信息描述服务,可以检测网络的运行状态,并将有用的网络状态信息告知协议。ICMP基于IP协议,ICMP协议的格式如图3.5所示。
TCP协议TCP协议是一种基于连接的可靠协议。它负责发送和接收协议,然后维护正确可靠的数据传输服务。它运行在IP协议上,而IP是一种无连接协议,所以TCP丰富了IP协议的功能,使其具有可靠的传输服务。TCP协议格式如图3.6所示。
UDP用户数据报协议UDP是IP协议上的传输层协议,提供无连接协议服务。它在IP协议的基础上提供了端口功能,以便应用程序可以进行通信。UDP协议格式如图3.7所示。
2.协议处理Winpcap系统处理流程图3.8:
协议分析流程图3.9:
Ethernet_package_handler():用于解析以太网帧。
IP_v4_package_handler():用于解析IPv4数据报。
IP_v6_package_handler():用于解析IPv6数据报。
Arp_package_handler():用于解析Arp协议
ICMP_package_handler():用于解析ICMP协议
TCP_package_handler():用于解析TCP段。
Udp_package_handler():用于解析Udp段。3.交通统计。流量统计的流程如3.10所示。
分析网络层协议时,以IP地址为关键,流量值存储在map中。如果IP值已经存在,流量值加1,最终值表示该IP的流量。
四。软件实现这个软件是用C实现的,写在VS 2017上。
1.效果:选择装备。
选择要捕获的数据包数量。
ARP协议分析
IP协议分析
UDP协议解析
ICMP协议解析
最终效果
2.头文件设计#ifndef _PAC_ANA_H
#define _PAC_ANA_H
# VER国际金融中心
/*
*我们不希望出现关于旧的不推荐使用的和不安全的C
*/
#define _CRT_SECURE_NO_WARNINGS
#endif
/*设置环境头文件*/
#定义WIN32
#pragma comment (lib, ws2_32.lib) //load ws2_32.dll
/*设置C头文件*/
#包括输入输出流
#包含标准视频
#包含地图
#包含字符串
#包括非全部
#包含流
/*设置wpcap头文件*/
#包含" pcap.h "
#包含WinSock2.h
#定义分部-
# define B _ DIVISION =================
/* 4字节互联网协议(Internet Protocol)地址*/
数据类型说明结构ip _ v4 _地址
/* 16字节互联网协议(Internet Protocol)地址*/
数据类型说明结构ip _ v6 _地址ip _ v6 _地址
/*8字节测量与控制(Measurement and Control)地址*/
typedef struct MAC _ address MAC _ address;
/*以太网报头*/
typedef struct Ethernet _ header Ethernet _ header;
/* IPv4报头*/
数据类型说明结构ip _ v4 _ header
/*IPv6报头*/
数据类型说明结构ip _ v6 _ header
/*arp头*/
typedef struct ARP _ header ARP _ header;
/*TCP报头*/
typedef struct TCP _ header TCP _ header;
/* UDP头*/
数据类型说明结构udp _ header
/*ICMP头*/
typedef struct icmp _ header icmp _ header;
/*数据包处理程序的原型*/
void packet _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析以太网数据包*/
void Ethernet _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析IPv4数据包*/
void IP _ v4 _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析IPv6数据包*/
void IP _ V6 _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析阿尔普数据包*/
void ARP _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析用户数据报协议数据包*/
void UDP _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析传输控制协议数据包*/
void TCP _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*分析网间控制报文协议数据包*/
void icmp _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u _ char * PKT _ data);
/*用c标准:地图对包进行计数*/
void add _ to _ map(STD:map STD:string,int counter,IP _ v4 _ address IP);
void add _ to _ map(STD:map STD:string,int counter,IP _ V6 _ address IP);
/*打印地图信息*/
void print _ map(STD:map STD:string,int counter);
#endif //!H3帕克安娜。具体实现#包含pac_ana.h
使用命名空间标准
/*ip计数器*/
std:map std:string,int计数器;
/*标题结构*/
结构ip _ v4 _地址
{
u _ char字节1
u _ char字节2
u _ char字节3
u _ char字节4
};
结构ip _ v6 _地址
{
u _ short part1
u _ short part2
u _ short part3
u _ short part4
u _ short part5
u _ short part6
u _ short part7
u _ short part8
};
结构老兄地址
{
u _ char字节1
u _ char字节2
u _ char字节3
u _ char字节4
u _ char字节5
u _ char字节6
};
结构以太网_标题
{
老兄地址数据访问控制地址
MAC _地址src _ mac _ addr
u_short类型;
};
结构ip _ v4 _头
{
u _ char ver _ ihl//版本(4位)互联网报头长度(4位)
u _ char tos//服务类型
u _ short tlen//总长度
u_short标识;//标识
u _ short flags _ fo//标志(3位)片段偏移量(13位)
u _ char ttl//生存时间
u _ char proto//协议
u_short校验和;//标头校验和
ip _ v4 _ address//源地址
ip _ v4 _ address//目标地址
u _ int op _ pad//选项填充
};
结构ip_v6_header
{
u _ int 32 _ t ver _ traffic class _ flow标签;
u _ short有效载荷_长度
u _ char next _ head
u _ char ttl
ip _ v6 _地址
ip _ v6 _地址dst _ ip _地址
};
结构arp_header
{
u _ short硬件类型
u_short协议_类型;
u字符硬件长度;
u字符协议_长度;
u_short操作_代码;
mac地址来源mac地址
ip地址v4地址源地址;
老兄地址数据访问控制地址
ip地址v4地址
};
结构tcp_header
{
u _ short运动
u _ short数据端口
u_int序列;
u_int确认;
u字符偏移量;
u字符标志;
u_short窗口;
u_short校验和;
u_short急_指针;
};
结构udp_header
{
u _ short sport//源端口
u _ short dport//目标端口
u _ short len//数据报长度
u_short校验和;//校验和
};
结构icmp_header
{
u字符类型;
u字符代码;
u_short校验和;
u _短id
u_short序列;
};
int main()
{
pcap _ if _ t * alldevs
pcap _ if _ t * d;
int inum
int I=0;
int pktnum
pcap _ t * adhandle
char ERRBUF[PCAP _ ERRBUF _ SIZE];
u _ int netmask=0xffffff
结构bpf _程序fcode
if (pcap_findalldevs( alldevs,errbuf)==-1)
{
fprintf(stderr, pcap_findalldevs中的错误:%s\n ,errbuf);
出口(1);
}
for(d=所有开发人员;d;d=d-下一个)
{
cout i。“d-name;
如果(d-描述)
描述恩德尔
其他
cout (没有可用的描述) endl
}
如果(i==0)
{
cout \ n找不到接口!请确保安装了WinPcap .恩德尔
return-1;
}
cout 输入接口号(1-我):;
的文件伊努姆;
if (inum 1 inum i)
{
cout \接口号超出范围endl
pcap _ freeall devs(所有dev);
return-1;
}
for (d=alldevs,I=0;I inum-1;d=d-下一个,我);
if((ad handle=pcap _ open _ live(d-name,//设备名称
65536,//要捕获的数据包部分。
//65536允许在所有测量与控制(Measurement and Control)上捕获整个数据包。
1,//混杂模式(非零表示混杂)
1000,//读取超时
errbuf //错误缓冲区
))==NULL)
{
fprintf(stderr, \ n无法打开适配器WinPcap。不支持% s是,d-name);
pcap _ freeall devs(所有dev);
return-1;
}
“cout”监听" d-描述".恩德尔
pcap _ freeall devs(所有dev);
if (pcap_compile(adhandle,fcode, ip或arp ,1,网络掩码)0)
{
fprintf(stderr, \ n无法编译数据包筛选器。检查语法. \ n );
pcap _ close(广告句柄);
return-1;
}
if (pcap_setfilter(adhandle,fcode) 0)
{
fprintf(stderr, \ n设置筛选器时出错. \ n );
pcap _ close(广告句柄);
return-1;
}
cout 请输入您要捕获的数据包数量(0表示保持捕获):;
CIN PKT编号;
cout结束
pcap_loop(adhandle,pktnum,packet_handler,NULL);
pcap _ close(广告句柄);
getchar();
返回0;
}
/* libpcap为每个传入的数据包调用回调函数*/
void packet _ handler(u _ char * param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
结构tm * ltime
char timestr[16];
时间_本地_电视_秒
/*将时间戳转换为可读格式*/
local _ TV _ sec=header-ts。TV _ sec
ltime=当地时间(local _ TV _ sec);
strftime(timestr,sizeof timestr, %H:%M:%S ,ltime);
cout B_DIVISION time: timestr ,
标题-ts。TV _ usec len: header-len B _ DIVISION endl;
ethernet_package_handler(param,header,PKT _ data);
}
void Ethernet _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
Ethernet _ header * eh=(Ethernet _ header *)PKT _ data;
法院部门以太网协议分析结构分部恩德尔
u _ short type=ntohs(eh-type);
cout 类型:0x "十六进制类型;
cout set base(10);
开关(类型)
{
案例0x0800:
cout (IP v4) endl;
打破;
案例0x86DD:
cout (IPv6) endl;
打破;
案例0x0806:
cout (ARP) endl;
打破;
案例0x0835:
cout (RARP) endl;
默认值:
打破;
}
cout 目的地址: int(eh- des_mac_addr.byte1):
int(eh- des_mac_addr.byte2):
int(eh- des_mac_addr.byte3):
int(eh- des_mac_addr.byte4):
int(eh- des_mac_addr.byte5):
int(eh-des _ MAC _ addr。字节6)endl;
cout 源地址: int(eh- src_mac_addr.byte1):
int(eh- src_mac_addr.byte2):
int(eh- src_mac_addr.byte3):
int(eh- src_mac_addr.byte4):
int(eh- src_mac_addr.byte5):
int(eh-src _ MAC _ addr。字节6)endl;
开关(类型)
{
案例0x0800:
ip_v4_package_handler(param,header,PKT _ data);
打破;
案例0x0806:
arp_package_handler(param,header,PKT _ data);
打破;
案例0x86DD:
ip_v6_package_handler(param,header,PKT _ data);
打破;
默认值:
打破;
}
cout endl结束
}
请参阅ARP _ package _ handler(u _ char * param、const struct pcap _ pkthdr * header、const u_char *pkt_data)
{
arp _ header * ah
ah=(ARP _ header *)(PKT _ data 14);
空袭预防措施分割层协议分析结构终师;
u _ short operation _ code=ntohs(ah-operation _ code):
嘿,嘿硬件类型ntohs(ah-硬件类型)结束;
嘿,嘿协议类型:0x 十六进制数字(ah-协议类型)结尾;
setbase层(10);
嘿,嘿硬件地址长度int(ah-硬件长度)结束:
嘿,嘿协议地址长度: int(ah-协议长度)结尾:
开关(操作代码)
{
案例1:
空袭预防措施层请求协议结束;
打断;打断;
案例2:
空袭预防措施层应答协议结束;
打断;打断;
案例3:
空袭预防措施层请求协议结束;
打断;打断;
案例4:
拉普路应答协议结束;
打断;打断;
默认设置:
打断;打断;
}
嘿,嘿源互联网协议(Internet Protocol)地址地址:"
int(ah- source_ip_addr.byte1)。"
int(ah- source_ip_addr.byte2)。"
int(ah- source_ip_addr.byte3)。"
int(ah- source_ip_addr .字节4)结束;
嘿,嘿目的互联网协议(Internet Protocol)地址地址:"
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器:
添加到地图(计数器,ah- source_ip_addr):
print_map(计数器):
}
请参阅IP _ v4 _ package _ handler(u _ char * param、const struct pcap _ pkthdr * header、const u_char *pkt_data)
{
S7-1200可编程控制器:
ih=(IP _ v4 _ header *)(PKT _ data 14);//14测量值以太网标头长度
IPv4拆分层协议分析结构终师;
嘿,嘿版本号"((ih- ver_ihl0xf0) 4)结束;
嘿,嘿首部长度(ih- ver_ihl0xf)。"
((ih-ver _ IHL0x(2) b)结束;
嘿,嘿区别服务* int(ih-to)结束;
嘿,嘿总长度* ntohs(ih-tlen)有限公司;
嘿,嘿标识ntohs(ih-身份识别)结束;
嘿,嘿标志"((ih-flags _ fo0x 000)12)结束;
嘿,嘿片偏移S7-1200可编程控制器
((ih-flags _ fo0x 1 fff(3) b)"结束;
嘿,嘿生命周期* int(ih-TTL)结束;
嘿,嘿协议* ":
交换机(ih协议)
{
案例6:
三氯苯酚端包:
打断;打断;
案例17:
用户数据报协议(User Datagram Protocol)端层:
打断;打断;
案例1:
网间控制报文协议(Internet Control Messages Protocol)端包:
打断;打断;
默认设置:
端盖;端盖;
打断;打断;
}
嘿,嘿校验和ntohs(ih校验和)结尾;
嘿,嘿源互联网协议(Internet Protocol)地址地址:"
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器:
嘿,嘿目的互联网协议(Internet Protocol)地址地址:"
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器:
交换机(ih协议)
{
案例6:
tcp_package_handler(param、header、pkt_data):
打断;打断;
案例17:
udp_package_handler(param、header、pkt_data):
打断;打断;
案例1:
icmp_package_handler(param、header、pkt_data):
打断;打断;
默认设置:
打断;打断;
}
S7-1200可编程控制器:
print_map(计数器):
}
请参阅IP _ V6 _ package _ handler(u _ char * param、const struct pcap _ pkthdr * header、const u_char *pkt_data)
{
S7-1200可编程控制器:
ih=(IP _ V6 _ header *)(PKT _ data 14);//14测量值以太网标头长度
(同Internationalorganizations)国际组织版本=(ih-ver _ traffic class _ flow label 0 xf 000000)28;
int traffic _ class=ntohs(ih-ver _ traffic class _ flow label0x 0 ff 00000)20);
int flow _ label=ih-ver _ traffic class _ flow label0x 000 fff:
嘿,嘿版本号*最终版本:
嘿,嘿通信量类traffic _ class结束:
嘿,嘿流标号流标签结束:
嘿,嘿有效载荷ntohs(ih有效负载_len)结束:
嘿,嘿下一个首部int(ih- next_head)结束:
嘿,嘿跳数限制* int(ih-TTL)结束;
嘿,嘿源互联网协议(Internet Protocol)地址地址:"
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器:
嘿,嘿目的互联网协议(Internet Protocol)地址地址:"
内部(ih-dst _ IP _ add。第1部分):"
内部(ih-dst _ IP _ add。第二部分):”
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
S7-1200可编程控制器
int(ih- dst_ip_addr.part8)结束;
开关(ih- next_head)
{
案例6:
tcp_package_handler(param、header、pkt_data):
打破;
案例17:
udp_package_handler(param,header,PKT _ data);
打破;
案例58:
icmp_package_handler(param,header,PKT _ data);
打破;
默认值:
打破;
}
添加到地图(计数器,ih-src _ IP _ addr);
print_map(计数器);
}
void UDP _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
udp _ header * uh
uh=(UDP _ header *)(PKT _ data 20 14);
法院部门的用户数据报协议(User Datagram Protocol)协议分析结构分部恩德尔
cout 源端口: ntohs(uh-sport)endl;
cout 目的端口: ntohs(uh-dport)endl;
cout 长度: ntohs(uh-len)endl;
cout 检验和: ntohs(uh-checksum)endl;
}
void TCP _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
tcp _ header * th
th=(TCP _ header *)(PKT _ data 14 20);
cout DIVISION TCP协议分析结构分部恩德尔
cout 源端口: ntohs(th-sport)endl;
cout 目的端口: ntohs(th-d端口)endl
cout 序号: ntohl(th-sequence)endl;
cout 确认号: nto HL(th-acknowledge ment)endl;
cout 数据偏移:((th- offset0xf0) 4)(
((th-offset0xf 0)2) B) endl;
cout 标志: ;
如果(第标志0x01)
{
科特芬
}
如果(第标志0x02)
{
cout SYN
}
如果(第标志0x04)
{
cout RST
}
如果(第标志0x08)
{
cout PSH
}
如果(第标志0x10)
{
cout ACK
}
如果(第个标志0x20)
{
考特堡
}
cout结束
cout 窗口: ntohs(th-windows)endl;
cout 检验和: ntohs(第个校验和)endl
cout 紧急指针: ntohs(th-urgent _ pointer)endl;
}
void icmp _ package _ handler(u _ char * param,const struct pcap_pkthdr *header,const u_char *pkt_data)
{
icmp _ header * ih
ih=(icmp _ header *)(PKT _ data 14 20);
标准输出部门的网间控制报文协议(Internet Control Messages Protocol)协议分析结构分部恩德尔
cout ICMP类型: ih-type;
开关(ih型)
{
案例8:
cout ICMP回显请求协议恩德尔
打破;
案例0:
cout ICMP回显应答协议恩德尔
打破;
默认值:
打破;
}
cout ICMP代码: ih-code endl;
cout 标识符: ih-id endl;
cout 序列码:‘ih-sequence endl;
cout ICMP校验和: ntohs(ih校验和)endl
}
void添加到地图(映射字符串,int计数器,ip _ v4 _地址ip)
{
字符串ip _字符串
int amount=0;
映射字符串,int:迭代器ITER;
ip_string=to_string(ip.byte1) .
to_string(ip.byte2) .
to_string(ip.byte3) .
to _字符串(IP。字节4);
ITER=柜台。find(IP _ string);
如果(iter!=counter.end())
{
量=iter-秒;
}
柜台。insert _ or _ assign(IP _ string,amount);
}
void添加到地图(映射字符串,int计数器,ip _ v6 _地址ip)
{
字符串ip _字符串
int amount=0;
映射字符串,int:迭代器ITER;
ip_string=to_string(ip.part1):
to_string(ip.part2):
to_string(ip.part3):
to_string(ip.part4):
to_string(ip.part5):
to_string(ip.part6):
to_string(ip.part7):
to _字符串(IP。第8部分);
ITER=柜台。find(IP _ string);
如果(iter!=counter.end())
{
量=iter-秒;
}
柜台。insert _ or _ assign(IP _ string,amount);
}
void print_map(映射字符串,int计数器)
{
映射字符串,int:迭代器ITER;
法院部门流量统计分部恩德尔
cout IP setfill( ) setw(45)流量恩德尔
for(ITER=计数器。begin();iter!=计数器。end();iter)
{
cout iter- first setfill( . )setw(45-ITER-第一。length())ITER-第二endl
}
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。