1 实验内容
给定网络拓扑以及节点的路由表配置,实现路由器的转发功能,使得各节点之间能够连通并传送数据。
- 在主机上安装arptables, iptables,用于禁止每个节点的相应功能
- 运行给定网络拓扑(router_topo.py)
- 路由器节点r1上执行脚本(disable_arp.sh, disable_icmp.sh, disable_ip_forward.sh),禁止协议栈的相应功能
- 终端节点h1-h3上执行脚本disable_offloading.sh
- 在r1上执行路由器程序
- 在h1上进行ping实验
- 构造一个包含多个路由器节点组成的网络
- 手动配置每个路由器节点的路由表
- 有两个终端节点,通过路由器节点相连,两节点之间的跳数不少于3跳,手动配置其默认路由表
- 连通性测试
- 终端节点ping每个路由器节点的入端口IP地址,能够ping通
- 路径测试
- 在一个终端节点上traceroute另一节点,能够正确输出路径上每个节点的IP信息
2 实验原理
不同网络之间的数据传输需要用到路由器的数据转发功能。
当数据包到达路由器的端口时,需要查询路由表获取转发路径,在查询路由表时,数据包只包含目的地址,通常使用最长前缀匹配的方式来查找,路由表结构如下:
Dest/Mask | GW | Iface |
10.0.0.0/8 | 1.2.0.1 | eth0 |
10.0.0.0/16 | 1.3.0.1 | eth1 |
10.2.0.0/16 | 1.4.0.1 | eth2 |
Default | 1.5.0.1 | eth3 |
最长前缀匹配方式:(dst_ip & mask) == (dest & mask),且掩码长度最长(mask值最大)
2.1 路由器总体实现逻辑
- 处理ARP请求和应答
- 收到ARP请求时,如果Target Proto Addr为本端口地址,则ARP应答
- 转发数据包时,如果ARP缓存中没有相应条目,则发送ARP请求
- ARP缓存管理
- 进行ARP查询、更新等操作
- IP地址查找和IP数据包转发
- 收到数据包后,查找对应的转发端口;更新IP头部,转发数据包
- 发送ICMP数据包
- 路由表查找失败;ARP查询失败; TTL值为0;收到ping本端口的包
2.2 路由器路由查找流程
- 给定数据包,提取该数据包的目的IP地址
- 注意进行字节序转换:数据包中的都是网络字节序,本地存储的数据结构都为本地字节序
- 遍历路由表(链表),使用最长前缀匹配查找相应条目
- 如果设置默认路由,则肯定能查找到匹配路由条目
- 如果查找到相应条目,则将数据包从该条目对应端口转出,否则回复目的网络不可达(ICMP Dest Network Unreachable)。在转发数据包时:
-
- 对IP头部的TTL值进行减一操作,如果该值 <= 0,则将该数据包丢弃,并回复ICMP信息
- IP头部数据已经发生变化,需要重新设置checksum
- 在新的网络内发送数据包
-
- 将以太网头部的源MAC地址设置为转发端口的MAC地址
- 将目的MAC地址设置为对应的MAC地址
2.3 ARP查询
使用ARP机制查询下一跳IP地址对应的MAC地址:
-
- 路由器维护一个缓存ARP相关内容的数据结构:arpcache
- arpcache缓存两类数据:
-
-
- IP->MAC映射条目
- 查找不到相应条目而等待ARP应答的数据包
-
ARP缓存操作:
-
- 查找IP->MAC映射
-
-
- 如果在arp缓存中找到相应映射,则填充数据包的目的MAC地址,并转发该数据包
- 否则,将该数据包缓存在arpcache->req_list中,并发送ARP请求
-
-
- 收到新的IP->MAC映射
-
-
- 将该映射写入arp缓存中 ,如果缓存已满(最多32条),则随机替换掉其中一个
- 将在缓存中等待该映射的数据包,依次填写目的MAC地址,转发出去,并删除掉相应缓存数据包
-
-
- 每1秒钟,运行arpcache_sweep操作
-
-
- 如果一个缓存条目在缓存中已存在超过了15秒,将该条目清除
- 如果一个IP对应的ARP请求发出去已经超过了1秒,重新发送ARP请求
- 如果发送超过5次仍未收到ARP应答,则对该队列下的数据包依次回复ICMP(Destination Host Unreachable)消息,并删除等待的数据包
-
ARP协议格式:
2.4 ICMP数据包格式
- 路由表查找失败
Type: 3, Code: 0, Rest of ICMP Header: 前4字节设置为0,接着拷贝收到数据包的IP头部(>= 20字节)和随后的8字节
- ARP查询失败
Type: 3, Code: 1, Rest of ICMP Header: 同上
- TTL值减为0
Type: 11, Code: 0, Rest of ICMP Header:同上
- 收到Ping本端口的数据包( Type为8 )
Type: 0, Code: 0, Rest of ICMP Header: 拷贝Ping包中的相应字段
-
- Type 8 表示 Echo Request,即Ping请求,用于向目标主机发送Ping包。
- Type 0 表示 Echo Reply,即Ping应答,用于回应Ping请求。
3 实验流程与结果分析
3.1 实验具体实现
代码的实现逻辑自顶向下推导,如下框图所示:
对于数据包的处理包含两条逻辑:转发数据包类型还是icmp通信协议类型。对于数据包的转发需要考虑对路由表的遍历、最长前缀匹配以及是否满足转发条件;对于icmp通信协议类型则根据不同typ