设计人员为每个接入网络中的主机都分配一个 IP 地址(Internet Protocol Address),是一个 32 位的整数地址
只有合法的 IP 地址才能接入互联网中并且与其他主机进行通信
IP 地址是软件地址,不是硬件地址。
硬件 MAC 地址是存储在网卡中的,应用于本地网络中寻找目标主机。
网络地址转换(NAT)
它是一种把内部私有网络地址(IP 地址)翻译成合法网络 IP 地址的技术。
具有 NAT 功能的路由器必须拥有一个内部地址与一个外部地址。 |
---|
内部地址:是为了与局域网的用户通信而使用的,它使用一个特定的内部 IP 地址,如 192.168.0.1(也是局域网的网关)。 外部地址:是与广域网进行通信而使用的,这是一个有效的 IP 地址,通常为运营商分配给我们。 |
IP报文
IP首部片段 | 长度 /bit |
解释 |
---|---|---|
版本 | 4 | IPv4,该值为 4; 对于 IPv6,该值为 6。 |
首部字段 | 4 | 用于记录 IP 首部的数据的长度 IP 首部中包含了一些可变的数据选项,故需要这 4bit 记录首部的长度 |
服务类型(TOS) | 8 | 以便使不同类型的 IP 数据报(例如,一些特别要求低时延、高吞吐量或可靠性的数据报)能相互区别开来。 |
数据包长度 | 16 | IP 数据报的总长度(首部+数据区域) 因为该字段长为 16bit,所以整个 IP 数据报的理论最大长度为 65535 字节 |
标识 | 16 | 用于表示 IP 层发送出去的每一份 IP 数据报,在发送每一份报文,该值加 1。 在分片的时候,该字段会被复制到每个分片数据报中,在目标接收主机中,使用该字段判断这些数据是否属于同一个 IP 数据报。 |
标志 | 3 | 第一位保留未用; 第二位是不分片标志位,如果该位为 1,则表示 IP 数据报在发送的过程中不允许进行分片。(如果这个 IP 数据报的大小超过链路层能承载的大小,这个 IP 数据报将被丢弃,) 第三位:更多分片位,如果为 1 则表示该分片数据报不是整个 IP 数据报 的最后一个分片,如果为 0 则表示是整个 IP 数据报的最后一个分片。 |
分片偏移量 | 13 | 表示当前分片所携带的数据在整个 IP 数据报中的相对偏移位置(以 8 字节为单位),才能将分片进行重装为一个完整的 IP 数据报,并且重装 IP 数据报的依据就是分片的偏移量。 |
生存时间 | 8 | 该字段用来确保数据报不会永远在网络中循环。 每当 IP 数据报由一台路由器处理时,该字段的值减 1 若 TTL 字段减为 0,则该数据报必须丢弃,同时会返回一个 ICMP 差错报文给源主机,这样子数据就不会永远在网络中漂流而占据资源。 |
上层协议 | 8 | 该字段仅在一个 IP 数据报到达其最终目的地才会有用。 该字段的值指示了 IP 数据报的数据部分应交给哪个特定的传输层协议。 值为 6 表明数据部分要交给 TCP 值为 17 表明数据要交给 UDP 在 IP 数据报中的协议号所起的作用,类似于运输层报文段中端口号字段所起的作用。 - 协议字段是将网络层与运输层绑定到一起的粘合剂 - 端口号是将运输层和应用层绑定到一起的粘合剂 |
首部检验和 | 16 | 首部检验和用于帮助路由器检测收到的 IP 数据报首部是否发生错误 而对应 IP 数据报中的数据区域校验那是上层协议处理的事情 |
选项字段 | 0~40 | 不常用 |
数据区域 (也可以称之为有效载荷) |
IP 数据报中的数据字段包含要交付给目标 IP 地址的运输层。 数据区域也可承载其他类型的报文,如 ICMP 报文。 |
|
数据报在以太网帧上的封装
IP 数据报分片
一个主机打算发送 4000 字节的 IP 数据报(20 字节 IP 首部加上 3980 字节 IP 数据区域,
假设没有 IP 数据报首部选项字段),且该数据报必须通过一条 MTU 为 1500 字节的以太网
链路。这就意味着源始 IP 数据报中 3980 字节数据必须被分配为 3 个独立的数据报分片
(其中的每个分片也是一个 IP 数据报)。
假定初始 IP 数据报贴上的标识号为 666
- 那么第一个分片的数据报总大小为 1500 字节(1480 字节数据大小+20 字节 IP 数据报首部),分片偏移量为 0。
- 第二个分片的数据报大小也为 1500 字节,分片偏移量为 185(185*8=1480),
- 第三个分片的数据报大小为 1040(3980-1480-1480+20),分片偏移量为370(185+185)。
校验算法:https://blog.csdn.net/caozhigang129/article/details/82415698
发送端: 将发送的数据以两字节为单位进行补码相加,checksum处设置为0,得到32字节的数,再将底16位和高16位相加,结果求反,即为较验和。
接收端:和发送端相同的算法,checksum处使用发送端的结果进行补码相加,结果求反为0x0000,表明数据传输正确,否则数据传输不正确,舍弃。
static unsigned short chksum(void *dataptr, unsigned short len)
{
unsigned long acc;
unsigned short src;
unsigned char *octetptr;
acc = 0;
octetptr = (unsigned char*)dataptr;
while (len > 1)
{
src = (*octetptr) << 8; //2个字节结合
octetptr++;
src |= (*octetptr);
octetptr++;
acc += src;
len -= 2;
}
if (len > 0) //最后单个字节,补0,组成2字节
{
src = (*octetptr) << 8;
acc += src;
}
printf("acc=%x\n",acc);
if ((acc & 0xffff0000UL) != 0) //高16位 + 低16位
{
acc = (acc >> 16) + (acc & 0x0000ffffUL);
}
src = (unsigned short)acc;
printf("src=%x\n",src);
return ~src;
}