【斯坦福CS144】Lab5

一、实验目的

在现有的NetworkInterface基础上实现一个IP路由器。

二、实验内容

在本实验中,你将在现有的NetworkInterface基础上实现一个IP路由器,从而结束本课程。路由器有几个网络接口,可以在其中任何一个接口上接收互联网数据报。路由器的工作是根据路由表转发它得到的数据报:一个规则列表,它告诉路由器,对于任何给定的数据报:

发送到哪个接口;

下一跳的IP地址 ;

你的工作是实现一个路由器,它可以为任何给定的数据报计算出这两件事。(你不需要实现设置路由表的算法,例如RIP、OSPF、BGP或SDN控制器,只需要实现跟随路由表的算法)。

你对路由器的实现将使用带有新的Router类的Sponge库,以及在模拟网络中检查你的路由器功能的测试。本实验建立在你在上一个实验中对NetworkInterface的实现之上,但不使用你在之前实验中实现的TCP栈。IP路由器不需要知道任何关于TCP、ARP或以太网的信息(仅限IP)。我们希望你的实现将需要大约25-30行的代码。

三、实验过程

在minnow目录下输入git merge origin/check5-startercode获取Lab5

用文本编辑器打开./src/router.hh

修改代码

用文本编辑器打开./src/router.cc

修改代码

在build目录下输入make进行编译

输入make check5进行测试

测试成功,实验结束

四、实验体会

1.本实验中的 Router 实现比较简单,只需实现一下 IP 最长匹配并将数据包转发即可。

2.需要注意的是,联系计算机网络理论课和实验所学习的内容,在实际网络中,路由表会根据网络拓扑和路由策略进行配置,以确保数据包能够正确地转发到目标。路由表中的路由条目根据目标网络地址的前缀匹配来确定数据包的转发规则。当无法找到匹配的路由条目时,数据包将根据默认路由进行转发,或者如果没有默认路由,则会被丢弃。

五、代码附录

router.hh

#pragma once#include "network_interface.hh"#include <optional>
#include <queue>// A wrapper for NetworkInterface that makes the host-side
// interface asynchronous: instead of returning received datagrams
// immediately (from the `recv_frame` method), it stores them for
// later retrieval. Otherwise, behaves identically to the underlying
// implementation of NetworkInterface.
class AsyncNetworkInterface : public NetworkInterface
{std::queue<InternetDatagram> datagrams_in_ {};public:using NetworkInterface::NetworkInterface;// Construct from a NetworkInterfaceexplicit AsyncNetworkInterface( NetworkInterface&& interface ) : NetworkInterface( interface ) {}// \brief Receives and Ethernet frame and responds appropriately.// - If type is IPv4, pushes to the `datagrams_out` queue for later retrieval by the owner.// - If type is ARP request, learn a mapping from the "sender" fields, and send an ARP reply.// - If type is ARP reply, learn a mapping from the "target" fields.//// \param[in] frame the incoming Ethernet framevoid recv_frame( const EthernetFrame& frame ){auto optional_dgram = NetworkInterface::recv_frame( frame );if ( optional_dgram.has_value() ) {datagrams_in_.push( std::move( optional_dgram.value() ) );}};// Access queue of Internet datagrams that have been receivedstd::optional<InternetDatagram> maybe_receive(){if ( datagrams_in_.empty() ) {return {};}InternetDatagram datagram = std::move( datagrams_in_.front() );datagrams_in_.pop();return datagram;}
};// A router that has multiple network interfaces and
// performs longest-prefix-match routing between them.
// class Router
// {
//   // The router's collection of network interfaces
//   std::vector<AsyncNetworkInterface> interfaces_ {};//   struct Route_entry//route_entry_
//   {
//     uint32_t route_prefix{};
//     uint8_t prefix_length{};
//     std::optional<Address> next_hop;
//     size_t interface_num{};
//   };
//   //static typedef struct route_entry_ Route_entry;
//   std::vector<Route_entry> route_table_{};
class Router
{// The router's collection of network interfacesstd::vector<AsyncNetworkInterface> interfaces_ {};struct Route_entry{uint32_t route_prefix {};uint8_t prefix_length {};std::optional<Address> next_hop;size_t interface_num {};};std::vector<Route_entry> route_table_ {};//std::vector<Route_entry>::iterator longest_prefix_match_( uint32_t dst_ip );//static int match_length_( uint32_t src_ip, uint32_t tgt_ip, uint8_t tgt_len );
public:// Add an interface to the router// interface: an already-constructed network interface// returns the index of the interface after it has been added to the routersize_t add_interface( AsyncNetworkInterface&& interface ){interfaces_.push_back( std::move( interface ) );return interfaces_.size() - 1;}// Access an interface by indexAsyncNetworkInterface& interface( size_t N ) { return interfaces_.at( N ); }// Add a route (a forwarding rule)void add_route( uint32_t route_prefix,uint8_t prefix_length,std::optional<Address> next_hop,size_t interface_num );// Route packets between the interfaces. For each interface, use the// maybe_receive() method to consume every incoming datagram and// send it on one of interfaces to the correct next hop. The router// chooses the outbound interface and next-hop as specified by the// route with the longest prefix_length that matches the datagram's// destination address.void route();std::vector<Route_entry>::iterator longest_prefix_match_( uint32_t dst_ip );int match_length_( uint32_t src_ip, uint32_t tgt_ip, uint8_t tgt_len );// std::vector<Route_entry>::iterator longest_prefix_match_( uint32_t dst_ip );// int match_length_( uint32_t src_ip, uint32_t tgt_ip, uint8_t tgt_len );
};

router.cc

#include "router.hh"#include <iostream>
#include <limits>
using namespace std;// route_prefix: The "up-to-32-bit" IPv4 address prefix to match the datagram's destination address against
// prefix_length: For this route to be applicable, how many high-order (most-significant) bits of
//    the route_prefix will need to match the corresponding bits of the datagram's destination address?
// next_hop: The IP address of the next hop. Will be empty if the network is directly attached to the router (in
//    which case, the next hop address should be the datagram's final destination).
// interface_num: The index of the interface to send the datagram out on.
// void Router::add_route( const uint32_t route_prefix,
//                         const uint8_t prefix_length,
//                         const optional<Address> next_hop,
//                         const size_t interface_num )
// {
//   cerr << "DEBUG: adding route " << Address::from_ipv4_numeric( route_prefix ).ip() << "/"
//        << static_cast<int>( prefix_length ) << " => " << ( next_hop.has_value() ? next_hop->ip() : "(direct)" )
//        << " on interface " << interface_num << "\n";//   // (void)route_prefix;
//   // (void)prefix_length;
//   // (void)next_hop;
//   // (void)interface_num;//   route_table_.emplace_back(route_prefix, prefix_length, next_hop, interface_num);
//   return;
// }// void Router::route()
// {
//   for ( auto& current_interface : interfaces_ ) {
//     auto received_dgram = current_interface.maybe_receive();
//     if ( received_dgram.has_value() ) {
//       auto& dgram = received_dgram.value();
//       if ( dgram.header.ttl > 1 ) {
//         dgram.header.ttl--;
//         // NOTE: important!!!
//         dgram.header.compute_checksum();
//         auto dst_ip = dgram.header.dst;
//         auto it = longest_prefix_match_( dst_ip );
//         if ( it != route_table_.end() ) {
//           auto& target_interface = interface( it->interface_num );
//           target_interface.send_datagram( dgram, it->next_hop.value_or( Address::from_ipv4_numeric( dst_ip ) ) );
//         }
//       }
//     }
//   }
// }// std::vector<Router::Route_entry>::iterator Router::longest_prefix_match_( uint32_t dst_ip )
// {
//   auto res = route_table_.end();
//   int max_length = 0;
//   for ( auto it = route_table_.begin(); it != route_table_.end(); ++it ) {
//     int len = match_length_( dst_ip, it->route_prefix, it->prefix_length );
//     if ( len > max_length ) {
//       max_length = len;
//       res = it;
//     }
//   }
//   return res;
// }// int Router::match_length_( uint32_t src_ip, uint32_t tgt_ip, uint8_t tgt_len )
// {
//   if ( tgt_len == 0 ) {
//     return 0;
//   }//   if ( tgt_len > 32 ) {
//     return -1;
//   }//   // tgt_len < 32
//   uint8_t const len = 32U - tgt_len;
//   src_ip = src_ip >> len;
//   tgt_ip = tgt_ip >> len;
//   return src_ip == tgt_ip ? tgt_len : -1;
// }void Router::add_route( const uint32_t route_prefix,const uint8_t prefix_length,const optional<Address> next_hop,const size_t interface_num )
{cerr << "DEBUG: adding route " << Address::from_ipv4_numeric( route_prefix ).ip() << "/"<< static_cast<int>( prefix_length ) << " => " << ( next_hop.has_value() ? next_hop->ip() : "(direct)" )<< " on interface " << interface_num << "\n";route_table_.emplace_back( route_prefix, prefix_length, next_hop, interface_num );
}void Router::route()
{for (uint32_t i=0; i<interfaces_.size();i++) {auto received_dgram = interface(i).maybe_receive();if ( received_dgram.has_value() ) {auto dgram = received_dgram.value();if ( dgram.header.ttl > 1 ) {dgram.header.ttl--;dgram.header.compute_checksum();auto dst_ip = dgram.header.dst;auto it = longest_prefix_match_( dst_ip );if ( it != route_table_.end() ) {//这里的buginterface( it->interface_num ).send_datagram( dgram, it->next_hop.value_or( Address::from_ipv4_numeric( dst_ip ) ) );}}}}
}std::vector<Router::Route_entry>::iterator Router::longest_prefix_match_( uint32_t dst_ip )
{auto res = route_table_.end();int max_length = -1;for ( auto it = route_table_.begin(); it != route_table_.end(); ++it ) {int len = match_length_( dst_ip, it->route_prefix, it->prefix_length );if ( len > max_length ) {max_length = len;res = it;}}return res;
}int Router::match_length_( uint32_t src_ip, uint32_t tgt_ip, uint8_t tgt_len )
{if ( tgt_len == 0 ) {return 0;}if ( tgt_len > 32 ) {return -1;}// tgt_len < 32uint8_t len = 32U - tgt_len;src_ip = src_ip >> len;tgt_ip = tgt_ip >> len;return src_ip == tgt_ip ? tgt_len : -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/881392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot访问web中的静态资源

SpringBoot访问web中的静态资源&#xff0c;有两个方式&#xff1a; 1、SpringBoot默认指定了一些固定的目录结构&#xff0c;静态资源放到这些目录中的某一个&#xff0c;系统运行后浏览器就可以访问到 ① 关键是SpringBoot默认指定的可以存放静态资源的目录有哪些&#xff…

JavaScript 数组简单学习

目录 1. 数组 1.1 介绍 1.2 基本使用 1.2.1 声明语法 1.2.2 取值语法 1.2.3 术语 1.3 案例 1. 数组 1.1 介绍 1.2 基本使用 1.2.1 声明语法 1.2.2 取值语法 1.2.3 术语 1.3 案例

基于SpringBoot和Vue的餐饮管理系统

基于springbootvue实现的餐饮管理系统 &#xff08;源码L文ppt&#xff09;4-078 第4章 系统设计 4.1 总体功能设计 一般个人用户和管理者都需要登录才能进入餐饮管理系统&#xff0c;使用者登录时会在后台判断使用的权限类型&#xff0c;包括一般使用者和管理者,一…

星融元P4交换机:在全球芯片短缺中,为您的网络可编程之路保驾护航

当数字化转型成为新常态&#xff0c;云计算、物联网、5G和人工智能等技术正以惊人的速度进步&#xff0c;重塑了我们对网络设备性能和适应性的预期。在这场技术革新的浪潮中&#xff0c;网络的灵活性、开放性和编程能力成为了推动行业发展的关键。P4可编程交换机&#xff0c;以…

飞驰云联入围2024西门子Xcelerator公开赛50强

近日&#xff0c;备受瞩目的西门子 Xcelerator公开赛公布结果&#xff0c;经过激烈的筛选&#xff0c;Ftrans飞驰云联《Ftrans制造业数据交换安全管控解决方案》凭借优异的表现&#xff0c;成功入围 Xcelerator公开赛50强&#xff01; Xcelerator 公开赛以工信部智能制造典型场…

胤娲科技:00后揭秘——AI大模型的可靠性迷局

当智能不再“靠谱”&#xff0c;我们该何去何从&#xff1f; 想象一下&#xff0c;你向最新的GPT模型提问&#xff1a;“9.9和9.11哪个大&#xff1f;”这本应是个小菜一碟的问题&#xff0c;却足以让不少高科技的“大脑”陷入沉思&#xff0c; 甚至给出令人啼笑皆非的答案。近…

实战逆向RUST语言程序

实战为主&#xff0c;近日2024年羊城杯出了一道Rust编写的题目&#xff0c;这里将会以此题目为例&#xff0c;演示Rust逆向该如何去做。 题目名称&#xff1a;sedRust_happyVm 题目内容&#xff1a;unhappy rust, happy vm 关于Rust逆向&#xff0c;其实就是看汇编&#xff…

太阳诱电电感选型方法及产品介绍

功率电感在电子电路中被广泛应用&#xff0c;太阳诱电的功率电感从原材料开始进行研发&#xff0c;生产和销售。 本次研讨会将带领大家更加了解功率电感的选型方法&#xff0c;以及各种功率电感的种类和特征。 此外&#xff0c;也将介绍太阳诱电的最新产品阵容。本次研讨会预计…

社工字典生成工具 —— CeWL 使用手册

GitHub - digininja/CeWL: CeWL is a Custom Word List GeneratorCeWL is a Custom Word List Generator. Contribute to digininja/CeWL development by creating an account on GitHub.https://github.com/digininja/CeWL/ 0x01&#xff1a;CeWL 简介 CeWL&#xff08;Cust…

openmmlab实现图像超分辨率重构

文章目录 前言一、图像超分辨率重构简介二、mmmagic实现图像超分 前言 超分辨率重构技术&#xff0c;作为计算机视觉领域的一项重要研究课题&#xff0c;近年来受到了广泛关注。随着科技的飞速发展&#xff0c;人们对图像质量的要求越来越高&#xff0c;尤其是在智能手机、监控…

【算法】链表:24.两两交换链表中的节点

目录 1、题目链接 2、题目介绍 3、解法 4、代码 1、题目链接 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 2、题目介绍 3、解法 引入伪头节点&#xff1a; 为了处理头节点可能被交换的情况&#xff0c;我们引入一个伪头节点&#xff08;dummy no…

AI助力农作物自动采摘,基于嵌入式端超轻量级模型LeYOLO全系列【n/s/m/l】参数模型开发构建作物生产场景下番茄采摘检测计数分析系统

去年十一那会无意间刷到一个视频展示的就是德国机械收割机非常高效自动化地24小时不间断地在超广阔的土地上采摘各种作物&#xff0c;专家设计出来了很多用于采摘不同农作物的大型机械&#xff0c;看着非常震撼&#xff0c;但是我们国内农业的发展还是相对比较滞后的&#xff0…

快速生成单元测试

1. Squaretest插件 2. 依赖 <dependency><groupId>junit</groupId>

新赚米渠道,天工AI之天工宝典!

新赚米渠道&#xff0c;天工AI之天工宝典&#xff01; 引言 随着人工智能和数字创作工具的发展&#xff0c;内容创作的门槛不断降低&#xff0c;为普通用户提供了更多的赚钱机会。在这样的背景下&#xff0c;天工AI应运而生&#xff0c;凭借其强大的创作能力和最新更新的“天…

JZ2440开发板——异常与中断

以下内容源于韦东山课程的学习与整理&#xff0c;如有侵权请告知删除。 一、中断概念的引入与处理流程 1.1 中断概念的引入 这里有一个很形象的场景比喻&#xff1a;假设一位母亲在大厅里看书&#xff0c;婴儿在房间里睡觉&#xff0c;这位母亲怎样才能知道这个孩子睡醒了&a…

《Linux从小白到高手》理论篇:Linux的系统环境管理

List item 值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。本篇详细深入介绍Linux的系统环境管理。 环境变量 linux系统下&#xff0c;如果你下载并安装了应用程序&#xff0c;很有可能在键入它的名称时出现“command not found”的提示…

【PPT工具】三维绘图神器ThreeD Tools插件安装及使用

【PPT工具】三维绘图神器ThreeD Tools插件安装及使用 1 ThreeD Tools插件安装及加载1.1 ThreeD Tools插件安装1.2 ThreeD Tools插件加载 2 ThreeD Tools插件使用绘制渐变箭头 参考 ThreeD Tools是一款Microsoft PowerPoint的第三方插件&#xff0c;是“只为设计”为“般若黑洞”…

众智OA办公系统 Account/Login SQL注入漏洞复现

0x01 产品简介 众智OA办公系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台。它凭借先进的技术和人性化的设计理念,实现了信息的快速传递和自动化处理,帮助企业和机构实现信息化、自动化、智能化和标准化的办公管理。 0x02 漏洞概述 众智OA办公系统 Acc…

【C语言】使用结构体实现位段

文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体&#xff0c;而位段的声明和结构是类似的&#xff0c;它们有两个不同之处&#xff0c;如下&…

【重学 MySQL】四十四、相关子查询

【重学 MySQL】四十四、相关子查询 相关子查询执行流程示例使用相关子查询进行过滤使用相关子查询进行存在性检查使用相关子查询进行计算 在 select&#xff0c;from&#xff0c;where&#xff0c;having&#xff0c;order by 中使用相关子查询举例SELECT 子句中使用相关子查询…