基于 py 路由器转发内容
实验内容
实验内容一
运行给定网络拓扑(router_topo.py)
在 r1 上执行路由器程序./router,进行数据包的处理
在 h1 上进行 ping 实验
- Ping 10.0.1.1 (r1),能够 ping 通
- Ping 10.0.2.22 (h2),能够 ping 通
- Ping 10.0.3.33 (h3),能够 ping 通
- Ping 10.0.3.11,返回 ICMP Destination Host Unreachable
- Ping 10.0.4.1,返回 ICMP Destination Net Unreachable
实验内容二
构造一个包含多个路由器节点组成的网络
- 手动配置每个路由器节点的路由表
- 有两个终端节点,通过路由器节点相连,两节点之间的跳数不少于 3 跳,手动配置其默认路由表
连通性测试
- 终端节点 ping 每个路由器节点的入端口 IP 地址,能够 ping 通
路径测试
- 在一个终端节点上 traceroute 另一节点,能够正确输出路径上每个节点的 IP 信息
设计思路
ARP 数据包处理
arp.c 中 handle_arp_packet
函数
当每一个端口收到数据包后,数据链路层若查询到这是一个 ARP 的包,则处理函数跳转到 handle_arp_packet
函数。
handle_arp_packet
函数需要比对端口 IP。若该端口 IP 与数据包的目的 IP 相同,则进一步处理:
- 若该包是 ARP 应答包,则说明该端口需要将源 IP 和源 MAC 地址的映射插入到 ARP Cache 中,即调用
arpcache_insert
处理。 - 若该包是 ARP 请求包,则向发送请求的端口回复 ARP 包,传递该端口 IP 和 MAC 地址的解析信息,即调用
arp_send_reply
函数进行 ARP 应答。
arp.c 中 arp_send_reply
函数
当 ARP 请求的目的 IP 对应的收到 ARP 请求包,则向发送请求的端口回复 ARP 包,传递该端口 IP 和 MAC 地址的解析信息。
arp_send_reply
函数需要根据 ARP协议
和接收到的 ARP请求
进行组包应答,具体实现函数如下:
void arp_send_reply(iface_info_t *iface, struct ether_arp *req_hdr)
{
char * packet = (char *) malloc(ETHER_HDR_SIZE + sizeof(struct ether_arp));
struct ether_header * ether_hdr = (struct ether_header *)packet;
struct ether_arp * ether_arp_pkt = (struct ether_arp *)(packet + ETHER_HDR_SIZE);
ether_hdr->ether_type = htons(ETH_P_ARP);
memcpy(ether_hdr->ether_shost, iface->mac, ETH_ALEN);
memcpy(ether_hdr->ether_dhost, req_hdr->arp_sha, ETH_ALEN);
ether_arp_pkt->arp_hrd = htons(ARPHRD_ETHER);
ether_arp_pkt->arp_pro = htons(ETH_P_IP);
ether_arp_pkt->arp_hln = (u8)ETH_ALEN;
ether_arp_pkt->arp_pln = (u8)4;
ether_arp_pkt->arp_op = htons(ARPOP_REPLY);
memcpy(ether_arp_pkt->arp_sha, iface->mac, ETH_ALEN);
ether_arp_pkt->arp_spa = htonl(iface->ip);
memcpy(ether_arp_pkt->arp_tha, req_hdr->arp_sha, ETH_ALEN);
ether_arp_pkt->arp_tpa = req_hdr->arp_spa;
iface_send_packet(iface, packet, ETHER_HDR_SIZE + sizeof(struct ether_arp));
}
结果验证
实验一结果验证(在 h1 上进行 ping 实验)
Ping 10.0.1.1 (r1),能够 ping 通
实验结果如下:
上述结果符合预期,即该实验成功。
Ping 10.0.2.22 (h2),能够 ping 通
实验结果如下:
上述结果符合预期,即该实验成功。
Ping 10.0.3.33 (h3),能够 ping 通
实验结果如下:
上述结果符合预期,即该实验成功。
Ping 10.0.3.11,返回 ICMP Destination Host Unreachable
实验结果如下:
上述结果符合预期,即该实验成功。
Ping 10.0.4.1,返回 ICMP Destination Net Unreachable
实验结果如下:
上述结果符合预期,即该实验成功。
实验二结果验证
本实验构造了一个含有两个路由器,两个主机的网络,路由器 R1 和 R2 相连,主机 H1 与 R1 相连 H2 与 R2 相连。Python 配置如下:
h1.cmd('ifconfig h1-eth0 10.0.1.11/24')
h2.cmd('ifconfig h2-eth0 10.0.2.22/24')
h1.cmd('route add default gw 10.0.1.1')
h2.cmd('route add default gw 10.0.2.1')
r1.cmd('ifconfig r1-eth0 10.0.1.1/24')
r1.cmd('ifconfig r1-eth1 10.0.3.1/24')
r1.cmd('route add -net 10.0.2.0 netmask 255.255.255.0 gw 10.0.3.2 dev r1-eth1')
r2.cmd('ifconfig r2-eth0 10.0.2.1/24')
r2.cmd('ifconfig r2-eth1 10.0.3.2/24')
r2.cmd('route add -net 10.0.1.0 netmask 255.255.255.0 gw 10.0.3.1 dev r2-eth1')
连通性测试
主机 H1 和 H2 相互 Ping 对方,结果如下:
由上图可知,两个节点可以互相 Ping 通,因此两主机节点连通。
路径测试
在一个终端节点上 traceroute 另一节点,能够正确输出路径上每个节点的 IP 信息。
由上图可知,两个节点可以 traceroute 符合路由表预期。