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时抛弃。