RIP实验
源代码.txt“我羡慕内些老人 羡慕他们手牵手一直走到最后。━交话费的时候,才发现自己的话那么值钱。#include "sysinclude.h"
#include
extern void rip_sendIpPkt(unsigned char* pData, UINT16 len, unsigned short dstPort, UINT8 iNo);/*RIP包的发送函数*/
extern struct stud_rip_route_node *g_rip_route_table;/*路由表*/
typedef struct _packet_header /*RIP数据包的头部*/
{
unsigned char command;/*命令只能是REQUEST或者RESONSE*/
unsigned char version;/*版本号,1或者2*/
unsigned short pad0;/*置零*/
} packet_header;
typedef struct _packet_data/*RIP数据包*/
{
unsigned short addrfamily;/*地址族,必须为2*/
unsigned short routetag;/*路由标记*/
unsigned int ipaddr;/*IP地址*/
unsigned int netmask;/*掩码*/
unsigned int nexthop;/*下一跳*/
unsigned int metric;/*跳数*/
} packet_data;
#define DECLAREERROR(pkt,type) {printf("Discard because %d\n",type);ip_DiscardPkt(pkt,type);return 0;}/*定义RIP包出错时的返回类型*/
unsigned char buffer[256];/*缓冲区*/
void dumpPkt(unsigned char*buf,int len)/*实现数据提取功能*/
{
printf("Dumping sending packets:\n");
int l=0;
for (int i=0;i {
printf("%02x ",(unsigned int)buf[i]);
l++;
if (l++==15)/*l应该小于16*/
{
printf("\n");
l=0;
}
}
printf("\n");
}
void MakePacket(char version, UINT8 iNo)/*该函数实现组装RIP数据包*/
{
stud_rip_route_node *pnow=g_rip_route_table;
/*发送数据包时满足:1.端口必须不相同2.跳数必须小于16*/
while (pnow&;&;(pnow->if_no==iNo||pnow->metric==16))
pnow=pnow->next;
/*遍历并复制路由链表*/
do
{
/*组装RIP数据包的头部*/
packet_header*ph=(packet_header*)buffer;
ph->command=2; /*响应(RESPONSE)分组*/
ph->version=version; /*版本号*/
ph->pad0=0; /*必须为0*/
/*组装数据包*/
int pCount=0;
while (pCount<25&;&;pnow)/*一个数据包最多能容纳25条记录*/
{
packet_data*pd=(packet_data*)(buffer+sizeof(packet_header));
pd+=pCount;
pd->addrfamily=htons(2);
pd->routetag=0;
pd->ipaddr=htonl(pnow->dest);
if (version==2)
pd->netmask=htonl(pnow->mask);
else
pd->netmask=0;
if (version==2)
pd->nexthop=htonl(pnow->nexthop);
else
pd->nexthop=0;
pd->metric=htonl(pnow->metric);
pCount++;
do {
pnow=pnow->next;
} while (pnow&;&;(pnow->if_no==iNo||pnow->metric==16));
}
/*发送数据包*/
dumpPkt(buffer,sizeof(packet_header)+sizeof(packet_data)*pCount);
rip_sendIpPkt(buffer,sizeof(packet_header)+sizeof(packet_data)*pCount,520,iNo);
} while (pnow);
}
#include
char*clone(char*org,int len)/*取出数据并删除缓冲区的原始数据*/
{
char*t=(char*)malloc(len);
memmove(t,org,len);
return t;
}
int stud_rip_packet_recv(char*pBuffer, int bufferSize, UINT8 iNo, UINT32 srcAdd)
{
pBuffer=clone(pBuffer,buffer
Size);
/*检查数据包头部是否合法,否则调用出错函数返回出错类型*/
packet_header*ph=(packet_header*)pBuffer;
if (ph->command!=1&;&;ph->command!=2) DECLAREERROR(pBuffer,STUD_RIP_TEST_COMMAND_ERROR);
if (ph->version!=1&;&;ph->version!=2) DECLAREERROR(pBuffer,STUD_RIP_TEST_VERSION_ERROR);
if (ph->pad0!=0) DECLAREERROR(pBuffer,STUD_RIP_TEST_COMMAND_ERROR);
if (ph->command==1)/*为REQUEST包*/
{
printf("Get valid request\n");
MakePacket(ph->version,iNo);
}
else/*为RESPONSE包*/