下表描述了整个从上到下的网络协议层:
这些网络协议在FPGA实际开发的过程中用到的就是传输层、网络层、数据链路层和物理层,在我们的举例中用到UDP、IP、ARP协议,物理层就用88E1111(10/100/1000BASE-T IEEE 802.3 compliant )的RGMII接口。
整个UDP报文层次结构如下图,请记住这张图贯穿整篇文章,层与层之间的关系搞不清楚了就回头来看看这张图,让自己的思路清醒一下。
好了,那么首先我们就从传输层开始,来一层一层的揭开UDP通信协议的面纱:
1、16位源、目的端口号:
源端口号:发送方发送数据的端口。
目的端口号:接收方接收数据的端口。
2、16位UDP长度 :
长度为16bit。UDP的长度是指包括包头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。理论上,包含报头在内的数据报的最大长度为65535字节,实际上,UDP的MTU一般为1500,这与CDMA/CS机制有关系,即使巨型包也不会超过65535,在基于USO和UFO层次时,可对UDP进行拆包处理。(这部分暂未研究,以后有机会一定要好好学习一哈)
3、16位UDP校验和:
占16bit,用来对UDP头部和UDP数据进行校验。UDP的校验和需要计算UDP首部+数据部分,但也需要加上UDP伪首部,这个伪首部指的是:
UDP校验和计算步骤如下:(注意啊,加上UDP伪首部,16位的UDP长度参与了两次运算)
(1)把校验和字段置为0;
(2)把需校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;
什么是二进制反码求和?答:对一个无符号的数,先求其反码,然后从低位到高位,按位相加,有溢出则向高位进1(跟一般的二进制加法规则一样),若最高位有进位,则向最低位进1。
翻译一下:把所有16位的字相加,如果遇到进位,则将高于16字节的进位部分的值加到最低位上,(即高位溢出位会加到低位),将得到的和的反码填入校验和字段。举例,0xBB5E+0xFCED=0x1 B84B,则将1放到最低位,得到结果是0xB84C。将所有字相加得到的结果应该为一个16位的数,将该数取反,则可以得到检验和checksum)
(3)把得到的结果存入校验和字段中。
另外UDP、TCP数据报的长度可以为奇数字节,如果在计算校验和数据长度不能满足16bit的整倍数,需要填充一个字节的0。(注意,填充字节只是为了计算校验和,可以不被传送)。
4、数据
打包在UDP协议中的用户数据。
前20字节为IP数据报的首部,IP数据报的首部是固定的,首部的每一行是一个32位的单位,最高位在左边,为0bit,最低位在右边,为31bit。
4字节的32bit数据传输次序为:首先0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit,这种传输次序为big endian(大端对齐)。TCP/IP所有二进制整数在网络中传输时都要求采用这种次序,因此这种传输次序又称为网络字节序。
1、版本+首部长度:
长度为1字节。
版本[0:3]:就是IPv4或者IPv6,一般选择IPv4,即版本值为4。
首部长度[4:7]:是指首部有多少个32位数,因为4位的最大值为15,因此首部最长为60字节,5表示固定最小值为20字节。选项部分(可选字段)的最大值为40字节,不够4的倍数要用0填充,使数据部分的起始地址为4的倍数。
2、服务类型 :
长度为8比特,置0。
3、总长度 :
长度为2Byte。总长度是指整个IP数据报的长度(IP报头+数据),16bit,最长为65535字节,如果超过1500-20=1480还需要进行分包处理。
4、分段标识:
长度为2Byte。是否属于同一数据段,IP报文的分段ID。随意置数即可。
5、段标识和段偏移:
长度为2B。置0即可。
6、生成周期(TTL):
长度为1Byte。
表示这可经过的最大路由数,生存时间字段设了数据包可以经过的最大路由数,表示数据包在网络上生存多久。TTL的初始值由源主机设置(通常为32或64),一旦经过一个路由器(网络层),他的值就减去1,当该字段的值为0时,数据报就被丢弃,并发送ICMP消息通知源主机,这样当封包在传递过程中由于某些原因未能抵达目的地的时候就可以避免其一直充斥在网路。
7、上层协议(上层为传输层):
1Byte。指示该封包所使用的网络协议类型,常用的协议号:
16’d00:IP
16’d01:ICMP
16’d06:TCP
16’d17:UDP
8、报头校验和:
2Byte。
IP报头的校验和,只校验IP报头,不对首部后面数据进行计算,计算方法和UDP校验和计算方法一样:
(1)将校验和字段置0,然后将IP包头按照16bit分成更多单元,如包头长度不是16bit整数倍,则用0bit填充到16bit的倍数。
(2)对各个单元采用反码加法运算(即高位溢出位会加到低位),将得到的和的反码填入校验和字段。
9、源IP地址:
4byte。发送端的IP地址。
10、目的IP地址 :
4Byte。接收端的IP地址。
11、可选字段:
可选,没有时候可以为0,最大为40字节,必须为4的倍数,不到的话用0填充。
MAC帧是数据帧的一种,所谓数据帧,就是数据链路层的协议数据单元,包括三部分:帧头、数据部分、帧尾。其中,帧头和帧尾包含一些必要的控制信息,比如同步信息、地址信息、差错控制信息等;数据部分则包含网络层传输下来的数据,比如IP数据包。
前导码和帧起始符不算MAC帧组成,所以MAC帧的固定长度为6+6+2+4=18。
MAC帧的帧头包括三个字段,前两个字段分别为6字节长的目的地址字段和源地址字段,第三个字段为2字节的类型/长度字段。
1、前导码(Preamble):
不算在MAC帧成分,前导码的作用是使主机接收器时钟和源主机发送器时钟同步,紧接着是帧开始分界符字节0x55或者0xAA,用于指示帧的开始,前导码是为了隔离每个以太网帧的,也是定位符。因为以太网是变长的,所以每个帧之间需要前导码来确认。字段长度为:7个字节。
2、帧开始符(SFD)
不算MAC帧成分,8’hd5:表明下一字段为为目的MAC字段。
3、目的MAC地址:
长度为:6个字节,指接收方。广播时为(ff_ff_ff_ff_ff_ff) ,例如ARP请求包发送时。
4、源MAC地址:
长度为6个字节,指发送者。
5、长度/类型(type/length):
帧的数据字段长度,为2个字节,type/length规定大于0x600就是type帧,小于或等于1500则指示帧的有效数据长度,length标识有效载荷的数据长度,不包含填充的长度。当类型字段的数值为0x0800时,就表示使用的是IP报文。当类型字段的数值为0x0806时,就表示使用的是ARP报文。
6、数据和填充(数据部分)
Data and Pad,长度为46~1500,包含的是高层(网络层)的数据,通常是3层协议单元,对于TCP/IP是IP数据包。
(46B如何得出?)
以太网最小帧长64B。去掉MAC帧18B的首部地址和尾部,64-18=46。如果一个帧的数据部分少于46B,则MAC子层就会在就会在有效数据字段的后面加入填充字段Pad,以保证以太网的MAC地址不低于64B。再计算一下,去掉IP报头20B,去掉UDP报头8B,实际我们要发送的数据最小为46-20-8=18B,但是我们为什么还能发一个字节或者两个字节呢?其实就是被Pad字段填充补齐了一帧数据。
MAC帧中数据和填充部分的长度必须在46~1500字节之间,这是由以太网的物理特性决定的,这个1500字节被称为链路层的MTU(最大传输单元,Max Transmit Unit),但是这并不是指链路层的长度被限制在1500字节,MTU指的是链路层的数据区,并不包括链路层的首部和尾部的18字节。
因为IP数据报的首部长度为20字节,所以IP数据报的数据区长度为1480字节,而这个1480字节就是用来存放TCP传来的TCP报文段或者UDP传来的UDP数据报的,又因为UDP数据报的首部为8字节,所以UDP数据报的数据区最大长度为1472字节。(这1472即为可使用的字节数)
在普通局域网环境下,将UDP的数据控制在1472字节下最好。在intel上标准MTU的值为576字节,一般就是512字节一个包,大数据使用分包—封包处理。
7、帧校验序列(FCS)
使用CRC循环冗余校验码校验,判断是否传输错误,如果发现错误,丢弃此帧。这个字段只是提供检错功能,并不提供纠错功能,该校验范围为:目的地址+源地址+类型/长度+数据字段。
CRC循环冗余校验码校验:循环冗余校验同其他差错检测方式一样,通过在要传输的k比特数据D后添加(n-k)比特冗余位(又称帧检验序列,Frame Check Sequence,FCS)F形成n比特的传输帧T,再将其发送出去。
下面以最常用的CRC-16为例来说明其生成过程。
CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
注意:该步检查LSB应该是右移前的LSB,即第3步前的LSB。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
上面我们已经一层层的将UDP的数据包讲解完毕,下面就要把UDP通信的整个过程来梳理一下,让大家对UDP通信的过程有一个整体的认知:
1、主机、从机设定好MAC地址、IP地址、端口号。
2、主机广播从机IP地址,发送ARP请求,寻找从机MAC地址。
3、从机接收到主机的ARP请求,产生应答,把本地的MAC地址发送给主机。
4、主机接收到ARP应答后,主从就建立起了网络连接,可以互相发送UDP数据报。
这四个步骤就是两台设备间简单的UDP通信过程,其中我们提到了ARP,那么ARP具体是什么呢?
在网络访问层中,同一局域网中的一台主机要和另一台主机进行通信,需要通过 MAC 地址进行定位,然后才能进行数据包的发送。而在网络层和传输层中,计算机之间是通过 IP 地址定位目标主机,对应的数据报文只包含目标主机的 IP 地址,而没有 MAC 地址。因此,在发送之前需要根据 IP 地址获取 MAC 地址,然后才能将数据包发送到正确的目标主机,而这个获取过程是通过 ARP 协议完成的。
1、ARP 工作的基本流程:
ARP 工作流程分为两个阶段,一个是 ARP 请求过程,另一个是 ARP 响应过程。
工作流程如下所示。
在上面图片中,主机 A 的 IP 地址为 192.168.1.1,主机 B 的 IP 地址为 192.168.1.2。
主机 A 与主机 B 进行通信,需要获取其 MAC 地址,基本流程如下:
2、ARP报文格式:
ARP 协议是通过报文进行工作的,ARP 报文格式如图所示。
ARP 报文总长度为 28 字节,MAC 地址长度为 6 字节,IP 地址长度为 4 字节。
其中,每个字段的含义如下。
ARP 数据包分为请求包和响应包,对应报文中的某些字段值也有所不同。
RGMII数据接口采用DDR双沿采样,4bit位宽,上升沿采低4bit,下降沿采高4bit,一个周期的期拼成一个字节。
介绍到这就可以了,UDP数据包按照88E1111接口时序发送出去就好了,其实最主要的还是搞懂UDP数据包,88E1111就是一个收发数据的物理接口。