数据包分析
想要知道如何解析IP数据包,就要知道不同的IP数据包的包头结构,于是我们上⽹查查资料:
以太网数据包
ARP数据包
IPv4
IPv6
TCP
UDP
ICMP
ICMPv6
根据以上数据包头结构,我们就有了我们的protocol.h文件,声明各种数据包:
#ifndef PROTOCOL_H
#define PROTOCOL_H
#define HAVE_REMOTE
#define PROTO_ICMP 1
#define PROTO_TCP 6
#define PROTO_UDP 17
#include <iostream>
#include <QObject>
#include "_bsd_types.h"
#include "pcap.h"
using namespace std;
//IPV4
typedef struct ip_address{u_char byte1;u_char byte2;u_char byte3;u_char byte4;
}ip_address;typedef struct ipv6_address
{u_char byte1;u_char byte2;u_char byte3;u_char byte4;u_char byte5;u_char byte6;u_char byte7;u_char byte8;
}ipv6_address;typedef struct ipv4_header{u_char ver_ihl;u_char tos;u_short tlen;u_short Identification;u_short flags_fo;u_char ttl;u_char proto;u_short crc;ip_address srcaddr;ip_address dstaddr;u_int op_pad;
}ipv4_header;typedef struct ipv6_header{u_int ver:4,flowtype:8,flowtip:20;u_short len;u_char pnext;u_char lim;ipv6_address srcaddr;ipv6_address dstaddr;
}ipv6_header;typedef struct tcp_header{u_short srcport;u_short dstport;u_int seq;u_int ack_seq;u_short resl:4,doff:4,fin:1,syn:1,pst:1,psh:1,ack:1,urg:1,ece:1,cwr:1;u_short window;u_short check;u_short urg_ptr;u_int opt;
}tcp_header;typedef struct udp_header{u_short srcport;u_short dstport;u_short tlen;u_short crc;
}udp_header;typedef struct icmp_header{u_char type;u_char code;u_char seq;u_char crc;
}icmp_header;typedef struct icmp6_header{u_char type;u_char code;u_char seq;u_char crc;u_char op_type;u_char op_len;u_char op_ethaddr[6];
}icmp6_header;typedef struct pkg_count{int n_tcp;int n_udp;int n_icmp;int n_icmp6;int n_http;int n_arp;int n_ipv4;int n_ipv6;int n_other;int n_ttl;
}pkg_count;typedef struct arp_header{u_short hardware;u_short proto;u_char ml;u_char ipl;u_short opt;u_char sm[6];ip_address sip;u_char dm[6];ip_address dip;
}arp_hearder;typedef struct eth_header{u_char smac[6];u_char dmac[6];u_short type;
}eth_header;typedef struct pkg_data
{QString pkgtype;int time[6];int len;eth_header *ethh;ipv4_header *ipv4h;ipv6_header *ipv6h;arp_header *arph;udp_header *udph;tcp_header *tcph;icmp_header *icmph;icmp6_header *icmp6;void *apph;}pkg_data;#endif // PROTOCOL_H
再对数据包的结构进行了解后,我们就需要对这些包进行解析,所以我们需要一个packettools类,里面用静态函数写出包的解析,供我们在别的地方调用:
#ifndef PACKETTOOLS_H
#define PACKETTOOLS_H
#include <QObject>
#include <QTextEdit>
#include "protocol.h"
#include "iostream"using namespace std;class PacketTools
{
public:static int unpcak_Frame(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpcak_Arp(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Ip(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Ipv6(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Icmp(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Icmp6(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Tcp(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int unpack_Udp(const u_char *pkg,pkg_data *data,pkg_count *pkgCnts);static int pack_Print(u_char *pkg,int size,QTextEdit *edit);
};#endif // PACKETTOOLS_H
主要一点就是要知道父类数据包的type字段对子类数据包的分类,然后将数据包拷贝储存到全局容器里面。