概述
IPv4
为上层协议提供无连接,无状态,不可靠的服务
- 无状态:IP通信双方不同步传输数据的状态信息,所以IP数据报的发送,传输和接收都是相互独立的,没有上下文关系 (IP模块无法处理IP数据报的乱序和重复,IP模块只要接收到完整的IP数据报就会发给上层协议模块)
- 无连接:IP通信双方都不长久的维持对方任何信息,(所以每次发送数据都要指出对方IP地址)
- 不可靠: IP协议不能保证IP数据报准确地到达接收端(只是best effort),发送端的IP模块检测到IP数据报发送失败就通知上层协议发送失败,并不会重传
IPv4头部结构
-
Version 4bit: IP版本号,IPv4 = 4
-
Header Length 4bit: IP头部有多少个4字节(32bit),
2^4-1=15,15*5=60Byte
,所以IP头部最长60Byte -
Type of Service 8bit: 服务类型TOS,8bit,前3bit弃用,中间4bit表示如下,最后1bit必须置0
4bit分别表示:最小延时,最大吞吐量,最高可靠性,最小费用
1000:最小延时
0100:最大吞吐量
0010:最高可靠性
0001:最小费用
3bit弃用+4bit类型+1bit0
4bit中最多只用1个可以置1,全0表示一般服务,ftp这种需要最大吞吐,ssh和telnet需要最小延时
-
Total Length: 16bit: 整个IP数据报的长度,所以IP数据报最大长度(
2^16-1=65535
字节),因为数据链路层MTU限制(现在一般都是以太网MTU=1500),长度超过MTU的数据报都将被分片传输 -
Identitfier 16bit: 唯一的标识主机发送的每一个数据报,由OS随机生成,同一个数据报的所有分片都具有相同标识值
-
Flags 3bit: 第1bit保留,第2bit
Don't Fragment DF
位=1表示禁止分片,如果此IP数据报长度超过MTU则IP模块将会丢弃并返回ICMP报文,第3bitMore Fragment MF
位=1表示更多分片,除了数据报最后一个分片外,其他分片此bit都=1 -
Fragmented offset: 13bit:分片位移,是分片相对于原始IP数据报开始处(数据部分)的偏移,实际值=该值左移3bit,所以偏移都是8的倍数,,那么除了最后一个分片外,其他分片的长度都是8的倍数
-
Time to live TTL: 8bit: 允许经过的路由器转跳次数,Win发送时TTL=64,Linux发送是TTL=128
-
Protocol: 8bit: 表示上层协议是谁:
/etc/protocols
可查看各上层协议,ICMP=1,TCP=6,UDP=17 -
Header CheckSum: 16bit: 仅校验数据报头部
到这里已经用了12Byte
-
Source Address: 32bit
:源IP地址 -
Destination Address: 32bit
目标IP地址到这里用了20Byte
-
Options
,剩下的40字节是可变长可选择信息
本实验的网络结构
虚拟机A和B都是Vmware的NAT网络模式
主机A IP:192.168.247.148
主机B IP:192.168.247.147
网关IP: 192.168.247.2
tcpdump实际查看一下包头部结构
sudo tcpdump -ntx -i lo #回环地址网卡
telnet 127.0.0.1
网络数据都是大端的,从头开始对应看
- 0x04: ipv4
- 0x05:4*5=20Byte,所以头部长20字节
- 0x10: 中间4bit:1000 标识最小延时(上层telnet需要最小延时服务)
- 0x3c:整个IP数据报长度=60字节
- 0x7239:整个IP数据报标识,每发送一个IP数据报值+1
- 0x40: TTL = 60
- 0x06: 表示上层协议是TCP协议(telnet基于tcp)
- 0xca70:校验和
- 0x7f000001:转化为点分十进制: 127.0.0.1
- 同上
每发送一个IP,id+1
IP分片
IP数据报长度超过数据链路层的MTU,将被分片传输,在IP层进行分片(网络层)
IP头部第2个4字节提供了分片的信息,
- 数据报标识
- 3bit分片flags
- 13bit数据偏移值
特点:
-
每个IP分片具有自己的IP头部,具有相同的标识值和不同的片偏移
-
除了最后一个分片,其他分片的flags=MF
-
每个分片的IP头部的总长度字段将被设置为该分片的长度
ifconfig
查看mtu
不被分片的话IP数据报的数据部分长度最长是1480字节(IP头部20字节),构造一个数据部分长度为1481字节的数据报来查看如何分片
用ICMP来封装一个1481字节的ICMP报文,ping命令使用的ICMP回显和应答报文头部长度是8字节,则构造数据长度是1473字节的ICMP数据就行
sudo tcpdump -ntv -i ens33 icmp
#只抓ICMP报文
ping -s 1473 192.168.247.148
#在主机B向我ping,并且指定ICMP数据包的数据长度
- 2个ip分片的id相同,
- 第二个分片的offset=第一个分片的数据长度,
- 第一个分片的flags = MF = flags[+]
- 第一个分片长度1500,第二个分片长度=21字节
分片图解
IP模块工作大概流程
接收来自数据链路层IP数据报,
- 对数据报头部做CRC校验
- 判断是否发送给自己(或者是广播地址),是就给上层协议的模块
- 不是就根据路由表转发,如果OS配置不允许转发的话就丢弃
路由表大概机制
查看路由表
- default:默认路由项,网关地址这里没显示,在这实验的网络结构是192.168.247.2, G标识下一跳目标是Gateway网关,网卡是ens33
- 192.168.247.0+子网掩码255.255.255.0:表示可以直接发送此网段的所有主机192.168.247.*
匹配规则:
- IP数据包目标地址完全匹配路由表中目的IP地址
- 上面的第二项,属于同一网段
- 选择默认路由项
路由表更新
如下例子
-
在主机A上添加对主机B的路由
sudo route add -host 192.168.247.147 dev ens33
-
删除上面route表的第二项
sudo route del -net 192.168.247.0 netmask 255.255.255.0
-
删除default
sudo route del default
注意此时我们就无法连接internet了
-
将主机B作为默认网关
sudo route add default gw 192.168.247.147 dev ens33
此时还是不能连接上Internet (原因下面讲)
IP转发
为什么主机A访问Internet的IP包发给网关(主机B)后不能上网呢,
回顾IP模块处理流程:判断是否发送给自己,这里不是,然后让转发模块来处理,根据OS配置来判断是否转发,那么A访问不了Internet的原因可能是主机B并没有转发主机A的包
主机一般只接收和发送数据报
开启主机B的IP转发功能:
sudo -s
echo 1 > /proc/sys/net/ipv4/ip_forward
然后在主机A,访问Internet,
ping www.baidu.com
这里返回了ICMP重定向报文,告诉主机此IP数据报更应该使用哪一个路由器来转发,并且更新此主机(主机A)的路由表
为什么主机A把主机B作为网关(把包发给B)不是最优路由路径,因为主机A和B都要通过网关192.168.247.2来访问Internet)
- 一般来说主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文 (可设置)
参考 <<Linux高性能服务器编程>>
最后
以上就是还单身树叶为你收集整理的IPv4协议详解的全部内容,希望文章能够帮你解决IPv4协议详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复