基于py的网络路由实验

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

基于 py 的网络路由实验

实验内容

实验内容一

基于已有代码框架,实现路由器生成和处理 mOSPF Hello/LSU 消息的相关操作,构建一致性链路状态数据库

  • 运行网络拓扑(topo.py)
  • 在各个路由器节点上执行 disable_arp.sh, disable_icmp.sh, disable_ip_forward.sh),禁止协议栈的相应功能
  • 运行./mospfd,使得各个节点生成一致的链路状态数据库

实验内容二

基于实验一,实现路由器计算路由表项的相关操作

  • 运行实验

    • 运行网络拓扑(topo.py)
    • 在各个路由器节点上执行 disable_arp.sh, disable_icmp.sh, disable_ip_forward.sh),禁止协议栈的相应功能
    • 运行./mospfd,使得各个节点生成一致的链路状态数据库
    • 等待一段时间后,每个节点生成完整的路由表项
    • 在节点 h1 上 ping/traceroute 节点 h2
    • 关掉某节点或链路,等一段时间后,再次用 h1 去 traceroute 节点 h2

测试与验证

  • 各个节点生成一致的链路状态数据库
  • tracerout 能获取正确结果

设计思路

生成和处理 mOSPF Hello 消息

void *sending_mospf_hello_thread(void *param) 函数

该函数被一个线程单独开启运行,每个节点周期性(5 秒)节点就向外界宣告自己的存在,并发送 mOSPF Hello 消息:包括 router ID, 端口的 mask 等消息。

该节点发送 IP 包的目的 IP 地址为 224.0.0.5,目的 MAC 地址为 01:00:5E:00:00:05

void handle_mospf_hello(iface_info_t *iface, const char *packet, int len) 函数

每个端口在收到一个 mOSPF HELLO 包以后,调用该函数进行处理。该函数需要从 mOSPF HELLO 包中获取 rid、IP、MASK 等信息。

若该发送该包的节点信息以及存在于 iface 中的 nbr_list 中,则更新其到达时间。否则,将该节点的相关信息保存在 iface 中的 nbr_list 中。

void *checking_nbr_thread(void *param) 函数

该函数负责处理邻居列表中老化的节点。若一个节点超过 3*hello_interval 没有更新,则代表该节点老化,需要被清理掉。

生成和处理 mOSPF LSU 消息

void sending_mospf_lsu() 函数

该函数负责组包并发送 mOSPF LSU 消息,会被线程函数 sending_mospf_lsu_thread 以 30 秒为周期进行调用发送。在该节点的邻居列表发生变动时,也会调用该函数发送 LSU 消息。

该函数向邻居节点发送的链路状态信息为:

  • 该节点 ID (mOSPF Header)、邻居节点 ID、网络和掩码 (mOSPF LSU)
  • 当端口没有相邻路由器时,也要表达该网络,邻居节点 ID 设为为 0 (即端口连接局域网内部节点)
  • 序列号(sequence number),每次生成链路状态信息时加 1
  • 目的 IP 地址为邻居节点相应端口的 IP 地址,目的 MAC 地址为该端口的 MAC 地址(通过调用 ip_send_packet 函数发包)。

void handle_mospf_lsu(iface_info_t *iface, char *packet, int len) 函数

该函数在收到收到 LSU 消息后被调用进行处理数据包。如果之前未收到该节点的链路状态信息,或者该信息的序列号更大,则更新链路状态数据库,TTL 减 1,如果 TTL 值大于 0,则向除该端口以外的端口转发该消息。

void *checking_database_thread(void *param) 函数

该线程函数负责周期性的检查失效节点。当数据库中一个节点的链路状态超过 40 秒未更新时,表明该节点已失效,将对应条目删除。另外,在该函数会调用 update_rtable 进行路由表项的更新。

void update_router (int prev[], int dist[]) 函数

该函数根据 Dijkstra 算法获得的节点拓扑信息来进行更新路由表。对于每个节点,会根据 Dijkstra 算法匹配到前序节点。用递归的方式前递可以找到对于本节点而言,每一个其他的节点的下一条节点是多少,并以此更新路由表,从而确定到其他网络的下一跳网关地址、源节点的转发端口。

另外,实验初始化时,会从内核中读入到本地网络的路由条目,更新路由表时需要区分这些条目和计算生成的路由条目。本设计中非默认路由表会在一开始删去。

结果验证

本实验实验结果如下:

在这里插入图片描述

可以从上图中看出,不同节点之间可以通过 HELLO 和 LSU 信息,生成一致的链路状态信息。

另外 tracerout 的结果表明可以通过 Dijkstra 算法生成正确的路由表。并在网络状态改变(link r2 r4 down)时,自动生成新的路由表。


网站公告

今日签到

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