cs144网络课程5 IP router#

环境#

https://cs144.github.io/assignments/check5.pdf

commit lab4的代码。

merge lab5的代码
git merge origin/check5-startercode

编译/测试
cmake --build build
cmake --build build --target check5

流程#

本次要实现ip路由器。

我们要改的代码是router.hhrouter.cc,实现Router类。
还是从测试代码入手tests/router.cc

总的是一个Network

  • 包含一个RouterRouter包含多个NetworkInterface

  • 包含多个HostHost可看成一台电脑,有自己的ip地址和名字,有自己的NetworkInterfaceNetworkInterface其实可看成网卡。

Network初始化时添加多个Host。用add_route添加多条路由数据。

看pdf的图2,可与上述数据对上。

network_simulator开始测试。

用某个Hostsend_to生成一个发到指定地址的ip包。用这个Host的NetworkInterface::send_datagram发出。
相当于放到网卡buffer,待实际发送。
类似于调socket接口,发到缓冲区。

Host的expect记下这个ip包。

network.simulate开始模拟网络数据处理流程。

_router.route是我们的路由逻辑。

simulate_physical_connections进行一系列exchange_frames
exchange_framesdeliver,实现2个或3个网卡两两交换数据。
delivermaybe_send取出第1个网卡buffer中的EthernetFrame
如果有2个参数,第2个网卡通过recv_frame收第1个网卡的frame。
如果有3个参数,后2个网卡通过recv_frame收第1个网卡的frame。
循环直到取完数据。
看图2,这个函数模拟的是路由器上每个口和连到它的host之间的数据交换。
路由器上各个口之间并没有数据交换。

然后每个host开始check,用maybe_receive检查网卡里的数据是否符合预期。

再看图2。我们要做的事是处理路由器上各个口之间的数据交换。
也就是联通不同口/网络,也就是所谓的路由。

add_routeroute_prefix是ip地址。
prefix_length用前缀长度指定子网掩码,比如192.168.0.0/24就是前24位固定,子网ip从192.168.0.0到192.168.0.255。
172.16.0.0/16就是固定前16位,子网ip从172.16.0.0到172.16.255.255
next_hop写死了此host发ip包的目标ip地址。
interface_num就是接口的index,可通过id拿到接口。

_router.route里,遍历每个接口,用maybe_receive取数据,发到目标接口。

测试代码发了这样的ip包。
auto dgram_sent = network.host( "applesauce" ).send_to( network.host( "cherrypie" ).address() );
applesauce发ip包到cherrypie的ip地址192.168.0.2。
applesauce的网卡先和它绑定的eth0交换数据。然后我们遍历到路由器上的接口eth0时就能得到applesauce的ip包。
再查192.168.0.2跟哪些接口匹配,选匹配长度最长的那个。调这个接口的send_datagram完成路由。
都暴力遍历数组即可,不需要实现更快的算法。
都匹配不到的话,一定会落在0.0.0.0/0上,因为它本质上不需要匹配。

收到ip包时ttl–,小于1时抛弃。