任务描述
根据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;
}