文章目录
- 前言:IPv4报文协议格式
- 二、IP_RX模块设计
- 2.1、模块接口
- 2.2、模块工作过程
- 三、IP_TX模块设计
- 3.1、模块接口
- 3.2、模块工作过程
- 四、仿真
- 4.1、发送端
- 4.2、接受端
前言:IPv4报文协议格式
参考:https://sunyunqiang.com/blog/ipv4_protocol_rfc791/这篇文章内容很丰富,建议看看
Version : 长度为 4 比特, 表征 IP 协议的版本号, 对 IPv4 来说该字段的值为 4
IHL : 长度为 4 比特, IHL 是 Internet Header Length 的缩写, 以 4 字节为单位指示 IP Header 的长度, 对于 IPv4 来说, Header 的最小长度为 20 字节, 因此该字段的最小值为 5
Type of Service : 服务类型, IETF 在之后将该字段改为 Differentiated Service, 即区分服务, 长度为 8 比特, 该字段用来表达发送端对服务质量的期望程度, 例如可以通过在该字段中设置标志位表达发送方希望该 IP Datagram 低时延 (Low Delay) 的效果送达终端, 或希望以高可靠性 (High Relibility) 的效果送达终端, 但这些都需特定网络或 ISP 的支持。
Total Length: 长度为 16 比特, 顾名思义该字段以字节为单位指示整个 IP Datagram 的长度, 结合 IHL, 我们可以计算出一个 IP Datagram 的数据部分长度为 Total Length - IHL / 4, 因为该字段的长度为 16 比特, 所以可以知道一个 IP Datagram 理论上最大的长度为 2 ^ 16, 即 65535 个字节, 但实际上这么长的 IP Datagram 往往无法保证一定可以被主机或路由器正确的处理, RFC 791 规定所有主机都至少能够处理 576 字节的 IP Datagram, 因此不建议发送超过 576 字节的 IP Datagram, 除非你知晓中途的主机或路由器都可以正确地处理
Identification: 长度为 16 比特, 发送方维护一个计数器, 每产生一个 IP Datagram, 计数器的值就加一, 该字段主要用在 IP 分片场景中, 对于分片的 IP Datagram, 它们在逻辑上仍然是一个 IP Datagram, 所有分片的 IP Datagram 的 Identification 值都是相同的, 接收方最终可以根据该字段知晓哪些 IP Datagram 是属于同一个整体的
Flag: 长度为 3 比特, 其中最高位为保留位, 目前没有使用, 必须设置为 0, 中间的一位是 DF (Don’t Fragment), 当该位为 1 时代表不分片, IP Datagram 在传输过程中, 如果其长度过长, 中间设备无法处理, 但又发现该字段为 1 时, 应丢弃该 IP Datagram, 最后一位是 MF (More Fragments), 当该位为 1 时, 代表当前不是分片的最后一个 IP Datagram, 在之后还有更多的分片, 当该位为 0 时代表当前是分片的最后一个 IP Datagram,总结如下:
- Bit 0 : 保留,必须置零。
- Bit 1: (DF) 为0 表示可以对分组进行分片, 为1 表示不可以对分组进行分片
- Bit 2: (MF) 为0表示该数据段是本分组中最后的一个数据分段,为1 表示后面还有数据分段
Fragment Offset: 片偏移, 长度为 13 比特, 当发生 IP Datagram 分片时, 该字段将指示当前分片在原先的整个 IP Datagram 上的偏移量, 以 8 字节为单位, 对于不分片或分片的第一个 IP Datagram, 该字段的值必须为 0
Time to Live : 简称 TTL, 长度为 8 比特, 由发送端设置初始值, 在 RFC 791 中, 该字段的语义是一个 IP Datagram 从发出以后所能存活的最长时间, 以秒为单位, IP Datagram 在每经过一个主机或路由器时, 都需要减去路由器处理该 IP Datagram 时所花费的时间, 如果花费时间少于 1s 则按 1s 算, 现在该字段已经被改为跳数, 即每经过一个主机或路由器该字段减去1, 当某个 IP Datagram 的 TTL 字段的值减到 0 时, 必须立即丢弃该分组, 设置该字段的目的是为了防止那些无法被交付到目的地的分组在网络中无限地循环, 造成不必要的资源浪费
Protocol : 长度为 8 比特, 用于指示 IP Datagram 携带的数据使用的上层协议类型, 该字段的值为协议的编号, 协议编号由 IANA 维护
Header Checksum : 长度为 16 比特, 其值为 IP Header 部分的校验和, 在一定程度上保证 IP 数据的完整性, 接收到 IP Datagram 的主机应检查该字段是否正确, 若不正确应立即丢弃该分组, 另外, 用于每经过一个主机或路由器, Header 部分都会更改 (至少需要更改 TTL), 因此该字段的值每经过一跳都需要重新计算和赋值
Source Address : 32 bits,指明了发送节点的IP地址。
Destination Address : 32 bits,指明了接收节点的IP地址。
Options :拓展字段, 该字段长度可变, 扩展字段可以包含一些可选项, 例如客户端可以利用拓展字段来记录 Datagram 的路由数据等
Padding:由于 IHL 字段以 4 字节为单位表征 IP Datagram 的 Header 部分的长度, 因此 IP Header 的长度必须是 4 字节的整数倍, 由于 Options 的长度是可变的, 它可能导致整个 IP Header 的长度不是 4 字节的整数倍, 此时需要使用 Padding 字段来填充, Padding 字段的值必须设置为全 0
二、IP_RX模块设计
2.1、模块接口
该模块主要功能为接收MAC层收到的的IP数据包,将其进行解析,发送给更上层的协议,ICMP或者是UDP层。
module IP_RX#(
parameter P_SRC_IP_ADDR = {8'd192,8'd168,8'd100,8'd99},
parameter P_DST_IP_ADDR = {8'd192,8'd168,8'd100,8'd100}
)(
input i_clk ,
input i_rst ,
input [31:0] i_dynamic_src_ip ,
input i_dynamic_src_valid ,
input [31:0] i_dynamic_dst_ip ,
input i_dynamic_dst_valid ,
/*****MAC AXIS interface*****/
input [63:0] s_axis_mac_data ,
input [79:0] s_axis_mac_user ,//用户自定义{16'dlen,r_src_mac[47:0],16'dr_type}
input [7 :0] s_axis_mac_keep ,
input s_axis_mac_last ,
input s_axis_mac_valid ,
/*****upper layer AXIS interface*****/
output [63:0] m_axis_upper_data ,
output [55:0] m_axis_upper_user ,//用户自定义{16'dlen,3'bflag,8'dtype,13'doffset,16'dID}
output [7 :0] m_axis_upper_keep ,
output m_axis_upper_last ,
output m_axis_upper_valid
);
2.2、模块工作过程
- 接收数据并解析关键字段信息
- 判数据包的目的IP地址是否为本机
- 将数据转化为AXIS的数据流形式传递给上层(难点在于尾端keep处理,但比MAC层的简单许多)
三、IP_TX模块设计
3.1、模块接口
该模块主要功能为接收上层协议的数据内容,按照IP协议进行组包,然后发送给MAC层
module IP_TX#(
parameter P_SRC_IP_ADDR = {8'd192,8'd168,8'd100,8'd99},
parameter P_DST_IP_ADDR = {8'd192,8'd168,8'd100,8'd100}
)(
input i_clk ,
input i_rst ,
input [31:0] i_dynamic_src_ip ,
input i_dynamic_src_valid ,
input [31:0] i_dynamic_dst_ip ,
input i_dynamic_dst_valid ,
/*****MAC AXIS interface*****/
output [63:0] m_axis_mac_data ,
output [79:0] m_axis_mac_user ,//用户自定义{16'dlen,r_src_mac[47:0],16'dr_type}
output [7 :0] m_axis_mac_keep ,
output m_axis_mac_last ,
output m_axis_mac_valid ,
/*****upper layer AXIS interface*****/
input [63:0] s_axis_upper_data ,
input [55:0] s_axis_upper_user ,//用户自定义{16'dlen,3'flag,8'dtype,13'doffset,16'dID}
input [7 :0] s_axis_upper_keep ,
input s_axis_upper_last ,
input s_axis_upper_valid ,
output s_axis_upper_ready
);
3.2、模块工作过程
- 将上层的数据先进入FIFO
- 将IP报文头组完后从FIFO当中取出数据,组成完整的IP报文
- 带有简单的流控机制,当前数据包发送完毕后通知上层继续传输数据包。
四、仿真
4.1、发送端
橙色信号为仿真文件产生的上层协议数据,蓝色为组好的IP数据,发送给MAC层。
4.2、接受端
仿真当中进行了数据回环,即发送端组好的IP数据又回到了IP接收端,即图中的绿色信号,橙色信号为IP_RX模块处理好的数据并发送给上次协议,与上图对比,恢复出来的数据一致。