网络层
IPv4
IPv4地址
早期地址分类
最早的IP地址被划分为五类,ABCDE
根据前缀区分
A类地址的网络地址占一个字节
整个IP地址空间的一半都是A类地址
B类地址的网络地址占两个字节
整个IP地址空间的四分之一是B类地址
其中A,B,C类网络地址是私有地址
特殊IP地址
网络号 | 主机号 | 源地址使用 | 目的地址使用 | 意义 |
---|---|---|---|---|
0 | 0 | 可以 | 不可 | 默认路径地址0.0.0.0, 本网络上的本主机 |
0 | host-id | 可以 | 不可 | 本网络上的某个主机 |
全1 | 全1 | 不可 | 可以 | 广播地址255.255.255.255, 只在本网络上广播(路由器不转发) 范围局限在LAN中,即同一子网掩码的网段内 |
net-id | 全1 | 不可 | 可以 | 特定子网的广播地址, 对net-id上所有主机广播 |
127 | 非全0或全1的数 | 可以 | 可以 | 用作本地软件环回测试 |
169.254 | 0 | 可以 | 可以 | 主机无法获取IP地址时 会自动配置地址169.254.x.x/16, 使其可以通信 |
多级IP地址
早期的网络地址=网络号+主机号
然而这种划分有很多浪费,于是引入三级IP地址
网络地址=网络号+子网号+主机号
只需要给大组织分配一个A或者B类地址,然后该组织自己划分子网号即可
只看IP地址是看不出有没有划分过子网的
这就是子网掩码的作用了
子网掩码"掩"住的是子网前缀,比如255.255.255.0这个子网掩码,它表明只有IP地址的最后一个字节才是主机号,前面的是网络号和子网号.
\[ 网络地址(原网络地址+子网地址)=IP地址 按位与 子网掩码 \]
192.168.1.0这是网络地址
192.168.1.255这是子网的广播地址
192.168.1.[1,254]这是可以给主机分配的IP地址
子网掩码和网关
一个计算机尝试访问另一个IP地址时,会进行如下计算:
自己的IP地址和自己的子网掩码按位与得到自己的网络地址
目标的IP地址和自己的子网掩码按位与,结果与自己的网络地址比较
如果相同说明目标计算机是"网上邻居",同处于一个子网内,则链路层帧的目的MAC地址就会填写该目标计算机的MAC地址.如果不知道邻居的MAC地址,会使用ARP协议,根据邻居的IP地址,查邻居的MAC地址
如果不同说明目标不在同一子网内,需要访问"外面的世界".这就需要网关转发,于是将链路层目的MAC地址填上网关的MAC地址.
如何获取网关的MAC地址?
这台计算机是有网关的IP地址的,不管是手动填上的还是DHCP获取的,反正就是有
然后本计算机通过ARP协议,根据网关的IP地址询问网关的MAC地址
这就存在一种单向通的情况:
192.168.3.4/16可以往192.168.1.1/24发包,并且可以被收到
但是192.168.1.1/24无法向192.168.3.4/16发包,
因为PC1@192.168.1.1经过计算,192.168.3.4是一个外网地址,但是自己没有设置网关,因此不知道应该把包发给谁
可变长子网掩码VLSM
地址划分举例
分配给某一小型组织机构一个地址块,我们已知块中一个地址是205.16.37.39/28,求该块的起始地址?
网络前缀有28位,这就意味着IP地址的前三个字节都是固定死的205.16.37,最后这个字节的高四位是固定死的
39=0010'0111b,那么起始地址应该是0010'0000b,也就是32
因此这个网络块的起始地址是205.16.37.32
块的起始地址一般不会分配,作为网络地址
块的最后地址也不会分配,作为本块的广播地址
已给一个组织分配了17.12.14.0/26的地址块,该组织有3个部门,需要划分为32、16和16个地址的子块。
17.12.14.0/26这个地址空间里有\(2^{32-26}=64\)个地址,恰好划分为32+16+16
因此可以这样划分:
172.12.14.00'100000/27,即172.12.14.32/27
172.12.14.00'010000/28,即172.12.14.16/28
172.12.14.00'000000/28,即172.12.14.0/28
某单位分配到一个 B 类 IP 地址,其net-id为129.250.0.0。
该单位有4000台机器,平均分布在16个不同的地点。
如选用子网掩码为255.255.255.0,试给每一地点分配一个子网号码,
并计算出每个地点主机号码的最小值和最大值。
4000台机器均分到16个地点,则每个地点有250台,一个/24子网中最多有256-2=254台
因此一个255.255.255.0子网可以容纳250台机器
只需要将129.250.0.0/16这样划分:
子网号(Binary) 子网号(Decimal) 网络地址 主机IP地址范围 00000000 0 129.250.0.0/16 129.250.0.1~129.250.0.254 00000001 1 129.250.1.0/16 129.250.1.1~129.250.1.254 00000010 2 129.250.2.0/16 129.250.2.1~129.250.2.254 00000011 3 129.250.3.0/16 129.250.3.1~129.250.3.254 ... 00001111 15 129.250.15.0/16 129.250.15.1~129.250.15.254
NAT地址转换
NAT类型 | 映射关系 | |
---|---|---|
静态NAT | 一个内网地址对应一个公网地址 | |
动态NAT | 多个内网地址对应多个公网地址 | |
PAT | 多个内网地址对应一个公网地址的多个端口号 |
IPv4包
Data用于承载运输层的协议,比如TCP,UDP
Header是IPv4数据报首部,其中Option为可选项,除此之外的前20个字节是固定的
VER
4bits
IP协议的版本号,目前只有4和6两种,代表IPv4,IPv6
两种IP协议的首部有区别,但是接收方只要是看到这个VER字段,就可以决定后面用IPv6还是IPv4协议来解释后面的数据报了
HLEN
4bits
由于存在Option这个变量,为了区分首部和数据,需要维护一个值,记录IPv4数据报的首部共有多少字节.这个值就放在HLEN字段,共4位,最大是15,单位是4字节,也就是说,IPv4首部最大可以是15*4=60字节,即Option最大是40字节
由于首部最小是20字节,因此HLEN这个值最小是5
SERVICE
8bits
要么表示服务类型
要么表示区分服务
服务类型
用于获得更好的服务
注意服务类型不是高层协议类型
运输层上使用的是TCP还是UDP等等,是由Protocol字段决定的
用于描述上层(运输层)的服务类型,
前3bits用于描述优先级
后1bits不使用
中间4bits,DTRC,用于描述服务类型
差分服务
前6bits是码点子字段,后面2bits不用
其中码点的不同组合有不同的意义
Total Length
16bits
总长度,len(header + data),单位,字节
最大长度不超过\(2^{16}=65536bytes\)
又总长度不能超过链路层规定的最大传送单元MTU,以太网(正在使用的局域网规范)该值默认是1500字节
以太网链路层帧限制上层的数据报长度在46~1500字节之间,不够46字节需要填充
也就是说链路层的协议,其Header到Trailer之间的空间有限,最大是MTU规定的大小,IP数据报必须尊重地域差异,入乡随俗
Identification
16bits
一段数据由于MTU的限制,可能要分成多个包发送,本字段用来表明哪些包是同一个文件的.
Flags
3bits
标志,用于标识该数据报是否可以分片,如果分片,是不是最后一片
最前面一个bit不用
中间一个bit是MF位,表征是否还有分片,1则还有分片,0则表明该数据报是最后一个分片
最后一个bit是DF位,表征是否可以分片,1不能分片,0允许分片
reserved | MF | DF |
---|
Fragmentation Offset
13bits
分片偏移,对于同一个包的分片,
指出较长的分组在分片后,其中一片在原分组中的编号.单位:8字节 \[ 分片偏移=IP数据的第一个字节编号/8 \]
\(8\times 2^{13}=2^{16}=65536bytes\)
本机在10.177.148.9,使用ICMP协议给61.150.43.78发送3500个字节的数据
1 >ping www.xidian.edu.cn -l 3500其中一组ping-pong应答:
去的包有三个,分别长1514,1514,587字节
为啥可以比mtu=1500多?因为这是整个数据报的总长度,包括了链路层的头
前两个总长度1514字节的包,实际上IPv4数据报就是1500字节,其中IPv4首部占用了20字节
Time to live
8bits
生存时间TTL,用于表示最大跳数,即该包还可以通过多少个路由器转发
为了防止数据报在网络上无休止地被转发而占用资源.路由器在转发每个数据报之前,都会首先将其TTL减一,如果降为0,则丢弃该数据报,不再转发
Protocol
8bits
协议类型,用于表示上层使用的协议,也就是data中存放的是啥协议的数据报
常用的协议编号如下
Header checksum
16bits
首部检校和,咋算的呢?
这里的首部包含Option字段,并且首部一定是4字节对齐的,Option如果不是4字节的倍数则向上取整到4字节的倍数
计算方式:
需要注意的是发送方最终填写的Check Sum是校验和计算值的反码
接收方也是将校验和计算结果取反检查是否是全零
比如
Source/Destination IP address
分别是32bits,源和目的主机的IP地址
Option
可以没有,最大40字节
首部附加选项
IPv6
IPv6地址
长128位
懒人表示法:
全零的段可以只写一个0
连续的全零段可以用一个Gap代替,全零段之间的冒号可以省去了.但是一个IPv6地址中只能有一个Gap
为啥只能有一个GAP?看看如何还原
带有Gap的地址如何还原?
IPv6包
IPv6头部包括固定40个字节的基础头部和可变长度的拓展头部,拓展头部的长度会在基础头部中给出
Base Header
字段 | 作用 | 长度(bit) |
---|---|---|
Version | IPv6版本 | 4 |
Traffic Class | 优先级,发生拥塞时分组的优先级 | 4 |
Flow Label | 流标号,类似于之前的Identification | 24 |
Payload Length | 有效载荷长度,即拓展头+IP数据的长度,单位:字节 | 16 |
Next Header | 指明上层协议,类似于Protocol | 8 |
Hop Limit | TTL | |
Source/ Destination Address |
源/目的地址 | 128/128 |
IPv4向IPv6过渡
三种过渡方法:
过渡方法 | 原理 |
---|---|
双协议栈 | |
隧道 | |
头转换 |
ARP
数据报
Hardware Type
16bits
链路层协议类型,以太网为1
Protocol Type
16bits
网络层协议类型,IP协议为0x0800
Hardware length
8bits
物理地址长度,比如以太网的物理地址,即MAC地址的长度就是6字节
Protocol length
8bits
逻辑地址长度,比如IPv4地址的长度就是4字节
Operation
16bits
ARP分组类型,有两种,Request请求或者Reply应答
四个地址
接下来是四个地址,依次是发送方的物理地址,发送方逻辑地址,接收方硬件地址,接收方逻辑地址
抓包观察
如图拓扑中
A@192.168.1.251试图ping B@192.168.1.250
在A的Ethernet0网卡上抓包
会发现首先发送和接受的并不是ICMP报文,而是arp报文,因为此时A计算机并不知道B@192.168.1.250的物理地址是多少.因此首先要问一下
第20帧,A向子网发送ARP广播,其报文中包括自己的物理地址,逻辑地址,目的地的逻辑地址,但是目的地址的物理地址是一个假值
第21帧,A接收到了B的单播回答
此时两个主机的物理地址,逻辑地址都已经填好了
ICMP
internet control message protocol 因特网控制协议,网络层协议
ICMP是网络层的协议,但是其在数据帧中的位置类似于TCP数据报的位置,都是在IPv4的data位置
报文格式
Type
ICMP报文分成差错报告和查询两种,体现在Type上
对于差错报告报文:
对于查询报文:
Code
代码要视报文类型决定
Checksum
校验和
差错报告报文
1 | ❏ 对于携带ICMP差错报文的数据报,不再生产ICMP差错报文。 |
差错报文数据字段:
差错报告类型 | 作用 | |
---|---|---|
目的端不可达 | 路由器无法路由或者目的主机无法传递数据时,报告目的端不可达 | |
源端抑制 | 配合流量控制使用 路由器或者目的主机发生拥塞时,丢弃数据包,发送源端抑制 |
|
时间超时 | TTL减为0时,路由器丢弃 或者报文的部分分片没有在有限时间抵达目的主机,由目的主机发送 |
|
参数问题 | IP分组首部错误 路由器或者目的主机丢弃分组并发送参数问题报文 |
|
重定向 | 向源端报告更好的路由 |
查询报文
查询报文类型 | 作用 | |
---|---|---|
回送请求和回答 | 诊断网络 | ping |
时间戳请求和回答 | 确定数据报往返时间,同步 | |
地址掩码请求和回答 | 获取地址对应掩码 | |
路由器询问和通告 | 询问路由器是否正常工作 | tracert |
tracert
DHCP协议
DHCP,Dynamic Host Configuration Protocol,动态主机地址分配协议
其前身是BOOTP(bootrap prottocol),引导程序协议,DHCP兼容BOOTP的功能
DHCP服务器有一个地址池,存放DHCP服务器可以动态分配的所有地址
DHCP工作过程
DHCP握手分为四步,主机要离开子网的时候,只有一步
DHCP报文类型 | 时机 | 方向 | 作用 |
---|---|---|---|
Discover | client刚加入子网,试图索要一个ip地址 | DHCP client--广播->DHCP servers | 向所有DHCP server索要ip地址 |
Offer | DHCP server收到了DIscover之后 | DHCP server--单播-->DHCP client | 所有DHCP服务器都会尝试给出一个可用的ip地址 |
Request | client收到Offer之后 | DHCP client--广播-->DHCP servers | client接受其中一个offer,谢绝其他offer |
ACK | 被接受offer的server收到Request之后 | DHCP server--单播-->DHCP client | 被接受offer的server回复收到 |
Release | client将要离开子网之时 | DHCP client--广播-->DHCP servers | 通知所有DHCP server,本client要放弃ip地址了,可以收回到ip地址池 |
其中四次握手同属于一个Transaction
路由协议
路由
路由:从某一网络设备发出,去往某个目的地,经过的路径
终端计算机,路由器,三层交换机上存在路由表
二层交换机上只有arp表
根据路由的发现方式,路由可以分成三种
直连路由:路由器自主发现相连端口的网络的路由
静态路由:人工维护路由表
动态路由:可周期性更新
路由表
子网掩码
网络地址
下一跳地址
朝向下一跳的端口
比如网络拓扑长这样
其中R1路由表长这样
如果图22.6中的一个目的地址为180.70.65.140的分组到达路由器R1,说明其转发过程。
180.70.65.140这个地址属于180.70.65.128/25网段,因此应该从m0口出去
首先路由器会在180.70.65.128/25网段中使用ARP协议获得下一跳的MAC地址,然后将IP分组转发给下一跳
netstat -r
在win或者linux主机上使用netstat -r命令即可查看本机的路由表
比如
1 | ┌──(root㉿Executor)-[/mnt/c/Users/86135] |
栏目 | Destination | Gateway | Genmask | Flags | MSS Window | irtt | Iface |
---|---|---|---|---|---|---|---|
意义 | 目的地址 | 网关 | 目的地址掩码 | 目标端口 |
在eNSP路由器上用display ip routing-table也可以查看该路由器的路由表
1 | [Huawei]display ip routing-table |
两者的主要区别就是这个NextHop
主机的网卡不需要下一跳地址,只需要维护一个网关的地址
路由器需要维护下一条的地址
最长掩码匹配
从路由表中选择具有最长掩码的路由
掩码越长,地址块越小,路由越具体
假如R2路由器收到了一个目的地址为140.24.7.192的地址,
该目的地址即属于140.24.7.192/26网段,
又属于140.24.7.0/24网段,
应该发往最长具有掩码的网段,即140.24.7.192/26
地址聚合
默认路由
默认路由就这种
子网掩码是0,意味着默认路由在路由表中排在最后,也就是最后的选择.
只要是前面都失配的包都会从默认路由这里匹配成功.该条记录只需要记录从本路由器中的哪个端口出去,下一条是谁
比如这里的B路由器,除了10.1.0.0/24,其他的包只能发往C路由器,于是B->C这条路由就是B的默认路由
路由协议优先级
直连路由的优先级最高,因为 其最可靠
IP路由表为路由器实际工作时使用的路由表
建立该表的过程中可能考虑了很多路由协议,比如RIP,OSPF,对于同一个Destination的路由记录,优先使用高优先级路由协议给出的路由记录
比如之类对于24.10.0/24这个地址,RIP和OSPF两种协议给出了不同的下一跳,必然有优劣.由于OSPF协议的优先级高,最终写入IP路由表的,来自OSPF协议
路由算法
dijkstra
边权是链路代价,两节点不连接时链路代价为无穷大
符号约定:
符号 | 意义 |
---|---|
T | 已经"拓展"的节点集合 |
N | 网络中的节点集合 |
s | 源点 |
w(i,j) | 从i到j节点的链路代价 |
L(i) | 目前从源点s到i节点的最小代价 |
以1号节点为起点,计算其与其他所有点的最短距离
计算过程:
Iter | T | L(2) | Path | L(3) | Path | L(4) | Path | L(5) | Path | L(6) | Path |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | {1} | 2 | 1-2 | 5 | 1-3 | 1 | 1-4 | ∞ | - | ∞ | - |
2 | {1,4} | 2 | 1-2 | 4 | 1-4-3 | 1 | 1-4 | 2 | 1-4-5 | ∞ | - |
3 | {1, 2, 4} | 2 | 1-2 | 4 | 1-4-3 | 1 | 1-4 | 2 | 1-4-5 | ∞ | - |
4 | {1, 2, 4, 5} | 2 | 1-2 | 3 | 1-4-5-3 | 1 | 1-4 | 2 | 1-4-5 | 4 | 1-4-5-6 |
5 | {1, 2, 3, 4, 5} | 2 | 1-2 | 3 | 1-4-5-3 | 1 | 1-4 | 2 | 1-4-5 | 4 | 1-4-5-6 |
6 | {1, 2, 3, 4, 5, 6} | 2 | 1-2 | 3 | 1-4-5-3 | 1 | 1-4 | 2 | 1-4-5 | 4 | 1-4-5-6 |
bellmanford
\(L_h(i)\)从源点到i点,最多经过h条链路时,最小链路代价和
计算过程
h | \(L_h(2)\) | Path | \(L_h(3)\) | Path | \(L_h(4)\) | Path | \(L_h(5)\) | Path | \(L_h(6)\) | Path |
---|---|---|---|---|---|---|---|---|---|---|
0 | ∞ | - | ∞ | - | ∞ | - | ∞ | - | ∞ | - |
1 | 2 | 1-2 | 5 | 1-3 | 1 | 1-4 | ∞ | - | ∞ | - |
2 | 2 | 1-2 | 4 | 1-4-3 | 1 | 1-4 | 2 | 1-4-5 | 10 | 1-3-6 |
3 | 2 | 1-2 | 3 | 1-4-5-3 | 1 | 1-4 | 2 | 1-4-5 | 4 | 1-4-5-6 |
4 | 2 | 1-2 | 3 | 1-4-5-3 | 1 | 1-4 | 2 | 1-4-5 | 4 | 1-4-5-6 |
动态路由协议
动态路由协议的目的:
知道有哪些邻居路由器;
能够学习到网络中有哪些网段;
能够学习到至某个网段的所有路径;
能够从众多的路径中选择最佳的路径;
能够维护和更新路由信息。
自治系统
每个自治系统内部使用一套相同的路由协议,同级的自治系统使用同一套路由协议,自治系统可以嵌套自治系统
每个自治系统都要分配一个AS号,用于路由
本级自治系统只负责将本级的IP分组发往本级目标自治系统,剩下具体发往目标AS中的哪一台主机,由该AS内部的路由协议自己决定
RIP on 距离向量算法
RIP协议基于距离向量协议
RIP协议中的距离或者说代价,就是跳数
Distance vector,距离向量算法
每个节点都有一个
初始化
最初的拓扑中,每个路由器都只知道与自己直连的路由器.其路由表中只有这些路由器的信息
比如D实际上式不知道B的存在的,它只知道A的存在.上图中的D的路由表中画出 BCE,但是距离是\(\infin\),就相当于不知道它的存在
共享路由信息&距离向量更新
周期共享
每个结点都会将自己知道的所有都告诉邻居
这里C共享给A的所有信息都要代价+2,这是AC之间的边权
C发往A的所有信息,其Next都是C,意思是,如果A需要使用该表中的一些信息,一定是C的贡献,届时A会以C作为下一跳发送相应数据包
A的老路由表和加上AC边权代价之后的C共享表进行比较,每一条路由都取Cost最小值,得到新路由表
缺点:
两个节点的不稳定性
当A与X之间的链路断开后,A到X的距离成为无穷大,如果因为丢包等原因,A没有及时通知B,X已经断开了,那么B就一直认为B->A->X这条链路正常.当B给A交换路由信息的时候,A又认为B还有其他通路到X(实际上就是之前的链路).于是A有到X的包就会发往B,B又发往A,A又发往B...
三个节点的不确定性:
X已经不和ABC连接了,A一开始也是知道X已经离开的,但是经过共享后,ABC都糊涂了
基于距离向量的RIP协议
就是将链路代价换成跳数
OSPF on 链路状态路由选择算法
链路状态:
每个节点都知道一些链路信息,比如链路代价,连接状态
每个节点都会字节建立一张路由表,通过洪范向其他节点广播状态
每个节点自己构建一个最短路径树,并以此构建路由表
最短路径树: