educoder -- ip路由查找

任务描述
本关任务:完成路由表查找算法。

/*根据路由信息,检索目标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;
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值