RIP协议设计 毕业课程设计报告包含源代码Word下载.docx
《RIP协议设计 毕业课程设计报告包含源代码Word下载.docx》由会员分享,可在线阅读,更多相关《RIP协议设计 毕业课程设计报告包含源代码Word下载.docx(22页珍藏版)》请在冰豆网上搜索。
对于RIP报文有两种版本的格式,Version1和Version2。
两种报文稍有不同,如所示分别为RIPv1和RIPV2:
命令
版本
全零
地址族
IP地址
全零
度量值
前20个字节的重复
路由选择
地址族
路径标签
子网掩码
下一个站点的IP地址
RIP报文中至多可以出现25个AFI、互联网络地址和度量域。
这样允许使用一个RIP报文来更新一个路由器中的多个路由表项。
包含多个路由表项的RIP报文只是简单地重复从AFI到度量域的结构,其中包括所有的零域。
图表2显示了路由信息域中只带一个目的地的RIP报文。
1字节命令
1字节版本
2字节0域
2字节
AFI
0域
4字节
网络地
址
度量
图表2
图表3具有两个表项的RIP报文
1字节
版本
0域
两字节
网络地址
网络
地址
图表3
地址域可以既包括发送者的地址也包括发送者路由表中的一系列IP地址。
请求报文含有一个表项并包括请求者的地址。
应答报文可以包括至多25个RIP路由表项。
2.2RIP的工作原理
RIP协议是矢量距离算法在局域网上的直接实现,RIP将协议的参加者分为主动机和被动机两种。
主动机主动地向外广播路径刷新报文,被动机被动地接受路径刷新报文。
一般情况下,网关作主动机,主机作被动机。
RIP规定,网关每30秒向外广播一个报文,报文信息来自本地路由表。
RIP的度量是基于跳数()
水平分割保证路由器记住每一条路由信息的来源,并且不在收到这条信息的端口上再次发送它。
这是保证不产生路由循环的最基本措施。
毒性逆转(poison reverse)
当一条路径信息变为无效之后,路由器并不立即将它从路由表中删除,而是用16,即不可达的度量值将它广播出去。
这样虽然增加了路由表的大小,但对消除路由循环很有帮助,它可以立即清除相邻路由器之间的任何环路。
触发更新(trigger update)
当路由表发生变化时,更新报文立即广播给相邻的所有路由器,而不是等待30秒的更新周期。
同样,当一个路由器刚启动RIP时,它广播请求报文。
收到此广播的相邻路由器立即应答一个更新报文,而不必等到下一个更新周期。
这样,网络拓扑的变化会最快地在网络上传播开,减少了路由循环产生的可能性。
抑制计时( timer)
一条路由信息无效之后,一段时间内这条路由都处于抑制状态,即在一定时间内不再接收关于同一目的地址的路由更新。
如果,路由器从一个网段上得知一条路径失效,然后,立即在另一个网段上得知这个路由有效。
这个有效的信息往往是不正确的,抑制计时避免了这个问题,而且,当一条链路频繁起停时,抑制计时减少了路由的浮动,增加了网络的稳定性。
即便采用了上面的4种方法,路由循环的问题也不能完全解决,只是得到了最大程度的减少。
一旦路由循环真的出现,路由项的度量值就会出现计数到无穷大(CounttoInfinity)的情况。
这是因为路由信息被循环传递,每传过一个路由器,度量值就加1,一直加到16,路径就成为不可达的了。
RIP选择16作为不可达的度量值是很巧妙的,它既足够的大,保证了多数网络能够正常运行,又足够小,使得计数到无穷大所花费的时间最短。
有些网络是NBMA(Non-BroadcastMultiAccess,非广播多路访问)的,即网络上不允许广播传送数据。
对于这种网络,RIP就不能依赖广播传递路由表了。
解决方法有很多,最简单的是指定邻居(neighbor),即指定将路由表发送给某一台特定的路由器。
2.3主要函数模块说明
2.3.1get_local_ip()
该函数主要是通过gethostname()函数获取本地ip,并将其赋值给local_addr;
2.3.2broadcast_rip_packet()
首先将包转换成网络读取数据的顺序,然后将要广播的ip和协议封装在一个结构体中,从定义的RIP端口520广播出去。
print_rip_packet()-->
rp_inverse_()-->
socket()-->
sendto()-->
close()
2.3.3timer_routine()
使用线程的pthread_mutex_lock()和pthread_mutex_unlock()对路由表更新模块进行保护,以防资源被更改。
2.3.4receive_rip_packet()
从网络上接受包,并解析结构体过去包的ip,通过520端口获得包,并检查包的格式,然后分析包的命令是请求还是相应给于相应的处理。
bind()-->
recvfrom()-->
rp_inverse_ntoh()-->
check_rip_packet()
2.3.5._addrip;
·
unsignedintzero2;
unsignedintzero3;
unsignedintmetric;
};
structrip_packet
{
unsignedcharcommand;
unsignedcharversion;
unsignedshortzero;
structrip_entryrip_entries[RIP_MAX_ENTRY];
structroute_entry
structin_addrdest;
structin_addrnext;
time_ttimer;
intvalid;
intflag;
structrip_packetcurrent_rip_packet;
structrip_packetcurrent_rip_packet_r;
intcurrent_rip_count;
structroute_entryrouting_table[ROUTE_MAX_ENTRY];
intcurrent_route_count;
intsockfd;
pthread_mutex_trt_mutex;
pthread_mutex_tcrp_mutex;
structin_addrlocal_addr;
voidprint_routing_table();
voidprint_message();
voidprint_rip_packet();
intcheck_rip_packet();
intcalculate_rip_metric(intrip_entry_number);
voidreset_rip_packet(intcommand);
voidinit_routing_table();
voidinit_all();
voidgen_request_all();
voidsend_rip_packet_to(structin_addrdest_ip);
voidbroadcast_rip_packet();
voidreceive_rip_packet();
void_addrsource_ip);
voidstart_rip_daemon();
voidupdate_routing_table();
void*timer_routine();
char*local_ip[LOCAL_ROUTE_ENTRY]={
"
195.51.0.0"
195.51.0.1"
195.51.0.2"
195.51.0.3"
195.51.0.4"
195.51.0.5"
195.51.0.6"
195.51.0.7"
195.51.0.8"
195.51.0.9"
#endif
RIP.c
#include"
myrip..()
void*tempptr=&
current_rip_packetmand;
unsignedshort*temp=(unsignedshort*)(tempptr);
unsignedshort*temp=(unsignedshort*)(&
current_rip_packet);
*temp==);
for(inti=0;
i<
current_rip_count;
i++)
{
current_rip_packet.rip_entries[i].metric==sizeof(buf);
constchar*buf_ptr;
printf("
currentroutingtable----\n"
);
for(inti=0;
current_route_count;
%dthre:
\n"
i);
buf_ptr=inet_ntop(AF_INET,&
routing_table[i].dest,buf,buf_len);
destination:
%s"
buf);
next:
metric:
%d\n\n"
routing_table[i].metric);
}
}
voidprint_message(constchar*title,constchar*content)
\n%s---\n"
title);
-%s-\n"
content);
endofmessage\n"
voidprint_rip_packet()
rippacketcontains%dentries:
-\n"
current_rip_count);