本文主要参考了《TCP/IP详解-卷1》、Yes-Lab视频和lifei6671的笔记的内容,在此表示感谢。
主要介绍以太网和IEEE 802封装。
首先,以太网是私有技术,IEEE 802.3标准是公有技术。
以太网和802.3的封装格式很不一样
802.3的封装格式(很少用到,了解即可):
目标地址+源地址+长度+不需要了解的固定位以及类型位和上层的协议内容
以太网的封装格式(很常用):
目标地址+源地址+类型位(0806表示后面是ARP协议,ARP协议内容不够46bit,因此需要补位;0800表示IP协议,后面跟IP协议内容)+上层协议内容(IP等)/ ARP协议
下面是以太网的头部信息,类型位0800后面就是IP协议:
环回接口是一个很有意思的概念,只要是127开头的都是环回接口,都可以ping通,但是常用的就是127.0.0.1。环回接口的处理流程如下所示:
Slides中列出了三种使用到环回接口的场景:
使用到环回接口的例子:
假设有内部局域网1.1.1.0和2.2.2.0,1.1.1.0的一部分流量输出到互联网(any),一部分在本地的2.2.2.0(VPN),我们并不想将1→2的流量进行NAT转换,此时只需要随便配一个环回接口,然后做一个对应的策略路由,把1→2的流量做策略路由,指向环回接口,就不会走NAT接口了。
原理:NAT被调用成功的三个条件,列表、内部接口输入、外部接口输出,可见1→2的流量从环回接口输出又从环回接口输入,所以不会走NAT了。
众所周知,以太网和802.3对数据帧的长度有限制,其中上限是1500字节和1492字节,即最大传输单元(MTU)。
如果IP数据包>以太网的MTU,就需要对数据包进行分片,以太网的MTU是以输出端MTU为准(不是输入端,而且是一段线路的输出端,不是整条线路的输出端),在传输过程中,可能会多次分片。
最核心的协议,是一个不可靠,无连接的数据报传输服务。
不可靠:尽可能最好的传输服务,不能保证IP数据报一定能发送成功,如果发生错误,会丢弃该数据报,然后发送ICMP消息报给信源端。(TCP通过三次握手和四次挥手保证了可靠性)
无连接:IP不维护后续数据报的状态信息,即每个数据报都是独立传输的。(TCP会排序)
组成:
IP首部可用的几种选项(并非所有主机和路由器都支持):
分为源地址和目的地址是否在同一个网络中(判断是否在同一网络:目的IP和源IP做与运算,网络号一样就表示在同一个网络),工作机制有所不同,左边代表同一网络,右边代表不同网络:
总结:除非使用NAT转换或者使用源路由选项(目的IP逐跳改变,很少使用),数据报中的IP地址一般不变(所有的路由选择决策都是基于这个目的IP地址,ARP中的FTP实验会详细介绍此处的机理),但是mac地址会逐跳改变,始终指向下一站的链路层地址。
受益于NAT和无类别的域间路由选择(CIDR,classless Inter-domain routing),IPV4域名不足的问题被缓解,但是没有得到根本解决。
ARP是一个非常不安全的协议,因为设备驱动程序从不检查IP数据报中的目的IP地址(可能当前直连网络中根本没有该IP地址,ARP就会找不到设备)。
ARP为逻辑地址(IP地址)到硬件地址(以太网中一般指mac地址)提供动态映射,之所以强调 动态 ,是因为这个过程是自动完成的(下面的FTP实验会看到这一点),用户不用操心,所以在使用ping dest_IP
时,不需要指定mac地址。
例子:输入ftp 服务器的域名bsdi
之后的处理流程:
总结:ARP背后的概念——知道主机的IP地址并不能让内核发送一帧数据给主机(telnet实验,如果尝试使用telnet去连接不存在的IP地址(mac地址不存在),ARP会不断的发送请求,直到因为指数退避不再发送为止),要想成功发送数据报,必须知道逻辑地址(IP地址)和硬件地址(以太网中的mac地址)。
ARP高效运行的关键是每个主机都有一个ARP高速缓存,这个高速缓存存放了最近IP地址到硬件地址的映射记录,高速缓存的每一项的生命周期一般为20分钟。
查询ARP缓存的命令:
pc: 查询 arp -a
,清除 arp -d
路由器 查询 show arp
清除 clear arp
(不完全清除。因为清除的时候也在解析)
ARP的数据报是一种以太网帧,其中:
特别**当R1没有默认网关(no ip routing)**想要ping R3,所以不论R3是否是直连(此时并没有查询路由表的能力,判断R3是否是直连),都会发送一个R3 IP地址的ARP请求,如果R2的接口E0开启了代理ARP的feature,R2如果也知道R3的mac地址,R2就会告诉R1:接口E0的硬件地址就是R3的mac地址。
应用:一般来说,将公司内部网页的地址(10.1.1.0)一对一转换到互联网地址(202.100.1.10),外部访问公司网页的时候,会直接访问服务器外侧的路由器R的代理ARP接口(202.100.1.10)
总结:通常ARP会被路由器隔离,但是支持代理ARP(proxy ARP)的路由器可以将ARP请求发送到邻近的网段,由此,两个网段可以像是在同一个网段中通信。
开机时设备一般会检测当前网络下是否有其他主机与当前设备设置了相同的IP地址,此时就是通过免费ARP完成的。
应用场景:公司有两台设备(IP地址相同,但是mac地址不同),每次只运行其中一台(冷备),早期切换设备的时候不能关闭一台,再打开另一台,否则路由器上的ARP缓存没有变化(20分钟的生命周期内),此时ARP映射就会找不到已关闭设备的mac地址。
目前已经可以这么做了,因为新设备开机的时候就会发送免费ARP请求,而路由器就会据此更新。
免费ARP攻击:攻击者会利用免费ARP的漏洞(比如原设备已关机),将网络上其他接收者的映射更新为发送者(攻击者)的mac地址,此时所有设备的ARP就被毒化了。
ICMP被认为是IP的附属协议,一些ICMP报文将 差错报文 返回给用户进程,例如ping
程序。
ICMP是在IP数据报文内部被传输的【IP数据报=IP首部+ICMP报文】,ICMP报文的结构:
注意:以太网和IP校验和仅校验以太网头部和IP头部,但是TCP和ICMP的 校验和 校验之后所有的位。
从总的分类上,可以将ICMP报文分为查询报文(例如ping应答00和ping请求80)和差错报文(例如不可达3x)。
当发送一份ICMP差错报文时,报文中始终包括IP首部和IP数据报的前8个字节,这样,接收ICMP差错报文的模块就会把它与某个特定的协议(IP首部的协议字段)和用户进程(IP数据报的前8个字段,含有TCP或UDP的端口号)联系起来。(这其实很合理,毕竟你要告诉源机,究竟是哪个协议哪个进程丢了包)
以下情况不会产生ICMP差错报文:
常用ping来确定问题出现在哪儿,还能测出这台主机的往返时间,但是需要注意:一台主机的可达性不止取决于IP层是否可达,还取决于使用何种协议和端口,例如有的主机没有ICMP列表,但是可以telnet登录(?)。
注意大多数的TCP/IP实现都是在内核中直接支持ping服务器。
ICMP报文结构(以下针对Unix):类型号0或8,代码0,校验和(覆盖之后所有),标识符(Unix的标识符字段 为 发送进程的ID),序号,选项数据(发包时间,由此获得往返时间)
记录路径
大部分ping程序都提供了-R选项,用来记录路由的功能,但是受限于IP数据包大小(60-20=40字节),最多纪录9个IP地址(一个IP地址占4个字节);而且因为需要放在选项功能中,所以要求所有的路由设备都要支持选项功能 —— trace
可以更好的替代-R
选项,但是trace是记录入接口,-R记录的是出接口。
标识符字段 为 发送进程的ID),序号,选项数据(发包时间,由此获得往返时间)
记录路径
大部分ping程序都提供了-R选项,用来记录路由的功能,但是受限于IP数据包大小(60-20=40字节),最多纪录9个IP地址(一个IP地址占4个字节);而且因为需要放在选项功能中,所以要求所有的路由设备都要支持选项功能 —— trace
可以更好的替代-R
选项,但是trace是记录入接口,-R记录的是出接口。