基于py路由器转发内容

发布于:2022-12-13 ⋅ 阅读:(297) ⋅ 点赞:(0)

基于 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 符合路由表预期。


网站公告

今日签到

点亮在社区的每一天
去签到