目录奉上,用者自取:
文章目录
1. 以太网主要协议关系介绍
网络结构可以分为五层,自底向上依次为:物理层、数据链路层、网络层、传输层、应用层,每一层都有相应的协议。网络协议种类众多,但最为主要的几种协议为:多点接入载波监听/冲突检测CSMA/CD、媒体访问控制子层协议MAC、地址解析协议ARP、互联网控制消息协议ICMP、网际互连协议IP、用户数据报协议UDP、传输控制协议TCP,他们的关系结构如下:
在以太网(Ethernet)通信中,CSMA/CD协议一般直接使用PHY芯片(物理接口收发器PHY),因此主要关注的为上面几层的协议。
先介绍下几种协议是怎么样的关系,具体的协议功能及帧结构见下一节,如果在此节对于各种协议的功能有疑惑,可以先跳转到后面一节了解一下(* ^▽^ *)。
以太网帧(MAC帧)处于数据链路层,可以直接交付给PHY芯片,从而转化为比特流在物理通路上传输,由于PHY实现了CSMA/CD的部分功能,会自己进行碰撞检测。MAC帧数据段的内容可以填充为ARP数据报或者IP数据报,ARP协议主要用于获取MAC地址(IP-MAC地址映射),IP协议大家就比较了解了,用于传输各种数据。
IP数据报的数据段可以填充为ICMP报文、TCP报文、UDP报文。其中ICMP协议用于进行网络诊断、时间戳校验等,尽管ICMP是基于IP协议进行工作的,但一般认为它是网络层协议;TCP、UDP协议则是我们传送数据的主要手段。
TCP/UDP协议上层就是各种应用层协议了,如DNS、HTTP、FTP等等,如果是在高速数据采集系统里,TCP/UDP包的数据段可以直接就是数据。
2. 协议介绍及帧结构
2.1 媒体访问控制子层协议MAC
在物理层传输的是比特流,为了识别一MAC帧的起始(比特同步),会在每一MAC帧前加入7个字节的前导码Preamble以及1个字节的帧起始界定符SFD。从比特流来看,前导码固定为10101010,SFD固定为10101011,当收到11,表明后续数据属于MAC帧。由于我们使用GMII接口或者RGMII接口将数据送入PHY进行并串转换,字节流转换为比特流,该转换过程为小端传输,因此当在MAC帧前插入前导码和SFD时,字节流分别为0x55…0x55、0xd5。注意,尽管很多资料上说物理层传输MAC帧时会在前面加上前导码和SFD,但其实前导码和帧起始界定符都是在MAC层加上去的。在两个连续的MAC帧之间,也必须有一段间隔,也就是帧间隙IFG,帧间隙不小于12Byte,值全1。这个帧间隙是CSMA/CD的特性决定的。
MAC层及以上,传输的都是字节流,下面也都基于此进行说明。
MAC帧由MAC帧头、数据段、帧校验序列FSC(MAC帧尾)组成。MAC帧头包括三个字段:目的MAC地址、源MAC地址、长度/类型字段。目的、源MAC地址为长度6Byte,唯一确定了硬件的身份。长度/类型字段,当值小于1536(0x0600)时,表示MAC帧数据段的长度,单位Byte,否则表示数据段所使用的上层子协议类型,如0x0800为表示上层子协议为IP协议,0x0806则表示为ARP协议。
MAC帧数据段长度限制为46 ∼ \sim ∼ 1500Byte,对应MAC帧长64 ∼ \sim ∼ 1518 Byte,太长或太短的MAC帧都会被认为是无效帧,直接丢弃。64Byte长度是由CSMA/CD的争用期(即以太网端到端传输时间的两倍2t,也称碰撞窗口)决定的,感兴趣的同学可以了解下CSMA/CD碰撞检测,我这里就不介绍了。MAC帧数据段最大长度限制为1500,称为最大传输单元MTU,在不同的网络中由于数据链路和传输介质不同,可能存在差异,但最大是1500,这是为了避免某一帧过长而导致其他MAC帧等待时间过长而进行的限制。当传输到某网络的MAC帧长度大于其MTU时,会进行分片。
在MAC帧的最后要加上帧校验序列FSC,最常用的校验算法为循环冗余校验CRC-32。
2.2 地址解析协议ARP
2.2.1ARP帧结构
ARP协议是用于在局域网内进行IP地址-MAC地址映射的协议,ARP数据报填充至MAC帧数据段,由于其长度小于46Byte,因此组装成MAC帧时要后补零至满46Byte,其帧结构如下
ARP首部包含如下字段:
-
硬件类型字段,长度2Byte,1表示为以太网Ethernet。
-
协议类型字段,2Byte,0x0800表示要映射的地址类型为IP地址。
-
硬件地址长度字段,1Byte,单位Byte,由于MAC地址长度为6Byte,因此值为6。
-
协议地址长度字段,1Byte,单位Byte,由于IPv4地址长度为4Byte,因此值为4。
-
操作类型字段,2Byte,最常用的为ARP请求(值为1)、ARP应答(值为2)。
后面四个字段很容易理解,其中作为ARP请求时,目的MAC地址字段填0。
2.2.2 ARP协议工作原理
假设同一局域网内有两台主机要进行通信,主机A打算向主机B发送消息,此时主机A会首先查询自己的ARP缓存表(ARP缓存表存储了IP-MAC地址映射表项),如果检索到主机B的IP-MAC表项,主机A将主机B的MAC地址填入MAC帧,打包数据,发送。
但如果主机A没有在自己的ARP缓存中检索到对应的表项,会将待发送数据缓存,同时发送ARP请求,源MAC地址、源IP地址填入主机A自己的,目的MAC地址字段填0,目的IP地址填入主机B的IP地址。ARP请求是以广播形式发送的,广播时MAC帧的MAC地址为全1,即打包为MAC帧时,其目的MAC地址为0xFF-0xFF-0xFF-0xFF-0xFF-0xFF,此时整个局域网内的全部主机都将收到该ARP请求报文。
主机B在收到该ARP请求报文后,会回复ARP应答报文(而其他主机不会回复),将主机A的IP地址和MAC地址、自己的IP地址和MAC地址写入ARP帧,打包成MAC帧时,在目的MAC地址字段填入主机A的MAC地址,发送。此时主机A将收到该条ARP应答报文,因此主机A解析获取了主机B的MAC地址,将IP-MAC表项写入自己的ARP缓存表,下次再进行发送时将可以直接从自己的ARP缓存中获取主机B的MAC地址。同时,主机A将利用获取的主机B的MAC地址打包数据,发送,这样主机B就可以收到主机A发送的数据了。
这里可能有同学感到奇怪,既然MAC地址和IP地址是一一对应的,为什么还要两种地址呢?在局域网内确实如此,因为所有主机都是一跳可达的(通过转发器),但如果要进行不同局域网间的通信,此时就要进行路由。路由时IP数据报中的目的IP地址是不变的,对应接收方IP地址,而目的MAC地址则会不断改变,指示下一跳的MAC地址,因此除了最后一跳会是目的主机的MAC地址,其他的目的MAC地址都是路由器的MAC地址,其中发送方主机A打包的MAC帧,其目的MAC地址实际上不是主机B的MAC地址,而是默认网关的MAC地址。主机A直接将数据交付给网关,而网关查看自己的路由表,决定将IP数据报继续发送给哪一路由。
2.3 网际互连协议IP
2.3.1 IP协议帧
IP帧结构如图所示,包括IP首部和IP数据段,IP数据段内填充上层协议,如ICMP协议、UDP协议、TCP协议。
IP帧头至少20Byte,根据可选字段长度,最长60Byte(对应可选字段40Byte)。IP首部的各字段含义如下:
-
协议版本字段,4bit,标识采用的IP协议版本,IPv4为4(0b0100),IPv6为6(0b0110)。
-
首部长度字段,4bit,表示IP首部的长度,以32bit(4Byte)为单位,如没有可选字段,IP首部长度20Byte,则该字段值为20/4=5。
-
服务类型字段,8bit,该字段被划分成两个子字段: 3位优先级字段(现已基本忽略)和4位TOS(Type Of Service)字段,最后一位固定为0,服务类型为0时表示一般服务。
-
总长度字段,16bit,单位Byte,表示整个IP数据报的长度(IP首部长度+IP数据段长度)。一般而言会限制IP数据报长度小于1500 Byte,因此在MAC层可以避免分片的麻烦。
-
标识字段Id,16bit,用来标识主机发送的每一份数据报,通常每发送一份报文它的值就会加1。
-
标志字段Flag,3bit,用于IP数据报被分片的情况。第一位不使用,置0;第二位为不分片位DF,当设为1时,表示强制禁止分片,0表示允许分片;第三位为片未完位MF,当为0时表示为最后一片,为1表示不是最后一片。
-
片偏移,13bit,单位8Byte,在IP分片时使用,标识当前IP数据片段首字节处于原始数据的哪个位置,如为第400个Byte,则该值为400/8=50,IP分片必须以8Byte为单位进行划分,首个字节偏移标记为0。
-
生存时间TTL,8bit,标识该数据报在网络中总共可通过路由器的最大次数,防止数据包在网络上无休止地传播,一般被设置为64或者128,数据包每经过一次路由,其生存时间将减1,当TTL将为0时仍没有传输到目标主机时,将被路由器丢弃,同时给发送主机一个ICMP报,告知其跃点数超限。
-
协议类型字段,8bit,标识上层协议类型,ICMP为1,TCP为6,UDP为17。
-
首部校验和Checksum,16bit,只校验数据报的首部(不含校验域本身),计算方法为:首先将Checksum字段置0,将IP首部按16bit依次二进制反码求和,计算完成后将计算结果覆盖到Checksum字段。校验和计算方法为:
- 把校验和字段置为0;
- 对IP头部中的每16bit进行二进制求和;
- 如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;
- 将该16bit的值取反,存入校验和字段。
在接收方进行校验时,将整个IP首部按上述2、3步进行处理,结果取反,判断是否为0,为0则表示校验通过。
-
源IP、目的IP字段,各32bit,即发送主机和目的主机的IPv4地址。
-
可选字段,长度必须为32bit(4Byte)的整数倍,不足32bit的填充0,最长40Byte(因为首部长度字段最大值15,对应IP首部最长60Byte),可以没有,该字段根据不同的服务类型有所不同,一般服务(服务类型字段为0)不使用该字段。
IP数据段可以填充上层子协议,如ICMP协议报文、TCP报文、UDP报文等,其长度计算方式为:IP总长度字段值-4*IP首部长度字段值(单位:Byte),一个IP包最大长度为 65535 Byte,因此可携带的数据段最大长度为 65535-20 = 65515 Byte。
2.3.2 IP数据报分片重组
当IP数据报在某一网络其长度超过网络MTU时,将进行IP数据报分片。分片时,IP首部复制到每一数据片,并修改标志段和片偏移字段,由于标识字段Id相同,因此可识别为属于同一数据报。片偏移=首个字节的原始序号/8。
例如,IP报文无可选项,数据段D0…D999,当前网络MTU=420,则分成D0…D399,D400…D799,D800…D999三个数据片,每个数据片首部复制原始数据片的IP首部,第一片片偏移修改为0/8=0,第二片片偏移修改为400/8=50,第三片片偏移修改为800/8=100,片未完位分别修改为为1、1、0。
在进行IP数据片重组时,将标识字段相同的IP数据片按照片偏移逆向组装即可获得原始数据报。
2.4 互联网控制消息协议ICMP
ICMP协议用于传输出错报告控制信息,其帧结构如图所示,包含8Byte长度的ICMP首部以及可选项。
- 类型字段Type,1Byte,标识ICMP报文类型,目前已经定义了14种。
- 代码字段Code,1Byte,配合类型字段,标识了ICMP报文的详细类型。
- 校验和字段Checksum,2Byte,计算方法与计算IP数据报首部校验和类似,但覆盖包括ICMP报文数据部分在内的整个ICMP数据报。
- 标识字段Id,2Byte,用于标识本ICMP进程,但仅适用于回显请求和应答ICMP报文,对于目标不可达ICMP报文和超时ICMP报文等,该字段的值为0。
- 序列号字段Seq,2Byte,用于关联请求、应答报文,响应报文与其对应的请求报文的序列号相同。
- 可选项根据不同的ICMP报文类型而不同,此处不再涉及。
2.5 用户数据报协议UDP
UDP是一个简单的面向消息的传输层协议,不保证可靠传输。其帧结构也很简单,如下图所示
UDP帧包含8Byte的首部以及数据段,数据段长度可以通过两种方式进行计算:UDP长度字段值-8、IP总长度字段值-4*IP首部长度字段值-8。UDP首部各字段含义解释如下:
- 源端口,2Byte,标识发送进程的端口号。
- 目的端口,2Byte,标识目标进程的端口号。
- UDP长度,2Byte,单位Byte,标识整个UDP报文的长度,尽管2Byte最大值可以取到65535,但由于IP数据报长度的限制,其最大长度其实为65535-20=65515Byte(假设IP数据报没有可选字段)。
- 校验和,2Byte,计算算法与IP协议相同,但其覆盖范围包含伪首部、UDP首部、UDP数据。其中伪首部如下,共12字节,其中17为UDP的协议类型号,0则是为了补足16bit进行的填充。
2.6 传输控制协议TCP
TCP协议比较复杂,我也才刚开始了解,这里先只介绍TCP帧结构,如下图
- 源端口、目的端口同UDP,不再多解释。
- 序列号Seq,4Byte,用于标识TCP源端设备向目的端设备发送的字节流,它表示在这个报文段中的第几个数据字节,通常不是从0开始,而是随机初始化。
- 确认号Ack,4Byte,标识期望收到的下一个段的第一个字节,并声明此前的所有数据已经正确无误地收到,因此,确认号应该是上次已成功收到的数据字节序列号加1。收到确认号的源计算机会知道特定的段已被收到,确认号的字段只在ACK标志被设置时才有效。
- 首部长度字段,4bit,标识TCP首部有多少个32bit(4Byte),在没有可选字段时,最小为5(20/4=5),与IP首部长度字段类似。
- 保留字段,6bit,不使用,置0。
- 标志字段Flag,6bit,共6个标志位,功能分别如下:
- 紧急标志位URG,置位表明紧急指针有效;
- 确认标志位ACK,置位表示确认号有效;
- 立即发送标志位PSH,置位表示应立即将报文交付应用层;
- 复位标志位RST,用于重建一个已经混乱的连接,用来复位产生错误的连接,也会用来拒绝错误和非法的数据包;
- 同步标志位SYN,用于建立TCP连接,该标志仅在三次握手建立TCP连接时有效;
- 结束标志位FIN,用于断开TCP连接,该标志仅在四次挥手断开TCP连接时有效;
- 窗口尺寸,2Byte,用于TCP流量控制,表示接收方缓冲的字节数,为0表明发送方应该立即停止传送,接收方的TCP缓冲区已满。
- TCP校验和字段,2Byte,计算方法与UDP类似,也要加上伪首部,伪首部的类型号为6(TCP的协议类型号),同时覆盖整个TCP报文段(包括TCP首部和TCP数据段)。
- 紧急指针,2Byte,指向数据中优先部分的最后一个字节,通知接收方紧急数据的长度,该字段在紧急标志位URG置位时有效。
- 可选项,与IP协议类似,长度必须为32bit的整数倍,不足长的补零填充,最大40Byte,可以没有。
- 数据段,和UDP不同,TCP报文中没有直接给出数据段的长度,因此必须通过IP数据报长度进行计算,数据段长度为:IP总长度字段值 - 4 * IP首部长度字段值 - 4 * TCP首部长度字段值,TCP数据段最长为65535-20-20=65495 Byte。TCP数据段不是必须的,此时主要传输一些控制消息,比如在三次握手建立TCP连接以及四次挥手断开TCP连接时就没有数据段,其实IP数据报的数据段也不是必须的。
3. 最后的话
这是个刚开始入门以太网的小白写的学习笔记,如有不对的地方烦请大佬们指正!