做这个实验从网上扒了好多版本,验收的时候碰到一个非常严格的助教,告诉我们网上都是错的!没有子网掩码blablabla……改了好久,踩了很多坑,终于弄出来个正确的,特此记录,如果你的助教是一个叫姓傅的可爱的老师,请参考此代码=3=
(话虽这么说,确实期间学到了不少东西,本来也就知道个具体流程,现在估计让我自己写一遍都没问题了,还是要感谢这位助教啊)
放源码上来不是为了方便大家应付实验,个人不要脸的觉得在学习阶段,抄是可以的,但抄完了连抄的是什么都不知道是肯定不行的。毕竟大家的时间都很紧嘛,合理地分配时间达到最好的学习效果才是最好的。(估计考完试这辈子都不会看路由器咋实现的了2333)
#include "sysInclude.h"
#include<vector>
using std::vector;
// system support
extern void fwd_LocalRcv(char *pBuffer, int length);
extern void fwd_SendtoLower(char *pBuffer, int length, unsigned int nexthop);
extern void fwd_DiscardPkt(char *pBuffer, int type);
extern unsigned int getIpv4Address();
// implemented by students
struct route_table
{
int dest;
int nexthop;
int masklen;
};
vector<route_table> mytable; //路由表
void stud_Route_Init()
{
mytable.clear(); //清空路由表
return;
}
void stud_route_add(stud_route_msg *proute) // 添加一个新的表项
{
route_table t;
// 计算目的地址
t.dest = ntohl(proute->dest);
t.masklen = proute->masklen;
// 计算下一跳
t.nexthop=ntohl(proute->nexthop);
// 填入表中
mytable.push_back(t);
return;
}
int stud_fwd_deal(char *pBuffer, int length)
{
// 头部长度
int IHL = pBuffer[0] & 0xf;
// TTL
int TTL = (int)pBuffer[8];
// 头部校验和
int Head_Checksum = ntohs(*(unsigned short*)(pBuffer+10));
// 目的IP地址
int Dst_IP=ntohl(*(unsigned int*)(pBuffer+16));
// 如果本机地址等于目的IP地址
if (Dst_IP == getIpv4Address())
{
// 接收文件
fwd_LocalRcv(pBuffer,length);
return 0;
}
// 如果TTL = 0
if(TTL<=0)
{
// 错误
fwd_DiscardPkt(pBuffer, STUD_FORWARD_TEST_TTLERROR);
return 1;
}
// 遍历路由表
vector<route_table>::iterator ii;
for(ii = mytable.begin(); ii!=mytable.end(); ii++)
{
// 如果存在目的地址
if((ii->dest&((1<<31)>>(ii->masklen - 1)))== (Dst_IP&((1<<31)>>(ii->masklen - 1))))
{
char *buffer=new char[length];
memcpy(buffer,pBuffer,length);
// TTL-1
buffer[8]--;
// 计算首部校验和
int sum=0,i=0;
unsigned short Local_Checksum=0;
for(; i<2*IHL; i++)
{
if(i!=5)
{
sum+=(buffer[2*i]<<8)+(buffer[2*i+1]);
sum%=65535;
}
}
Local_Checksum=htons(0xffff-(unsigned short)sum);
memcpy(buffer+10, &Local_Checksum, 2);
// 传输给下一跳
fwd_SendtoLower(buffer, length, ii->nexthop);
return 0;
}
}
// 没有路由器
fwd_DiscardPkt(pBuffer,STUD_FORWARD_TEST_NOROUTE);
return 1;
}
ojbk!
(代码主要部分来自于网上,vector和map两类的,忘了具体扒哪个了【也不知道原创究竟是谁的233】,就不写了,主要修改子网掩码部分)