电子信息工程学系实验报告
课程名称:网络工程设计与系统集成 实验项目名称:配置动态路由RIP 实验时间:20##年12月7日班级: 计教081 姓名: 学号:
实验目的:
1、了解动态路由协议采用的自适应路由算法
2、了解路由协议算法的层次划分
3、学会配置动态路由RIP
实验环境:
Windows操作系统 CCCisco Systems
实验内容及过程:
动态路由协议采用自适应路由算法,能够根据网络拓扑的变化而重新计算机最佳路由。由于路由的复杂性,路由算法也是分层次的,通常把路由协议(算法)划分为自治系统(AS)内的(IGP,Interior Gateway Protocol)与自治系统之间(EGP,External Gateway Protocol)的路由协议。
RIP的全称是Routing Information Protocol,是IGP,采用Bellman-Ford算法。RFC1058是RIP version 1标准文件,RFC2453是RIP Version 2的标准文档。
一、实验环境构建,配置如下实例
实验中各个网段与路由器接口IP地址分配如上图所示。
二、RIP协议基本配置命令
Router(config)#ip classless 让路由器支持无类编址,RIPv1是不支持无类IP编址的。
RIP基本配置命令:
Router(config)#router rip
Router(config-router)#network w.x.y.z
可选的配置命令:
Router(config)#no router rip 在路由器上关闭RIP协议
Router(config-router)#no network w.x.y.z 从RIP协议中移除w.x.y.z网络
Router(config-router)#version 2 RIP协议为第2版
Router(config-if)#ip rip send version 2 该接口仅发送RIP ver 2报文
Router(config-if)#ip rip send version 1 该接口仅发送RIP ver 1报文
Router(conifg-if)#ip rip send version 1 2 该接口发送RIP ver 1报文和RIP ver 2报文
Router(config-if)#ip rip receive version 2 该接口仅接收RIP ver 2报文
Router(config-router)#no auto-summary 关闭路由协议的自动聚合功能
Router(config-router)#ip split-horizon 配置水平分割
三、RIP配置
首选根据实验需要配置好PC机及路由器各个接口的IP地址等参数。
1、三个路由器的基本配置
Router0>enable
Router0#configure terminal
Router0(config)#interface Serial1/0
Router0(config-if)#clock rate 64000
Router0(config-if)#no ip address
Router0(config-if)#ip address 192.168.0.1 255.255.255.0
Router0(config-if)#no shutdown
Router0(config)#interface FastEthernet0/0
Router0(config-if)#ip address 10.1.1.1 255.255.255.0
Router0(config-if)#no shutdown
Router0(config-if)#
基本配置主要是配置路由器的名字,安全密码,各个端口的IP地址等。仅一个路由器配置为例,其余的路由器与该路由器配置相似。
2、RIP路由协议配置
路由器Router0配置命令:
Router0(config)#router rip
Router0(config-router)#version 2
Router0(config-router)#network 10.1.1.0
Router0(config-router)#network 192.168.0.0
路由器Router1配置命令:
Router1(config)#router rip
Router1(config-router)#version 2
Router1(config-router)#network 10.0.0.0
Router1(config-router)#network 192.168.0.0
Router1(config-router)#network 192.168.1.0
路由器Router2配置命令:
Router2(config)#router rip
Router2(config-router)#version 2
Router2(config-router)#network 10.0.0.0
Router2(config-router)#network 192.168.1.0
3、RIP路由协议的诊断与排错
查看路由表show ip route
show ip rip database
debug ip rip开启RIP诊断,no debug ip rip 关闭RIP诊断
4、使用计算机不同网段互ping检查网络连通
1、实验配置中各个部件的连接
2、使用计算机不同网段互ping检查网络连通
Pc3可以ping通所有的网段
实验心得:
通过本次实验的操作,我掌握了路由器动态路由RIP的配置,可以自己独立完成RIP的所有配置。在这次实验过程中理解了关于动态路由RIP的相关知识点,比如,RIP的全称是Routing Information Protocol,是IGP,采用Bellman-Ford算法。当然通过这次实验我又学会了路由器的一个新的配置的知识,知识在于不断的积累我相信这次实验结束今后自己还可以相应的学到新的关于路由配置的知识。
第二篇:Exp2_路由协议RIP的简单实现_实验报告
Exp2路由协议RIP的简单实现实验报告
【实验目标】
? 对客户端接收到的RIP报文进行有效性检查:对客户端接收到的RIP协议报文进行合法性检查,丢弃存在错误的报文并指出错误原因; ? 处理Request报文:正确解析并处理RIP协议的Request报文,并能够根据报文的内容以及本地路由表组成相应的Response报文,回复给Request报文的发送者,并实现水平分割;
? 处理Response报文:正确解析并处理RIP协议的Response报文,并根据报文中携带的路由信息更新本地路由表;
? 路由表项超时删除:处理来自系统的路由表项超时消息,并能够删除指定的路由;
? 路由表项定时发送:实现对本地路由的定时发送功能,并实现水平分割。
【实验原理】
有效性检查
对接收到的RIP协议报文,要进行两方面的合法性检查:
? RIP版本号:packet->rip_vers域必须为2。
? RIP命令号:packet->rip_cmd域只能是1(Request报文)或者2(Response报文)。
处理Request报文
当接收到一个来自端口号为iNo的Request报文时,我们需要调用
select_routes()函数遍历路由表,取出所有if_no != iNo的条目(这个判断是为了实现水平分割)组成RIP Response包并发送。
处理Response报文
当接收到一个来自端口号为iNo的Response报文时,我们需要遍历包中每一条路由信息(首先完成网络序和主机序的转换),按照如下准则尝试更新路由表:
? 若<rr_addr, rr_mask>未曾出现,直接添加进路由表。
? 若<rr_addr,rr_mask>出现且srcAdd == next_hop,无条件更新路由表项。 ? 若<rr_addr,rr_mask>出现且srcAdd != next_hop,当且仅当metric值减小时才更新路由表项。
路由表项超时删除
当接收到一个路由表项超时消息时,我们查找路由表,并将表项中的metric值赋值为MAX_METRIC(16)。
路由表项定时发送
当接收到一个路由表定时发送消息时,我们枚举各端口(此处是1,2),完成处理Request报文相同的工作。
【实验中遇到的问题】
rip_sendIpPkt调用参数
一开始不知道rip_sendIpPkt的dstPort参数如何设置,还以为是目的IP地址,后来查阅手册才发现应设置为520。
网络序和本机序
接受到的RIP包中使用的是网络序,所以在存储时要首先转换为本地序(调用ntohl/ntohs函数),发送时要进行相反方向的转换(调用htonl/htons函数)。
【源代码】
#include "sysinclude.h"
extern void rip_sendIpPkt(unsigned char *pData, UINT16 len,unsigned short dstPort,UINT8 iNo);
extern struct stud_rip_route_node *g_rip_route_table;
const unsigned short DST_PORT = 520;
const unsigned int MAX_METRIC = 16;
struct stud_rip_route_node *find_route_table(unsigned int sdest, unsigned int smask)
{
}
struct stud_rip_route_node *res = g_rip_route_table; while (res != NULL && !(res->dest == sdest && res->mask == smask)) { } return res; res = res->next;
UINT16 select_routes(struct RipPacket *ppkt, unsigned int iNo) {
}
int stud_rip_packet_recv(char *pBuffer,int bufferSize,UINT8 iNo,UINT32 srcAdd) {
iNo);
break; // RIP Response from iNo, update g_rip_route_table struct RipRt *prt = &(packet->rip_rts[i]); if (prt->rr_addr.u_l == 0) { } break; for (int i = 0; i < RIP_MAX_ROUTES; ++i) { case 2: UINT16 len = 0; struct RipPacket *packet = (struct RipPacket *)pBuffer; if (packet->rip_vers != 2) { } switch (packet->rip_cmd) { case 1: // RIP Request from iNo, send routes with if_no != iNo struct RipPacket packet2send; len = select_routes(&packet2send, iNo); rip_sendIpPkt((unsigned char *)(&packet2send), len, DST_PORT, ip_DiscardPkt(pBuffer, STUD_RIP_TEST_VERSION_ERROR);return 0; ppkt->rip_cmd = 2; ppkt->rip_vers = 2; ppkt->rip_mbz = 0; int cnt = 0; struct stud_rip_route_node *prt = g_rip_route_table; while (prt != NULL) { } return (4 + 20 * cnt); if (prt->if_no != iNo) { } prt = prt->next; ppkt->rip_rts[cnt].rr_family = htons(2); ppkt->rip_rts[cnt].rr_rttag = 0; ppkt->rip_rts[cnt].rr_addr.u_l = htonl(prt->dest); ppkt->rip_rts[cnt].rr_mask.u_l = htonl(prt->mask); ppkt->rip_rts[cnt].rr_nexthop.u_l = ppkt->rip_rts[cnt].rr_metric = htonl(prt->metric); cnt++; // RIP Response // Version 2 // must-be-zero htonl(prt->nexthop); // RIP 版本错误
prt->rr_addr.u_l = ntohl(prt->rr_addr.u_l);
prt->rr_mask.u_l = ntohl(prt->rr_mask.u_l);
prt->rr_metric = ntohl(prt->rr_metric);
struct stud_rip_route_node *node =
find_route_table(prt->rr_addr.u_l, prt->rr_mask.u_l);
if (node == NULL) { // 新表项,添加到表头
node = new (struct stud_rip_route_node); node->dest = prt->rr_addr.u_l;
node->mask = prt->rr_mask.u_l;
node->nexthop = srcAdd;
node->metric = prt->rr_metric + 1;
node->if_no = iNo;
node->next = g_rip_route_table;
g_rip_route_table = node;
} else if (node->nexthop == srcAdd) { // 源地址等于下一跳,无论如何都更新
node->metric = prt->rr_metric + 1;
node->if_no = iNo;
} else if (node->metric - prt->rr_metric >0) { node->metric = prt->rr_metric + 1;
node->if_no = iNo;
}
}
break;
default:
ip_DiscardPkt(pBuffer, STUD_RIP_TEST_COMMAND_ERROR);
// RIP 命令错误
break;
}
return 0;
}
void stud_rip_route_timeout(UINT32 destAdd, UINT32 mask, unsigned char msgType) {
UINT16 len;
switch (msgType) {
case RIP_MSG_SEND_ROUTE:
for (int iNo = 1; iNo <= 2; ++iNo) { // 2 个端口均发送 struct RipPacket packet2send;
len = select_routes(&packet2send, iNo);
rip_sendIpPkt((unsigned char *)(&packet2send), len, DST_PORT, iNo);
} // 否则比较
break; struct stud_rip_route_node *node; node = find_route_table(destAdd, mask); if (node != NULL) { } break; node->metric = MAX_METRIC; case RIP_MSG_DELE_ROUTE: default: } }
break;