1 IP基础知识

1.1 IPv4地址分类

主机号全0或者全1有特殊意义:

  • 全0:指定某个网络
  • 全1:指定某个网络下全部主机

1.2 无分类地址CIDR

表示形式 a.b.c.d/x,其中 /x 表示前 x 位属于网络号,x 的范围是 0 ~ 32,这就使得 IP 地址更加具有灵活性。

还有另一种划分网络号与主机号形式,那就是子网掩码,掩码的意思就是掩盖掉主机号,剩余的就是网络号。

1.3 公有IP地址和私有IP地址

公有 IP 地址是有个组织统一分配的,假设你要开一个博客网站,那么你就需要去申请购买一个公有 IP,这样全世界的人才能访问。

1.4 IPv6

IPv4 的地址是 32 位的,大约可以提供 42 亿个地址,但是 IPv6 的地址是 128 位的。

  • IPv6 可自动配置,即使没有 DHCP 服务器也可以实现自动分配IP地址,便捷到即插即用
  • IPv6 包头包首部长度采用固定的值 40 字节,去掉了包头校验和,简化了首部结构,减轻了路由器负荷,大大提高了传输的性能
  • IPv6 有应对伪造 IP 地址的网络安全功能以及防止线路窃听的功能,大大提升了安全性

1.5 IPv4和IPv6首部

2 相关协议

2.1 DNS

将域名网址自动转换为具体的 IP 地址,域名的层级关系类似一个树状结构:

  • 根 DNS 服务器
  • 顶级域 DNS 服务器(com)
  • 权威 DNS 服务器(server.com)

2.2 ARP

在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就会通过主机「路由表」确定 IP 数据包下一跳。网络层的下一层是数据链路层,所以我们还要知道「下一跳」的 MAC 地址。ARP 是借助 ARP 请求与 ARP 响应两种类型的包确定 MAC 地址的。

  • 主机会通过广播发送 ARP 请求,这个包中包含了想要知道的 MAC 地址的主机 IP 地址。
  • 当同个链路中的所有设备收到 ARP 请求时,会去拆开 ARP 请求包里的内容,如果 ARP 请求包中的目标 IP 地址与自己的 IP 地址一致,那么这个设备就将自己的 MAC 地址塞入 ARP 响应包返回给主机。
  • 操作系统通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。MAC 地址的缓存是有一定期限的,超过这个期限,缓存的内容将被清除。
RARP

ARP 协议是已知 IP 地址求 MAC 地址,那 RARP 协议正好相反,它是已知 MAC 地址求 IP 地址。例如将打印机服务器等小型嵌入式设备接入到网络时就经常会用得到。

通常这需要架设一台 RARP 服务器,在这个服务器上注册设备的 MAC 地址及其 IP 地址。然后再将这个设备接入到网络,接着:

  • 该设备会发送一条「我的 MAC 地址是XXXX,请告诉我,我的IP地址应该是什么」的请求信息。
  • 该设备会发送一条「我的 MAC 地址是XXXX,请告诉我,我的IP地址应该是什么」的请求信息。

最后,设备就根据从 RARP 服务器所收到的应答信息设置自己的 IP 地址。

2.3 DHCP

DHCP 客户端进程监听的是 68 端口号,DHCP 服务端进程监听的是 67 端口号。

  • 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将帧广播到所有的网络中设备。
  • DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期
  • 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 **DHCP 请求报文(DHCP REQUEST)**进行响应,回显配置的参数。
  • 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。

如果租约的 DHCP IP 地址快期后,客户端会向服务器发送 DHCP 请求报文:

  • 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延长租期。
  • 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。

可以发现,DHCP 交互中,全程都是使用 UDP 广播通信

2.4 NAT

IPv4 的地址是非常紧缺的,在前面我们也提到可以通过无分类地址来减缓 IPv4 地址耗尽的速度,但是互联网的用户增速是非常惊人的,所以 IPv4 地址依然有被耗尽的危险。

简单的来说 NAT 就是同个公司、家庭、教室内的主机对外部通信时,把私有 IP 地址转换成公有 IP 地址。

这种转换表在 NAT 路由器上自动生成。例如,在 TCP 的情况下,建立 TCP 连接首次握手时的 SYN 包一经发出,就会生成这个表。而后又随着收到关闭连接时发出 FIN 包的确认应答从表中被删除。

缺点:

  • 外部无法主动与 NAT 内部服务器建立连接,因为 NAPT 转换表没有转换记录。
  • 转换表的生成与转换操作都会产生性能开销。
  • 通信过程中,如果 NAT 路由器重启了,所有的 TCP 连接都将被重置。

解决方式:

  • IPv6
  • NAT穿透技术:也就是说,在 NAT 穿透技术中,NAT设备后的应用程序处于主动地位,它已经明确地知道 NAT 设备要修改它外发的数据包,于是它主动配合 NAT 设备的操作,主动地建立好映射,这样就不像以前由 NAT 设备来建立映射了。

2.5 ICMP

ICMP 全称是 Internet Control Message Protocol,也就是互联网控制报文协议

功能:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。

ICMP 大致可以分为两大类:

  • 一类是用于诊断的查询消息,也就是「查询报文类型
  • 另一类是通知出错原因的错误消息,也就是「差错报文类型

2.6 IGMP

IGMP 是因特网组管理协议,工作在主机(组播成员)和最后一跳路由之间

  • IGMP 报文向路由器申请加入和退出组播组,默认情况下路由器是不会转发组播包到连接中的主机,除非主机通过 IGMP 加入到组播组,主机申请加入到组播组时,路由器就会记录 IGMP 路由器表,路由器后续就会转发组播包到对应的主机了。
  • IGMP 报文采用 IP 封装,IP 头部的协议号为 2,而且 TTL 字段值通常为 1,因为 IGMP 是工作在主机与连接的路由器之间。

3 ping的工作原理

ICMP 报文是封装在 IP 包里面,它工作在网络层,是 IP 协议的助手。

3.1 ping–查询报文类型的使用

ping 命令执行的时候,源主机首先会构建一个 ICMP 回送请求消息数据包。

ICMP 数据包内包含多个字段,最重要的是两个:

  • 第一个是类型,对于回送请求消息而言该字段为 8
  • 另外一个是序号,主要用于区分连续 ping 的时候发出的多个数据包。

每发出一个请求数据包,序号会自动加 1。为了能够计算往返时间 RTT,它会在报文的数据部分插入发送时间。

然后,由 ICMP 协议将这个数据包连同地址 192.168.1.2 一起交给 IP 层。IP 层将以 192.168.1.2 作为目的地址,本机 IP 地址作为源地址协议字段设置为 1 表示是 ICMP 协议,再加上一些其他控制信息,构建一个 IP 数据包。

接下来,需要加入 MAC 头。如果在本地 ARP 映射表中查找出 IP 地址 192.168.1.2 所对应的 MAC 地址,则可以直接使用;如果没有,则需要发送 ARP 协议查询 MAC 地址,获得 MAC 地址后,由数据链路层构建一个数据帧,目的地址是 IP 层传过来的 MAC 地址,源地址则是本机的 MAC 地址;还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。

主机 B 收到这个数据帧后,先检查它的目的 MAC 地址,并和本机的 MAC 地址对比,如符合,则接收,否则就丢弃。

接收后检查该数据帧,将 IP 数据包从帧中提取出来,交给本机的 IP 层。同样,IP 层检查后,将有用的信息提取后交给 ICMP 协议。

主机 B 会构建一个 ICMP 回送响应消息数据包,回送响应数据包的类型字段为 0序号为接收到的请求数据包中的序号,然后再发送出去给主机 A。

在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了 ICMP 回送响应消息,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。

可以看出 ping 这个程序是使用了 ICMP 里面的 ECHO REQUEST(类型为 8 ) 和 ECHO REPLY (类型为 0)

3.2 traceroute–差错报文类型的使用

traceroute 的第一个作用就是故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。它的原理就是利用 IP 包的生存期限1 开始按照顺序递增的同时发送 UDP 包,强制接收 ICMP 超时消息的一种方法。

traceroute 还有一个作用是故意设置不分片,从而确定路径的 MTU。这样做的目的是为了路径MTU发现。因为有的时候我们并不知道路由器的 MTU 大小,以太网的数据链路上的 MTU 通常是 1500 字节,但是非以太网的 MTU 值就不一样了,所以我们要知道 MTU 的大小,从而控制发送的包大小。

3.3 断网了,还能 ping 通 127.0.0.1 吗?

在IPV4下的回环地址是 127.0.0.1,在IPV6下,表达为 ::1 。中间把连续的0给省略了,之所以不是7个 冒号,而是2个冒号, 是因为一个 IPV6 地址中只允许出现⼀次两个连续的冒号

从应用层到传输层再到网络层。这段路径跟ping外网的时候是几乎是一样的。到了网络层,系统会根据目的IP,在路由表中获取对应的路由信息,而这其中就包含选择哪个网卡把消息发出。

当发现目标IP是外网IP时,会从"真网卡"发出。

当发现目标IP是回环地址时,就会选择本地网卡

本地网卡,其实就是个**“假网卡”,它不像"真网卡"那样有个ring buffer什么的,“假网卡"会把数据推到一个叫 input_pkt_queue 的 链表 中。这个链表,其实是所有网卡共享的,上面挂着发给本机的各种消息。** 消息被发送到这个链表后,会再触发一个软中断

专门处理软中断的工具人**“ksoftirqd”** (这是个内核线程),它在收到软中断后就会立马去链表里把消息取出,然后顺着数据链路层、网络层等层层往上传递最后给到应用程序。

ping回环地址和ping本机地址没有区别

3.3 127.0.0.1和localhost和0.0.0.0的区别

  • 127.0.0.1回环地址localhost域名,但默认等于 127.0.0.1,可以在 /etc/hosts 文件下进行修改。默认情况下,使用 localhost 跟使用 127.0.0.1 确实是没区别的。
  • 执行 ping 0.0.0.0 ,是会失败的,因为它在IPV4中表示的是无效的目标地址。启动服务器的时候,一般会 listen 一个 IP 和端口,等待客户端的连接。如果此时 listen 的是本机的 0.0.0.0 , 那么它表示本机上的所有IPV4地址
  • 如果服务器 listen 的是 0.0.0.0,那么此时用127.0.0.1和本机地址都可以访问到服务。