这一章实际上没什么讲的,就是把协议的标准搞懂,然后用数据结构将其实现就行。直接上代码吧,由底层到高层逐步实现。这些协议头是怎么使用的,将在下一章做出解释。
- #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