educoder -- 基于RIP协议的路由表更新

任务描述
根据RIP协议规则更新本地路由表。

#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;
}
/*删除路由表*/
void delete_routetable(struct Route *rtinfo){
	struct Route *p=rtinfo;
	while(rtinfo!=NULL){
    	p=rtinfo->rt_next;
    	free(rtinfo);
    	rtinfo=p;
    }
}
/* 从配置文件中创建静态路由表 */
struct Route* init_routetable(char *route_cfg, struct Route* rtinfo) {
    char str[100];int num, loc[10]; struct Route *p = NULL; struct Route *rt; uint32 ip, mask,maxnet,maxnif;
    FILE *f = fopen(strtrim(route_cfg), "r");
    if (f == NULL) {
        printf("打开接口配置文件失败%s\n", route_cfg);
        return rtinfo;
    }
    while (fgets(str, 100, f) != NULL) {
        strtrim(str);
        num = strsplit(str, ',', loc);
        if (num != 4) {
            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_distance = atoi(str+loc[3]);
        p->rt_next = rtinfo;
        rtinfo = p;
    }
    fclose(f);
     //路由下一跳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;
    }
    return rtinfo;
}
/*根据接口配置,更新路由表,以方便查询*/
struct Route* update_routetable(struct NetIf* netif, struct Route* rtinfo) {
    struct Route *rt; uint32 ip, mask,maxnet,maxnif;
  
    //将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_distance = 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_distance = 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_distance = 1 ;
        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_distance = 0 ;
        rt->rt_nexthop = 0;
        rt->rt_next = rtinfo;
        rtinfo = rt;
    }
    return rtinfo;
}
/*根据邻接路由信息,更新本地路由表*/
struct Route* adj_update_routetable(struct Route *rtinfo, struct Route *adj_rtinfo) {
    struct Route *res = NULL;
/***************** Begin 1 *****************/
struct Route *p, *temp;
while(adj_rtinfo != NULL){
    p = rtinfo;
    while(p != NULL){
        if(p->rt_net == adj_rtinfo->rt_net){
            if(p->rt_nexthop == adj_rtinfo->rt_nexthop){
                p->rt_distance = adj_rtinfo->rt_distance + 1;
                break;
            }

            if(p->rt_distance>adj_rtinfo->rt_distance + 1){
                p->rt_distance = adj_rtinfo->rt_distance + 1;
                p->rt_nexthop=adj_rtinfo->rt_nexthop;
                break;
            }
            break;
        }
        p=p->rt_next;
    }
    if(p==NULL){
        temp = (struct Route*)malloc(sizeof(struct Route));
        temp->rt_ifnum = -1;
        temp->rt_net = adj_rtinfo->rt_net;
        temp->rt_mask = adj_rtinfo->rt_mask;
        temp->rt_nexthop = adj_rtinfo->rt_nexthop;
        temp->rt_distance = adj_rtinfo->rt_distance + 1;
        uint32 maxnif = 0;
        uint32 maxnet = 0;
        for(int i = 1; netif[i].ni_device > 0; i++){
            if((temp->rt_nexthop&netif[i].ni_mask) == (netif[i].ni_ip & netif[i].ni_mask)){
                if((temp->rt_nexthop & netif[i].ni_mask) >= maxnet){
                    maxnet = temp->rt_nexthop & netif[i].ni_mask;
                    maxnif = i;
                }
            }
        }
        if(maxnif > 0){
            temp->rt_ifnum = maxnif;
        }
        temp->rt_next = rtinfo;
        rtinfo = temp;
    }
    adj_rtinfo = adj_rtinfo->rt_next;
}
res = rtinfo;
//下一跳相同,更新距离

//下一跳不同,距离变小,替换下一跳,并更新距离

//新网络,增加路由


/***************** End 1 *******************/
	return res;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值