IP报文首部:
版本号
占4位,标识目前采用的IP协议的版本号。一般的值为0100(IPv4),0110(IPv6)
首部长度
占4 位,用来表示IP报首部的长度。范围是0000--1111,只是在这里,我们的单位是32位字,即4个字节。所以IP首部大小范围是20—60(4*15)。当ip首部的度不是4字节的倍数时,必须要用最后的填充字段填充。所以数据部分的长度要从4字节的整数倍数开始。
区分服务
占8位,一般不使用。
总长度
占16位,表示的是数据和首部之和的长度。单位为字节,最大长度为2^16-1=65535个字节。
标识
占16位,当数据报的长度超过网络的MTU而必须分片时,这个标识就被复制到所有的数据报片的标识中。具有相同的标识字段的值使分片后的各数据报能正确的重装成原来的数据报。
标志
占3位,目前只有后两位有意义
MF=1时,表示后面还有分片,当MF=0时,表示这已是数据报中的最后一个。
DF=1时 表示不能有分片。当DF=0时,允许分片。
片偏移
占13位,表示当前片在原分组中相对于用户数据字段起点的相对位置。片偏移以8个字节为偏移单位。也就是说每个分片的长度一定是8字节的整数倍。
生存时间TTL
占8位表示数据报在网络中的寿命
TTL的意义是指明数据报在因特网中至多可以经过多少路由器。显然数据报能在因特网中经过的路由器的最大数值是255。
当TTL初始值设为1时,表明这个数据报只能在本局域网中传送。
协议
占8位。表示上层所使用的协议。
以下是比较常用的协议号:
首部检验和
占16位 这个字段只检验数据报的首部,不会检验数据部分。数据报每经过一个路由器,路由器都要重新计算一下首部校验和。
32位源地址
32位目的地址
IP报文首部结构体
struct iphdr {
#ifdefined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix<asm/byteorder.h>"
#endif
__u8 tos;
__u16 tot_len;
__u16 id;
__u16 frag_off;
__u8 ttl;
__u8 protocol;
__u16 check;
__u32 saddr;
__u32 daddr;
/*The options start here.*/
};
TCP报文格式
源端口和目的端口
各占2个字节。TCP的分用功能也是通过端口实现的。
序号
TCP是面向字节流的,在TCP连接中传送的每一个字节都是按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。
占4个字节,表示的是本报文段中所发送的数据的第一个字节的序号。序号使用mod(2^32)运算。
确认号
占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号。
若确认号是N,表明到序号N-1为止的所有数据都已经正确接收。
数据偏移:
占4位,表示TCP数据报数据的起始处到数据报开头的偏移量,表示了TCP数据报头部的大小,单位是32位字。也就是说TCP数据报首部的最大长度是60字节。
保留
占6位待他日使用
URG
当URG=1时,表示紧急指针有效,应该尽快传送。
ACK当ACK=1时,确认字段有效,在连接建立后的所有报文段都必须把ACK置为1。
PSH
当两个应用程序进行通信时,当PSH=1时,表示尽快地用“推送”给应用程序,而不用等到缓冲区满了再向上交付。
RST
复位,当TCP连接中出现了严重差错,必须释放连接。
SYN
同步当SYN=1时,表示这是一个连接请求或连接接受报文。
FIN
用来释放一个连接。当FIN=1时表示要求释放连接。
窗口
占2字节,窗口字段明确地指出了现在允许对方发送的数据量。窗口值是动态变化的。
检验和
占2个字节,检验和检验的范围包括首部和数据这两部分。
紧急指针
当URG=1时有效,它指出了紧急数据的字节数,当所有的紧急数据处理完时,TCP就告诉应用程序恢复到正常的操作中。
TCP头部结构体
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h>defines"
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;