您的位置:首页 > 理论基础 > 计算机网络

《TCP/IP详解,卷2:实现》读书笔记-IP首部格式

2007-04-11 19:45 411 查看
前面讲了这么多数据结构,Now welcome to IP's world! 首先还是要讲几个概念,是不是觉得概念太多,往往理解原理的第一步就是了解概念,只有将概念吃透了,后面才能事半功倍,就像改革开放的第一件事情就是解放思想一样!
我们把传输协议交给IP的数据称为报文。典型的报文包含一个运输层首部和应用程序数据。IP在报文的首部前加上它自己的首部形成一个数据报。如果在选定的网络中,数据报的长度太大,IP就把数据报分裂成几个分片,每个分片中含有它自己的IP首部和一段原来数据报的数据。当提交给数据链路层进行传送时,一个IP分片或一个很小的无需分片的IP数据报称为分组。数据链路层在分组前面加上它自己的首部,并发送得到的帧。
IP只考虑它自己加上的IP首部,对报文本身既不检查也不修改(除非进行分片),出错重传等机制都需要上层协议去保证。所有的协议均使用相同的校验算法(由函数in_cksum完成),但应用于分组的不同部分。对IP来说,检验和只保证IP的首部。对传输协议,如UDP或TCP,检验和覆盖了分组的数据部分和运输层首部。
在C中,处理位于一个无类型存储区域中数据的最简单的方法是:在该存储区域上覆盖一个结构,转而处理该结构中的各个成员,而不再对原始的字节进行操作。如果用C语言做过协议编程的人对这种用法应该有很深的体会。前面讲mbuf结构时谈到了一个IP分组可能储存在多个物理mbuf中,各mbuf相互连接在一个链表上。因为覆盖技术也可用于IP分组的首部,所以首部必须驻留在一段连续的存储区内,不能把首部分开放在不同的存储器缓存区。

struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_char ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};

4个字节的32bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作bigendian字节序,又称作网络字节序。这样我们理解上面结构中的版本和首部长度的次序时就比较好理解了,对于大端字节序,是版本在前首部长度在后,对于小端字节序,刚好是反过来的。

对照上面的结构,我们来看看IP首部的格式,将IP首部和结构对照起来比较,印象会特别深刻:)



目前的协议版本号是4,因此IP有时也称作IPv4。首部长度指的是首部占32bit字的数目,包括任何选项。由于它是一个4比特字段,因此首部最长为60个字节。总长度字段是指整个IP数据报的长度,以字节为单位。利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16比特,所以IP数据报最长可达65535字节。标识字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1。TTL(time-to-live)生存时间字段设置了数据报可以经过的最多路由器数。当该字段的值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。首部检验和字段是根据IP首部计算的检验和码。它不对首部后面的数据进行计算。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: