网络实验涉及到ipv4和ipv6的路由匹配问题,当时上网络理论课,只知道路由表要匹配,却没去深究到底是怎么匹配的。
不去追寻过去路由器如何匹配,只说现在的最长匹配规则。
最长掩码匹配规则的一个例子:
1.2.3.0/24
1.2.0.0/16
1.2.3.4/30
当一个目的地址为1.2.3.5的ipv4分组到达时,将会选择1.2.3.4/30的路由转发出去。即选择最长掩码的匹配项。
我要说的重点不是如何选择匹配项,而是如何判断一个路由表项是否匹配。
若已知子网掩码长度masklen(子网掩码中=1的bit数)
int mask = 0x1;//mask 子网掩码
for(i=0;i<masklen;i++)//masklen 子网掩码长度
mask = 0x1 + mask<<1;
mask = mask<<(32-masklen);
//dest为分组目的地址,temp为路由表的表项
if(dest&mask == temp&mask)//匹配成功
route = temp;
//然后进入下一个路由表项的匹配
上面方法,只是匹配方法,没有加入最长匹配的规则。并且masklen为主机字节序,dest和temp要保证字节序的一致。
对于ipv6要麻烦一点,因为ipv6地址有128位,若ipv6地址使用int型数组表示,那么就要根据masklen的大小,来计算mask,同样的使用int型数组来存放mask。
bool destEQdesip(char *pBuffer,route_table *temp){ //pbuffer指向ipv6的头部,判断目的地址是否与路由表项temp的目的地址相同
int i=0;
int j=0;
UINT32 mask = temp->rmsg->masklen;
int zero = 128 - mask;
int mask1[4];
if(mask>=96){
mask1[0] = 0x1;
for(i=0;i<32-zero;i++)
mask1[0] =0x1+mask1[0]<<1;
mask1[0] = mask1[0] <<zero;
}
else if(mask>=64){
mask1[0] = 0xFFFFFFFF;
mask1[1]=0x1;
for(i=0;i<64-zero;i++)
mask1[1] =0x1+mask1[1]<<1;
mask1[1] = mask1[1] <<(zero-32);
}
else if(mask>=32){
mask1[0] = 0xFFFFFFFF;
mask1[1]=0xFFFFFFFF;
mask1[2]= 0x1;
for(i=0;i<96-zero;i++)
mask1[2] =0x1+mask1[2]<<1;
mask1[2] = mask1[2] <<(zero-64);
}
else{
mask1[0] = 0xFFFFFFFF;
mask1[1]=0xFFFFFFFF;
mask1[2]= 0xFFFFFFFF;
mask1[3]=0x1;
for(i=0;i<128-zero;i++)
mask1[3] =0x1+mask1[3]<<1;
mask1[3] = mask1[3] <<(zero-96);
}
for(i=0;i<4;i++){
unsigned int *desip = (unsigned int*)(pBuffer+24+j);
if( (ntohl(temp->rmsg->dest.dwAddr[i])&mask1[0]) != (ntohl(*desip)&mask1[0]))
break;
j=j+4;
}if(i==4) return true;
else return false;
}