NetRiver - IPv6协议转发实验
来源:互联网 发布:魔眼软件 编辑:程序博客网 时间:2024/04/24 14:12
IPv6的协议转发实验在收发的基础上增加了转发功能,即要求查询路由表(Route table)并向相应地址转发。需要实现的函数接口也多了两个,一个是路由表的初始化,另一个是向路由表添加元素。路由表其实就是要建立并维护一个检索数据结构。
数据结构的思路有二,其一是通过散列函数实现复杂度为
本题中需要我们比较的是路由表项的目标地址前缀与IP包的目标地址前缀是否符合,前缀的长度相当于IPv4的子网掩码的定义。考虑到这一点,采用Trie树作为检索结构比较理想,根据最长匹配原则,查询的时候需要遍历对应的分支,查询次数是常数时间复杂度,记录最深的匹配节点即可。维护的复杂度比查询还要略低,同样是常数时间复杂度。因为题目给的路由表很短,树的稀疏度很大,可以进一步采取压缩优化。
不过实验实际给的路由表真的很短,所以这里就直接用数组暴力比较了,毕竟懒癌晚期……另外,本实验添加的路由表项中的masklen(严格来说是prefixlen)经测试不需要转字节序。代码如下。
/** MIT license* Copyright © 2016 Maristie* * Permission is hereby granted, free of charge, to any person obtaining a copy of this software* and associated documentation files (the "Software"), to deal in the Software without restriction,* including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions:* The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software.* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/#include "sysinclude.h"extern void ipv6_fwd_DiscardPkt(char *pBuffer, int type);extern void ipv6_fwd_SendtoLower(char *pBuffer, int length, ipv6_addr *nexthop);extern void getIpv6Address(ipv6_addr *pAddr);extern void ipv6_fwd_LocalRcv(char *pBuffer, int length);static stud_ipv6_route_msg route_table[50];static int table_size = 0;void stud_ipv6_Route_Init(){ return;}void stud_ipv6_route_add(stud_ipv6_route_msg *proute){ route_table[table_size++] = *proute; return;}int stud_ipv6_fwd_deal(char *pBuffer, int length){ // get destination address BYTE des_addr[16]; memcpy(des_addr, pBuffer + 24, 16); // counters declaration int i, j; // check hoplimit if (pBuffer[7] == 0) { ipv6_fwd_DiscardPkt(pBuffer, STUD_IPV6_FORWARD_TEST_HOPLIMIT_ERROR); return 1; } // check destination // get local address ipv6_addr *local_addr = (ipv6_addr*)malloc(sizeof(ipv6_addr)); getIpv6Address(local_addr); // compare destination and local address int flag = 0; for (i = 0; i < 16; ++i) if (des_addr[i] != local_addr->bAddr[i]) { flag = 1; break; } if (flag == 0) { ipv6_fwd_LocalRcv(pBuffer, length); return 0; } // not local host, then search route table unsigned int max_masklen = 0; ipv6_addr *nexthop = (ipv6_addr*)malloc(sizeof(ipv6_addr)); // used to record the next hop // traverse the route table for (i = 0; i < table_size; ++i) { unsigned int masklen = route_table[i].masklen; flag = 0; // flag == 0 means they have the same prefix, or else they're different for (j = 0; j < masklen / 8; ++j) if (des_addr[j] != route_table[i].dest.bAddr[j]) { flag = 1; break; } if (flag == 0 && des_addr[j] >> ((j + 1) * 8 - masklen) != route_table[i].dest.bAddr[j] >> ((j + 1) * 8 - masklen)) flag = 1; // judge flag if (flag == 0 && masklen > max_masklen) { max_masklen = masklen; *nexthop = route_table[i].nexthop; } } // if no route found if (max_masklen == 0) { fwd_DiscardPkt(pBuffer, STUD_IPV6_FORWARD_TEST_NOROUTE); return 1; } // route found, then prepare for sending // set hoplimit --pBuffer[7]; // send ipv6_fwd_SendtoLower(pBuffer, length, nexthop); return 0;}
0 0
- NetRiver - IPv6协议转发实验
- NetRiver - IPv6协议收发实验
- NetRiver - IPv4协议转发实验
- NetRiver - 滑动窗口协议实验
- NetRiver - IPv4协议收发实验
- 解析NetRiver滑动窗口协议实验
- IPv6协议及实验
- 网络实验 ipv6协议收发实验
- IPV6(转发)
- IPV6协议
- ipv6网段 防火墙 转发功能分析
- CCNA(新版)-ipv6网络中启用-ospfv3路由协议配置实验
- xp安装Ipv6协议
- IPv6邻居发现协议
- IPv6协议相关基础
- ipv6协议报文格式
- IPv6邻居发现协议
- 网络协议之ipv6
- JMeter参数化方法
- Smack Roster获取不到名册
- 版本校验,正则分享
- 常用插件
- nginx、fastCGI、php-fpm关系梳理
- NetRiver - IPv6协议转发实验
- 十一章 上机练习4 + 5
- Android 解决使用Log打印日志的时候中文是乱码(unicode)
- 安卓定时通知的研究与实现思路
- Assign Cookies(分蛋糕)
- 深度学习应用
- oracle数据库导入导出之imp,exp,impdp,expdp等工具的使用
- 在ubuntu16.04下载&编译android源代码
- socket 基本套接字1