IP头部:20个字节
算法
TCP头部:20字节网络
UDP头部:8字节tcp
ICMP头部:4字节大数据
TTL:通过一个路由器就减1,当TTL值为0时,路由器就丢弃这个包,而后发送ICMP包给源主机。this
默认状况下,Linux系统的TTL值为64或255,Windows NT/2000/XP系统的TTL值为128,Windows 98系统的TTL值为32,UNIX主机的TTL值为255。spa
以太网EthernetII最大的数据帧是1518字节,刨去以太网帧的帧头(DMAC目的地址MAC48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes(有时候你们也把它叫作FCS),那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes. 这个值咱们就把它称之为MTU。指针
以太网数据包长度:(64~1518)code
MTU: Maxitum Transmission Unit 最大传输单元 (46~1500)orm
MSS:Maxitum Segment Size 最大分段大小(MTU-IP header size-TCP header size)(1460=1500-20-20)htm
MSS解释:
MSS最大传输大小的缩写,是TCP协议里面的一个概念。MSS就是TCP数据包每次可以传输的最大数据分段。为了达到最佳的传输效能TCP协议在创建链接的时候一般要协商双方的MSS值,这个值TCP协议在实现的时候每每用MTU值代替(须要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)因此每每MSS为1460。通信双方会根据双方提供的MSS值得最小值肯定为此次链接的最大MSS值。
图中括号中的数字表明的是当前域所占的空间大小,单位是bit位。
黄色的是数据链路层的头部,一共18字节
绿色的部分是IP头部,通常是20字节
紫色部分是TCP头部,通常是20字节
最内部的是数据包内容
黄色部分:链路层
目的MAC:当前step目的主机的mac地址
源MAC:当前step的源主机的mac地址
类型:指定网络层所用的协议类型,一般是IP协议,0x0800
绿色部分:网络层,这里用的是IP包头格式
版本:记录数据报属于哪个版本的协议,如IPv4或IPv6
首部长度:指明IP头部长度,单位是字,也就是两个字节。该域的值最小为5,就是标准的头部长度;最大为15,代表有扩展部分。
服务类型:用来区分不一样服务的须要
数据报总长:包含IP头部的数据报的总长度。注意,这里不包括链路层的头部,目前最大值是65535字节。
分组ID:这个域的做用是当一个大的数据报被拆分时,拆分红的小的数据段的这个域都是同样的。
标记:共三个bit,第一个未使用;第二个DF(Don’t Fragment),设置成1表示这个数据包不能被分割,这个是针对路由器的一条指令;第三个MF(MoreFragment),若是一个数据包被分割了,那么除了最后一个分段之外的全部分段都必须设置为1,用来表示后面还有更多的分段没有到达,最后一个设置为0,用来表示分割的段所有到达。
段偏移量:这个域有13bit,也就是每个数据报最多有8192个分段。每个分段的长度必须是8字节的倍数,也就是说8字节是分段的基本单位,固然分组的最后一个段不作限制。这样最大的数据报长度为8*8192=65536字节,比目前限制的最大数据报长度还多1,可以知足对网络中全部数据报传送的需求。
生存时间:这是一个生存期计数器,最大为255s,可是实际上使用的时候用做跳数计数器,当值为0时数据报被丢弃,用来避免一个数据报太久的逗留在网络中。
高层协议:这里和链路层的类型做用相同,用来表示更高层的协议,这个数据报里是TCP
首部校验和:IP头部的校验和
源IP地址:数据报来源主机的IP地址
目的IP地址:数据报目的主机的IP地址
紫色部分:传输层,这里用的是TCP协议
源端口号:数据报来源主机的端口号
目的端口号:数据报目的主机的端口号
注意:源IP地址,目的IP地址,源端口号,目的端口号这四个字段惟一的肯定了一个TCP连接。
TCP序号(sq):发送的TCP的序号,从0开始,实际中这个值就是发送的数据报中内容的字节数,好比我发送的第一个报中sq=0,数据报内容20字节,那么下一个数据报的sq就应该是21。
捎带的确认(ack):确认收到上一个数据报,而后act的值是指定本身想要收到的下一个数据报的sq,好比我收到一个数据报的sq=0,数据报内容20字节,那么个人ack就应该是21,用来标明我sq=0,内容为20字节的数据报已经收到,我接下来指望收到的是sq=21的数据报。
首部长度:和IP头部的长度域相似,这个域用来标明TCP头部的长度,单位也是字。
保留:6bit未使用的域
Flag:从左到右,[URG|ACK|PSH|RST|SYN|FIN]
ACK设置为1表示前面的确认(ack)是有效的,不然前面的确认应被忽略。
PSH表示要求对方在接到数据后当即请求递交给应用程序,而不是缓冲起来直到缓冲区收满为止。
RST用于重置一个已经混乱的链接。
SYN用于创建链接的过程。在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域。连接应答则捎带了一个确认,即SYN=1和ACK=1.本质上SYN位是用来表示CONNECTION
REQUEST和CONNECTION ACCEPTED,而后进一步用ACK来区分是请求仍是应答,的确很高明。
FIN用来释放一个链接。它表示发送方已经没有数据要传输了。而后,在关闭一个链接后,关闭进程可能会在一段不肯定的时间内继续接收到数据。SYN和FIN数据段都有TCP序号,从而保证了这两种数据段被按照正确的顺序来进行处理。
窗口大小:指定了从被确认的字节算起能够发送多少个字节。要深刻理解这个域的含义,能够参看TCP用色控制和慢启动算法
校验和:校验范围包括TCP头、数据报内容和概念性伪头部。概念性伪头部又包括源IP,目的IP,TCP协议号。
紧急指针:指向数据报中紧急数据最后一个字节的下一个字节。
//以太网头部 struct ethhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_source[ETH_ALEN]; /* source ether addr */ __be16 h_proto; /* packet type ID field */ } __attribute__((packed));
// arp头部 struct arphdr { __be16 ar_hrd; /* format of hardware address */ __be16 ar_pro; /* format of protocol address */ unsigned char ar_hln; /* length of hardware address */ unsigned char ar_pln; /* length of protocol address */ __be16 ar_op; /* ARP opcode (command) */ #if 0 /* * Ethernet looks like this : This bit is variable sized however... */ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ unsigned char ar_sip[4]; /* sender IP address */ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ unsigned char ar_tip[4]; /* target IP address */ #endif };
//IP头部 struct iphdr { #if defined(__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; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ };
//UDP头部 struct udphdr { __be16 source; __be16 dest; __be16 len; __sum16 check; };
//TCP头部 struct tcphdr { __be16 source; __be16 dest; __be32 seq; __be32 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 __be16 window; __sum16 check; __be16 urg_ptr; };