一步一步开发sniffer(Winpcap+MFC)(四)要想从此过,留下协议头——各层网络协议头的实现
这一章实际上没什么讲的,就是把协议的标准搞懂,然后用数据结构将其实现就行。直接上代码吧,由底层到高层逐步实现。这些协议头是怎么使用的,将在下一章做出解释。#ifndef PROTOCOL_H#define PROTOCOL_H#define PROTO_ICMP 1#define PROTO_TCP 6#define PROTO_UDP 17#define
·
这一章实际上没什么讲的,就是把协议的标准搞懂,然后用数据结构将其实现就行。直接上代码吧,由底层到高层逐步实现。这些协议头是怎么使用的,将在下一章做出解释。
#ifndef PROTOCOL_H
#define PROTOCOL_H
#define PROTO_ICMP 1
#define PROTO_TCP 6
#define PROTO_UDP 17
#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
//Mac帧头 占14个字节
typedef struct ethhdr
{
u_char dest[6]; //6个字节 目标地址
u_char src[6]; //6个字节 源地址
u_short type; //2个字节 类型
};
//ARP头
typedef struct arphdr
{
u_short ar_hrd; //硬件类型
u_short ar_pro; //协议类型
u_char ar_hln; //硬件地址长度
u_char ar_pln; //协议地址长度
u_short ar_op; //操作码,1为请求 2为回复
u_char ar_srcmac[6]; //发送方MAC
u_char ar_srcip[4]; //发送方IP
u_char ar_destmac[6]; //接收方MAC
u_char ar_destip[4]; //接收方IP
};
//定义IP头
typedef struct iphdr
{
#if defined(LITTLE_ENDIAN)
u_char ihl:4;
u_char version:4;
#elif defined(BIG_ENDIAN)
u_char version:4;
u_char ihl:4;
#endif
u_char tos; //TOS 服务类型
u_short tlen; //包总长 u_short占两个字节
u_short id; //标识
u_short frag_off; //片位移
u_char ttl; //生存时间
u_char proto; //协议
u_short check; //校验和
u_int saddr; //源地址
u_int daddr; //目的地址
u_int op_pad; //选项等
};
//定义IP头
/*typedef struct iphdr
{
u_char ver_ihl;
u_char tos; //TOS 服务类型
u_short tlen; //包总长 u_short占两个字节
u_short id; //标识
u_short frag_off; //片位移
u_char ttl; //生存时间
u_char proto; //协议
u_short check; //校验和
u_int saddr; //源地址
u_int daddr; //目的地址
u_int op_pad; //选项等
};*/
//定义TCP头
typedef struct tcphdr
{
u_short sport; //源端口地址 16位
u_short dport; //目的端口地址 16位
u_int seq; //序列号 32位
u_int ack_seq; //确认序列号
#if defined(LITTLE_ENDIAN)
u_short res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(BIG_ENDIAN)
u_short doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#endif
u_short window; //窗口大小 16位
u_short check; //校验和 16位
u_short urg_ptr; //紧急指针 16位
u_int opt; //选项
};
/*typedef struct tcphdr
{
u_short sport; //源端口地址 16位
u_short dport; //目的端口地址 16位
u_int seq; //序列号 32位
u_int ack_seq; //确认序列号
u_short doff_flag; //头大小、保留位、标志位
u_short window; //窗口大小 16位
u_short check; //校验和 16位
u_short urg_ptr; //紧急指针 16位
u_int opt; //选项
};*/
//定义UDP头
typedef struct udphdr
{
u_short sport; //源端口 16位
u_short dport; //目的端口 16位
u_short len; //数据报长度 16位
u_short check; //校验和 16位
};
//定义ICMP
typedef struct icmphdr
{
u_char type; //8位 类型
u_char code; //8位 代码
u_char seq; //序列号 8位
u_char chksum; //8位校验和
};
//定义IPv6
typedef struct iphdr6
{
//#if defined(BIG_ENDIAN)
u_int version:4, //版本
flowtype:8, //流类型
flowid:20; //流标签
/*#elif defined(LITTLE_ENDIAN)
u_int flowid:20, //流标签
flowtype:8, //流类型
version:4; //版本
//#endif*/
u_short plen; //有效载荷长度
u_char nh; //下一个头部
u_char hlim; //跳限制
u_short saddr[8]; //源地址
u_short daddr[8]; //目的地址
};
//定义ICMPv6
typedef struct icmphdr6
{
u_char type; //8位 类型
u_char code; //8位 代码
u_char seq; //序列号 8位
u_char chksum; //8位校验和
u_char op_type; //选项:类型
u_char op_len; //选项:长度
u_char op_ethaddr[6]; //选项:链路层地址
};
//对各种包进行计数
typedef struct pktcount
{
int n_ip;
int n_ip6;
int n_arp;
int n_tcp;
int n_udp;
int n_icmp;
int n_icmp6;
int n_http;
int n_other;
int n_sum;
};
//////////////////////////////////////////////////////////////////////////
//要保存的数据结构
typedef struct datapkt
{
char pktType[8]; //包类型
int time[6]; //时间
int len; //长度
struct ethhdr* ethh; //链路层包头
struct arphdr* arph; //ARP包头
struct iphdr* iph; //IP包头
struct iphdr6* iph6; //IPV6
struct icmphdr* icmph; //ICMP包头
struct icmphdr6* icmph6; //ICMPv6包头
struct udphdr* udph; //UDP包头
struct tcphdr* tcph; //TCP包头
void *apph; //应用层包头
};
#endif
更多推荐
所有评论(0)