任务描述
本关任务:完成路由表查找算法。
/*根据路由信息,检索目标ip下一跳ip及负责转发的接口*/
struct Route* rtget(struct RouteInfo*rtinfo, uint32 dstip) ;
#include"network_protocol.h"
/* 从配置文件中初始化接口参数 */
struct NetIf* init_netif(char *netif_cfg, struct NetIf* netif) {
FILE *f = fopen(strtrim(netif_cfg), "r");
if (f == NULL) {
printf("打开接口配置文件失败:%s\n", netif_cfg);
return netif;
}
char str[100], *p = NULL;
int loc[10], num, nifnum = 0;
//伪接口
netif[0].ni_device = 0;
netif[0].ni_ip = 0;
netif[0].ni_mask = 0;
for (int i = 0; i < ETH_ADDR_LEN; i++)
netif[0].ni_hwa[i] = 0;
while (fgets(str, 100, f) != NULL) {
strtrim(str);
num = strsplit(str, ',', loc);
if (num != 3) {
printf("netif_cfg配置文件错误!\n");
return netif;
}
nifnum++;
netif[nifnum].ni_device = nifnum;
netif[nifnum].ni_ip = str2ip(str);
netif[nifnum].ni_mask = str2ip(str + loc[1]);
p = str2hex(str + loc[2]);
for (int i = 0; i < ETH_ADDR_LEN; i++)
netif[nifnum].ni_hwa[i] = (p[i * 2] << 4) + p[i * 2 + 1];
}
netif[nifnum + 1].ni_device = -1;
fclose(f);
return netif;
}
/* 从配置文件中创建静态路由表 */
struct Route* init_routetable(char *route_cfg, struct Route* rtinfo) {
FILE *f = fopen(strtrim(route_cfg), "r");
if (f == NULL) {
printf("打开接口配置文件失败%s\n", route_cfg);
return rtinfo;
}
char str[100];
int num, loc[10];
struct Route *p = NULL;
while (fgets(str, 100, f) != NULL) {
strtrim(str);
num = strsplit(str, ',', loc);
if (num != 3) {
printf("route_cfg配置文件错误!\n");
return rtinfo;
}
p = (struct Route*)malloc(sizeof(struct Route));
p->rt_ifnum = -1;
p->rt_net = str2ip(str);
p->rt_mask = str2ip(str + loc[1]);
p->rt_nexthop = str2ip(str + loc[2]);
p->rt_next = rtinfo;
rtinfo = p;
}
fclose(f);
return rtinfo;
}
/*根据接口配置,更新路由表,以方便查询*/
struct Route* update_routetable(struct NetIf* netif, struct Route* rtinfo) {
struct Route *rt; uint32 ip, mask,maxnet,maxnif;
//路由下一跳ip对应的设备号
rt = rtinfo;
while (rt != NULL) {
maxnif=0;maxnet=0;
for (int i = 1; netif[i].ni_device > 0; i++) {
if ((rt->rt_nexthop&netif[i].ni_mask) == (netif[i].ni_ip&netif[i].ni_mask)) {
//找到网络地址匹配最长的接口
if((rt->rt_nexthop&netif[i].ni_mask) >=maxnet){
maxnet=rt->rt_nexthop&netif[i].ni_mask ;
maxnif=i;
}
}
}
if(maxnif>0)
rt->rt_ifnum = maxnif;
rt = rt->rt_next;
}
//将127回环址加入路由表
rt = (struct Route*)malloc(sizeof(struct Route));
rt->rt_net = str2ip("127.0.0.0");
rt->rt_mask = htonl(0xff000000);
rt->rt_ifnum = 0;
rt->rt_nexthop = 0;
rt->rt_next = rtinfo;
//根据接口ip和mask添加路由,以方便查找
rtinfo = rt;
for (int i = 1; netif[i].ni_device > 0; i++) {
ip = netif[i].ni_ip;
mask = netif[i].ni_mask;
//将自己的ip加入路由表
rt = (struct Route*)malloc(sizeof(struct Route));
rt->rt_net = ip;
rt->rt_mask = 0xffffffff;
rt->rt_ifnum = 0;
rt->rt_nexthop = 0;
rt->rt_next = rtinfo;
rtinfo = rt;
//将自己的网络加入路由表
rt = (struct Route*)malloc(sizeof(struct Route));
rt->rt_net = ip & mask;
rt->rt_mask =mask;
rt->rt_ifnum = i;
rt->rt_nexthop = 0;
rt->rt_next = rtinfo;
rtinfo = rt;
//将自己的网络广播地址加入路由表
rt = (struct Route*)malloc(sizeof(struct Route));
rt->rt_net = (ip&mask) | (~mask);
rt->rt_mask = 0xffffffff;
rt->rt_ifnum = 0;
rt->rt_nexthop = 0;
rt->rt_next = rtinfo;
rtinfo = rt;
}
return rtinfo;
}
/*根据路由信息,检索目标ip下一跳ip及负责转发的接口*/
struct Route* rtget(struct Route *rtinfo, uint32 dstip) {
struct Route *res = NULL;
/***************** Begin 1 *****************/
struct Route *rt = rtinfo;
uint32 max = 0;
while(rt != NULL){
if(rt->rt_net == (dstip&rt->rt_mask)){
if((dstip&rt->rt_mask) >= max){
res = rt;
max = (dstip&rt->rt_mask);
}
}
rt = rt->rt_next;
}
/***************** End 1 *******************/
return res;
}