Network Layer
Last updated
Last updated
互联网控制消息协议(Internet Control Message Protocol,ICMP)用于网际协议(IP)中发送控制消息,提供可能发生在通信环境中的各种问题反馈。通过这些信息,使管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。
ICMP 有很多类型,最常用的类型是主动请求为 8,主动请求的应答为 0。
主动发起的类型。比如 ping 就是查询报文,是一种主动请求,并且获得主动应答的 ICMP 协议。
ping 的主动请求,称为 ICMP ECHO REQUEST,主动请求的回复,称为 ICMP ECHO REPLY。
异常情况发起,报告发生了不好的事。比如:终点不可达为3,源抑制为4,超时为11,重定向为5。
Traceroute 故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。
Traceroute 的参数指向某个目的 IP 地址,它会发送一个 UDP 的数据包。将 TTL 设置成 1,然后依次累加,直到到达目的主机,所以就能拿到所有的路由器 IP。
IP 地址被点分割为四个部分,每部分 8bit,所以 IP一共是 32 位。IPV6 有 128 位,比如 fe80::f816:3eff:fec7:7975/64 。
每个 IP 地址又包括了主机号和网络号两部分。相同网络号的主机组成一个子网;不同子网再通过路由器连接,组成一个庞大的网络。
无类别域间路由(Classless Inter-Domain Routing、CIDR)将 32 位的IP 地址一分为二,前面是网络号,后面是主机号。X.X.X.X/A,意思是 32 位中,前 A 位是网络号,后 32 - A 位是主机号。10.126.6.255 是广播地址(一旦发送这个地址,10.126.6 网络里面的所有机器都可以收到),255.255.255.0 是子网掩码。将子网掩码与 IP 地址进行 AND 计算,就得到网络号。
例如,求 16.158.165.91/22 的第一个地址、子网掩码、广播地址。可以这么拆解:16.158.<101001>.<01>.91。第一个地址是16.158.<101001>.<00>.1,即16.158.164.1。子网掩码是 255.255.<111111>.<00>.0,即255.255.252.0。广播地址为 16.158.<101001>.<11>.255,即16.158.167.255。
在 Windows 中通过 ipconfig
查看 IP,在 Linux 中通过 ifconfig
(net-tools)或ip iddr
(iproute2)查看。
ip addr 会显示所有的网卡,网卡可以有 IP 地址,也可以没有。上面输出 10.126.6.109 就是一个 IP 地址。
在 IP 地址的后面有个 scope,对于 eth0 这张网卡来讲,是 global,说明这张网卡是可以对外的,可以接收来自各个地方的包。对于 lo 来讲,是 host,说明这张网卡仅仅可以供本机相互通信。
在IP地址的上一行是 link/ether 00:16:3e:0e:33:97 brd ff:ff:ff:ff:ff:ff,这个被称为MAC地址,是一个网卡的物理地址,用十六进制,6个byte表示。MAC地址的通信范围比较小,局限在一个子网里面。
第一行的 <BROADCAST,MULTICAST,UP,LOWER_UP> 是 net_device flags,网络设备的状态标识。UP 表示网卡处于启动的状态;BROADCAST 表示这个网卡有广播地址,可以发送广播包;MULTICAST 表示网卡可以发送多播包;LOWER_UP 表示L1是启动的,也即网线插着呢。
mtu 1500 表示最大传输单元MTU为1500,这是以太网的默认值。
qdisc pfifo_fast 表示排队规则为 pfifo_fast。qdisc 全称是 queueing discipline。
最简单的 qdisc 是 pfifo,它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。
pfifo_fast 包括三个波段(band)。在每个波段里面,使用先进先出规则。
三个波段(band)的优先级不同,band 0 ~ 2 优先级依次降低。比如若 band 0 里面有数据包,系统就不会处理 band 1 里面的数据包。
数据包是按照服务类型(Type of Service,TOS)被分配到三个波段(band)里面的。TOS 是 IP 头里面的一个字段,代表了当前的包是高优先级的,还是低优先级的。
版本号:主流还是 IPv4
TOS 见上文
TTL 见 ICMP
协议:指 TCP 还是 UDP
在进行网卡配置的时候,除了IP地址,还需要配置一个 Gateway 的东西,这个就是网关。Gateway 的地址一定是和源 IP 地址是一个网段的。
Linux默认的逻辑是,如果是一个跨网段的调用,它便不会直接将包发送到网络上,而是企图将包发送到网关。也就是说如果你配置了网关,Linux 会获取网关的 MAC 地址,然后将包发送出去。
不改变 IP 地址的网关。包到达网关后,源 MAC 变成网关出口的 MAC,目标 MAC 变成下一跳网关的 MAC 或目标 IP 的 MAC;源 IP 和目标 IP 不变。
如图 A 访问 192.168.56.2,A 配置了网关 192.168.1.1,通过 ARP 获取其 MAC:
源 MAC:服务器 A 的 MAC
目标 MAC:192.168.1.1 这个网口的 MAC
源 IP:192.168.1.101
目标 IP:192.168.56.2
路由器 A 配置了静态路由,要想访问192.168.56.2,要从 192.168.56.1 这个口出去,没有下一跳:
源 MAC:192.168.56.1 的 MAC 地址
目标 MAC:192.168.56.2 的 MAC 地址
源 IP:192.168.1.101
目标 IP:192.168.56.2
NAT (Network Address Translation)网关:改变 IP 地址(源和目标)的网关。MAC 地址的行为和转发网关是一致的;源 IP 和目标 IP 通过配置的 NAT 修改。NAT 可以分为三类:
静态 NAT,内网 IP 与公网 IP 是一对一的映射关系。
动态 NAT,内网 IP 从公网 IP 池中动态选一个映射。
网络地址端口转换 NAPT(Network Address and Port Translation),内网 IP 映射到公网 IP 的不同端口,多个内网 IP共享同一个公网 IP。又可以分为三类:
SNAT,仅替换源 IP 或端口。主要用于内网多个 IP 共享一个公网 IP 来访问外网资源。
DNAT,仅替换目标 IP 或端口。主要用于公网 IP 通过不同端口号来访问内网资源,屏蔽真实 IP。
双向地址转换。主要用于公网 IP 与内网 IP 一一对应,在虚拟环境中为虚拟机分配浮动的公网 IP。
如图,A 访问 192.168.56.2。A 配置了网关 192.168.1.1,通过 ARP 获取其 MAC 地址:
源 MAC:A的 MAC
目标 MAC:192.168.1.1 的 MAC
源IP:192.168.1.101
目标IP:192.168.56.2
包到达路由器 A 后,路由器 A 配置了静态路由:要想访问 192.168.56.2/24,要从 192.168.56.1这个口出去,没有下一跳。路由器 A 发送 ARP 获取 192.168.56.2 的 MAC:
源 MAC:192.168.56.1 的 MAC 地址
目标 MAC:192.168.56.2 的 MAC 地址
源 IP:192.168.56.1
目标 IP:192.168.56.2
路由器 B 配置了 NAT 网关:
源 MAC:192.168.1.1 的 MAC 地址
目标 MAC:192.168.1.101 的 MAC 地址
源 IP:192.168.56.1
目标 IP:192.168.1.101
关于 NAT 的具体应用可见操作系统-NAT。
网关往往是一个路由器,是一个三层转发的设备,它有五个网口或者网卡,分别连着五个局域网。每个口的 IP 地址都和局域网的 IP 地址相同的网段,每个口都是对应局域网的网关。
任何一个想发往其他局域网的包,都会到达其中一个口,拿下 MAC 头和 IP 头,根据路由算法,选择另一个口,加上 IP 头和 MAC 头再发出去。
路由种类:
静态路由:路由项(routing entry)手动配置。
动态路由:根据路由协议算法生成动态路由表,随网络运行状况的变化而变化。本质是最短路径算法,比如 Bellman-Ford、Dijkstra。
路由规则包括:
目的网络
出口设备
下一跳网关
通过 route 命令和 ip route 命令都可以进行查询或者配置。核心思想:根据目的 IP 地址来配置路由。
例如ip route add 10.176.48.0/20 via 10.173.32.1 dev eth0
意思是 10.176.48.0/20 这个目标网络,要从 eth0 端口出去,经过 10.173.32.1。
除了可以根据目标 IP 来配置路由外,还可以根据多个参数配置路由,称为策略路由。可以配置多个路由表,根据源 IP、入口设备、TOS 等选择路由表。
距离矢量路由(distance vector routing)是基于 Bellman-Ford 算法。
基本思路:每个路由器都保存一个路由表,每行对应网络中的一个路由器,每一行包含两部分信息,一个是要到目标路由器,从那条线出去,另一个是到目标路由器的距离。
每个路由器都知道自己和邻居之间的距离,每个路由器都将自己所知的到达所有的路由器的距离告知邻居,每个路由器也能从邻居那里得到相似的信息。
问题:
添加路由器很快能被广播,但是路由器下线很久才能被知道。
每次发送都需要发送整个全局路由表。所以适用于小型网络(小于 15跳)。
链路状态路由(link state routing)是基于 Dijkstra 算法。
基本思路:当一个路由器启动的时,发现邻居,发送一个 echo,立即返回,除以二就是距离。然后将自己和邻居之间的链路状态包广播出去,发送到整个网络的每个路由器。这样每个路由器都能够收到它和邻居之间的关系的信息。因而,每个路由器都能在自己本地构建一个完整的图,然后针对这个图使用 Dijkstra 算法,找到两点之间的最短路径。
优点:
每次广播都只发送改变的网络拓扑。
路由器下线,它的邻居都会广播这个消息,很快就能被知道。
OSPF(Open Shortest Path First,开放式最短路径优先)是一个基于链路状态路由协议,多用在数据中心内部,用于路由决策,因而称为内部网关协议(Interior Gateway Protocol,简称IGP)。
有时候 OSPF 可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由。
边界网关协议(Border Gateway Protocol,BGP)是基于距离矢量路由算法。
BGP 分为两类,eBGP 和 iBGP。
BGP 协议使用的算法是路径矢量路由协议(path-vector protocol)。它是距离矢量路由协议的升级版。
类别
A 类
0
网络号(7位)
主机号(24位)
B 类
1
0
网络号(14位)
主机号(16位)
C 类
1
1
0
网络号(21位)
主机号(8位)
D 类
1
1
1
0
多播组号(28位)
E 类
1
1
1
1
0
留待后用(27位)