RIP协议设计 毕业课程设计报告包含源代码.docx

上传人:b****4 文档编号:3739865 上传时间:2022-11-25 格式:DOCX 页数:22 大小:21.98KB
下载 相关 举报
RIP协议设计 毕业课程设计报告包含源代码.docx_第1页
第1页 / 共22页
RIP协议设计 毕业课程设计报告包含源代码.docx_第2页
第2页 / 共22页
RIP协议设计 毕业课程设计报告包含源代码.docx_第3页
第3页 / 共22页
RIP协议设计 毕业课程设计报告包含源代码.docx_第4页
第4页 / 共22页
RIP协议设计 毕业课程设计报告包含源代码.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

RIP协议设计 毕业课程设计报告包含源代码.docx

《RIP协议设计 毕业课程设计报告包含源代码.docx》由会员分享,可在线阅读,更多相关《RIP协议设计 毕业课程设计报告包含源代码.docx(22页珍藏版)》请在冰豆网上搜索。

RIP协议设计 毕业课程设计报告包含源代码.docx

RIP协议设计毕业课程设计报告包含源代码

(此文档为word格式,下载后您可任意编辑修改!

 

网络程序设计

课程设计报告

 

题目RIP协议设计

专业及班级网络工程1101班

学号

姓名

日期2012年7月3日

一、课程设计目的

了解RIP协议的原理和应用等相关知识,通过距离矢量算法来实现最短传输路径的路由选择。

通过本次课程设计,可以对RIP协议的工作原理和实现机制,路由表的建立和路由信息的更新等有更直观和清晰的认识。

程序运行后能与路由器的RIP协议程序正确通信。

查阅相关RFC。

提供配置命令,程序运行后能动态设置协议参数。

收到的数据先放入循环队列,再从队列中取出依次处理。

使用定时器处理超时事件。

二、设计与实现

2.1RIP协议的报文格式分析

对于RIP报文有两种版本的格式,Version1和Version2。

两种报文稍有不同,如所示分别为RIPv1和RIPV2:

命令

版本

全零

地址族

全零

IP地址

全零

全零

度量值

前20个字节的重复

命令

版本

路由选择

地址族

路径标签

IP地址

子网掩码

下一个站点的IP地址

度量值

前20个字节的重复

RIP报文中至多可以出现25个AFI、互联网络地址和度量域。

这样允许使用一个RIP报文来更新一个路由器中的多个路由表项。

包含多个路由表项的RIP报文只是简单地重复从AFI到度量域的结构,其中包括所有的零域。

图表2显示了路由信息域中只带一个目的地的RIP报文。

1字节命令

1字节版本

2字节0域

2字节

AFI

2字节

0域

4字节

网络地

4字节

0域

4字节

0域

4字节

度量

图表2

图表3具有两个表项的RIP报文

1字节

命令

1字节

版本

2字节

0域

两字节

AFI

2字节

0域

4字节

网络地址

4字节

0域

4字节

0域

4字节

度量

4字节

网络

地址

4字节

0域

4字节

0域

4字节

度量

图表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端口获得包,并检查包的格式,然后分析包的命令是请求还是相应给于相应的处理。

socket()-->bind()-->recvfrom()-->rp_inverse_ntoh()-->print_rip_packet()-->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;

unsignedintmetric;

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);

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=¤t_rip_packetmand;

unsignedshort*temp=(unsignedshort*)(tempptr);

unsignedshort*temp=(unsignedshort*)(¤t_rip_packet);

*temp==);

for(inti=0;i

{

current_rip_packet.rip_entries[i].metric==sizeof(buf);

constchar*buf_ptr;

printf("currentroutingtable----\n");

for(inti=0;i

{

printf("%dthre:

\n",i);

buf_ptr=inet_ntop(AF_INET,&routing_table[i].dest,buf,buf_len);

printf("destination:

%s",buf);

buf_ptr=inet_ntop(AF_INET,&routing_table[i].dest,buf,buf_len);

printf("next:

%s",buf);

printf("metric:

%d\n\n",routing_table[i].metric);

}

printf("\n");

}

voidprint_message(constchar*title,constchar*content)

{

printf("\n%s---\n",title);

printf("-%s-\n",content);

printf("endofmessage\n");

}

voidprint_rip_packet()

{

printf("rippacketcontains%dentries:

-\n",current_rip_count);

printf("command:

%s",((current_rip_packetmand==RIP_RESPONSE)?

"RESPONSE":

"REQUEST"));

printf("version:

%d\n",current_rip_packet.version);

for(inti=0;i

{

printf("entry%d:

",i);

printf("ip:

%s",inet_ntoa(current_rip_packet.rip_entries[i].ip));

printf("metric:

%d\n",current_rip_packet.rip_entries[i].metric);

}

printf("\n");

}

intcheck_rip_packet()

{

if(current_rip_packet.version==2)

returnRIP_CHECK_OK;

if(current_rip_packet.version==0)

returnRIP_CHECK_FAIL;

checkmbz

if(current_rip_packet.zero)

returnRIP_CHECK_FAIL;

for(inti=0;i

{

if(current_rip_packet.rip_entries[i].zero1||

current_rip_packet.rip_entries[i].zero2||

current_rip_packet.rip_entries[i].zero3)

{

returnRIP_CHECK_FAIL;

}

returnRIP_CHECK_OK;

}

}

intcalculate_rip_metric(intrip_entry_number)

{

if(current_rip_packet.rip_entries[rip_entry_number].metric+1>RIP_INFINITY)

returnRIP_INFINITY;

returncurrent_rip_packet.rip_entries[rip_entry_number].metric+1;

}

voidreset_rip_packet(intcommand)

{

current_rip_count=0;

current_rip_packetmand=command;

current_rip_packet.version=1;

current_rip_packet.zero=0;

for(inti=0;i

{

current_rip_packet.rip_entries[0].family=2;

current_rip_packet.rip_entries[0].zero1=0;

current_rip_packet.rip_entries[0].ip.s_addr=0;

current_rip_packet.rip_entries[0].zero2=0;

current_rip_packet.rip_entries[0].zero3=0;

current_rip_packet.rip_entries[0].metric=0;

}

}

voidreset_routing_table()

{

current_route_count=0;

for(inti=0;i

{

routing_table[i].dest.s_addr=0;

routing_table[i].next.s_addr=0;

routing_table[i].metric=0;

routing_table[i].valid=1;

routing_table[i].timer=0;

routing_table[i].flag=0;

}

}

voidinit_routing_table()

{

reset_routing_table();

for(inti=0;i

{

if(inet_pton(AF_INET,local_ip[i],&(routing_table[i].dest))<=0)

{

printf("inet_ptonerror\n");

}

if(inet_pton(AF_INET,local_ip[i],&(routing_table[i].next))<=0)

{

printf("inet_ptonerror\n");

}

routing_table[i].metric=1;

routing_table[i].timer=time(NULL);

routing_table[i].valid=ROUTE_VALID;

routing_table[i].flag=0;

}

current_route_count=LOCAL_ROUTE_ENTRY;

}

voidget_local_ip()

{

charac[80];

if(gethostname(ac,sizeof(ac))==-1){

cerr<<"Error"<

"whengettinglocal;

}

printf("Hostnameis%s,",ac);

struct;

}

for(inti=0;phe->_addr));

printf("Address%d:

%s\n=======================================\n",i,inet_ntoa(local_addr));

}

}

voidinit_all()

{

get_local_ip();

reset_rip_packet(RIP_RESPONSE);

init_routing_table();

}

voidgen_request_all()

{

current_rip_count=1;

current_rip_packetmand=RIP_REQUEST;

current_rip_packet.version=1;

current_rip_packet.zero=0;

current_rip_packet.rip_entries[0].family=0;

current_rip_packet.rip_entries[0].zero1=0;

current_rip_packet.rip_entries[0].ip.s_addr=0;

current_rip_packet.rip_entries[0].zero2=0;

current_rip_packet.rip_entries[0].zero3=0;

current_rip_packet.rip_entries[0].metric=RIP_INFINITY;

}

voidsend_rip_packet_to(structin_addrdest_ip)

{

printf("beginsendingrippacket:

\n");

print_rip_packet();

rp_inverse_();

structsockaddr_inaddr;

intaddr_len=sizeof(structsockaddr_in);

bzero(&addr,addr_len);

addr.sin_family=AF_INET;

addr.sin_addr.s_addr=_port=_port=)<0)

printf("sentgreeninsend_rip_packet_to\n");

close(sockfd);

return;

}

voidbroadcast_rip_packet()

{

printf("beginbroadcastingrippacket:

\n");

print_rip_packet();

rp_inverse_();

structsockaddr_inaddr;

intaddr_len=sizeof(structsockaddr_in);

bzero(&addr,addr_len);

addr.sin_family=AF_INET;

inet_aton("59.66.132.170",&addr.sin_addr);

addr.sin_addr.s_addr=_addr.s_addr=_addr.s_addr);

addr.sin_port=");

intsockfd=socket(AF_INET,SOCK_DGRAM,0);

intval=1;

bind(sockfd,(structsockaddr*)&addr,sizeof(addr));

setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&val,sizeof(val));

if(sendto(sockfd,¤t_rip_packet,

RIP_PACKET_HEAD+current_rip_count*sizeof(structrip_entry),

sizeof(current_rip_packet),

0,(structsockaddr*)&addr,addr_len)<0)

{

printf("broadcasterrorinbroadcast_rip_packet\n");

}

close(sockfd);

return;

}

voidreceive_rip_packet()

{

structsockaddr_inaddr;

sockfd=socket(AF_INET,SOCK_DGRAM,0);

if(sockfd<0)

{

printf("opensocketerrorinstart_rip_daemon\n");

exit(-1);

}

bzero(&addr,sizeof(structsockaddr_in));

addr.sin_family=AF_INET;

addr.sin_addr.s_addr=_port=))<0)

{

printf("binderrorinstart_rip\n");

exit(-1);

}*

structsockaddr_inaddr;

intaddr_len=sizeof(structsockaddr_in);

intpacket_len=0;

packet_len=recvfrom(sockfd,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1