IPv4转发实验
实验目的
本实验设计模拟实现路由器中的 IPv4 协议,可以在原有 IPv4 分组收发实验的基础上,增加 IPv4 分组的转发功能。对网络的观察视角由主机转移到路由器中,了解路由器是如何为分组选择路由,并逐跳地将分组发送到目的主机。本实验中也会初步接触路由表这一重要的数据结构,认识路由器是如何根据路由表对分组进行转发的。
实验要求
在前面 IPv4 分组收发实验的基础上,增加分组转发功能。具体来说,对于每一个到达本机的 IPv4 分组,根据其目的 IPv4 地址决定分组的处理行为,对该分组进行如下的几类操作:
1) 向上层协议上交目的地址为本机地址的分组;
2) 根据路由查找结果,丢弃查不到路由的分组;
3) 根据路由查找结果,向相应接口转发不是本机接收的分组。
实验内容
实验内容主要包括:
1) 设计路由表数据结构。
2) IPv4 分组的接收和发送。
3) IPv4 分组的转发。
实验过程
- 路由表维护
需要完成下列分组接收处理步骤:
1)stud_Route_Init()
函数中,对路由表进行初始化。
2)stud_route_add()
函数中,完成路由的增加。 - 转发处理流程
在stud_fwd_deal()
函数中,需要完成下列分组接收处理步骤:
1) 查找路由表。根据相应路由表项的类型来确定下一步操作,错误分组调用函数fwd_DiscardPkt()
进行丢弃,上交分组调用接口函数fwd_LocalRcv()
提交给上层协议继续处理,转发分组进行转发处理。注意,转发分组还要从路由表项中获取下一跳的 IPv4 地址。
2) 转发处理流程。对 IPv4 头部中的 TTL 字段减 1,重新计算校验和,然后调用下层接口fwd_SendtoLower()
进行发送处理。
实验源码
代码基于上次作业修改完成,故有较多注释
#include "sysInclude.h"
#include<vector>
#include <iostream>
// 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();
using namespace std;
typedef struct {
unsigned int nexthop;
unsigned dest;
} routeItem;
vector<routeItem> myroute;
int stud_fwd_deal(char * pBuffer, int length){
printf("Check IP Version:\n");
unsigned int version=(pBuffer[0]>>4);
printf("IP Version is %d\n", version);
// if(version!=4){
// ip_DiscardPkt(pBuffer, STUD_IP_TEST_VERSION_ERROR);
// return 1;
// }
printf("Check Header Length:\n");
unsigned int len=(pBuffer[0]&0xF);
printf("Header Length is %d\n", len);
// if(len<5){
// ip_DiscardPkt(pBuffer, STUD_IP_TEST_HEADLEN_ERROR);
// return 1;
// }
printf("Check CheckSum:\n");
unsigned int sum=0;
for(int i=0;i<len*2;i++){
sum+=((unsigned short*)pBuffer)[i];
sum=(sum>>16)+(sum&0xffff);
}
cout<<sum<<endl<<~sum<<endl;
//cout<<bitset<sizeof(short)*8>((unsigned short)sum)<<endl;
//ut<<bitset<sizeof(short)*8>(~(unsigned short)sum)<<endl;
printf("Check Sum is %d\n", ~sum);
printf("CheckSUM is %d\n", ((unsigned short*)pBuffer)[5]);
// if(((unsigned short)sum)!=0xffff){
// ip_DiscardPkt(pBuffer, STUD_IP_TEST_CHECKSUM_ERROR);
// return 1;
// }
printf("Check Destination:\n");
unsigned int destination=ntohl(*(unsigned int*)(pBuffer+16));
unsigned int ip=getIpv4Address();
printf("destination is %d, host ip is %d\n", destination, ip);
if(ip==destination){
fwd_LocalRcv(pBuffer,length);
return 0;
}
printf("Check Time To Live:\n");
unsigned int ttl=pBuffer[8];
printf("Time To Live is %d\n", ttl);
if(ttl<=0){
ip_DiscardPkt(pBuffer, STUD_FORWARD_TEST_TTLERROR);
return 1;
}
vector<routeItem>::iterator ii;
for(ii=myroute.begin();ii!=myroute.end();ii++)
{
if(ii->dest==destination)
{
char *buffer=new char[length];
memcpy(buffer,pBuffer,length);
buffer[8]--;
int sum=0,i=0;
unsigned short Local_Checksum=0;
for(;i<2*len;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;
// printf("Send To UP\n");
// ip_SendtoUp(pBuffer,length);
// return 0;
}
void stud_route_add(stud_route_msg *proute){
routeItem t;
t.nexthop=proute->nexthop;
t.dest=ntohl(proute->dest) & (0xffffffff<<(32-ntohl(proute->masklen)));
myroute.push_back(t);
}
void stud_Route_Init(){
myroute.clear();
}
暂无评论
有没有c语言的
自己的作业要自己写