数据包分析
想要知道如何解析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字段对子类数据包的分类,然后将数据包拷贝储存到全局容器里面。