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.hh和router.cc,实现Router类。
还是从测试代码入手tests/router.cc。
总的是一个Network类
包含一个
Router。Router包含多个NetworkInterface。包含多个
Host。Host可看成一台电脑,有自己的ip地址和名字,有自己的NetworkInterface。NetworkInterface其实可看成网卡。
Network初始化时添加多个Host。用add_route添加多条路由数据。
看pdf的图2,可与上述数据对上。
network_simulator开始测试。
用某个Host的send_to生成一个发到指定地址的ip包。用这个Host的NetworkInterface::send_datagram发出。
相当于放到网卡buffer,待实际发送。
类似于调socket接口,发到缓冲区。
Host的expect记下这个ip包。
network.simulate开始模拟网络数据处理流程。
_router.route是我们的路由逻辑。
simulate_physical_connections进行一系列exchange_frames。
exchange_frames调deliver,实现2个或3个网卡两两交换数据。
deliver用maybe_send取出第1个网卡buffer中的EthernetFrame。
如果有2个参数,第2个网卡通过recv_frame收第1个网卡的frame。
如果有3个参数,后2个网卡通过recv_frame收第1个网卡的frame。
循环直到取完数据。
看图2,这个函数模拟的是路由器上每个口和连到它的host之间的数据交换。
路由器上各个口之间并没有数据交换。
然后每个host开始check,用maybe_receive检查网卡里的数据是否符合预期。
再看图2。我们要做的事是处理路由器上各个口之间的数据交换。
也就是联通不同口/网络,也就是所谓的路由。
add_route的route_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时抛弃。