udp检验和计算实现的代码 出错 请问原因
我最近开始学习数据包伪造 之前做的arp和ip都很简单就实现了。可是到了udp这有个难题就是udp的校验和,虽然我知道怎么去计算它,可是程序编出来,用sniffer抓包发现提示udp的校验和出错,不知道是哪里出问题了 我把代码贴出来希望有高人能给我指点迷津。小弟先谢了。
我首先定义了一个 u_char packet[1024];
然后依次填充 这个数据包。代码如下;
/*目的MAC*/
packet[0]= 0xff;
packet[1]= 0xff;
packet[2]= 0xff;
packet[3]= 0xff;
packet[4]= 0xff;
packet[5]= 0xff;
/*源MAC*/
packet[6]=0x00;
packet[7]=0x01;
packet[8]=0x6c;
packet[9]=0x8a;
packet[10]=0xec;
packet[11]=0xa8;
/*帧类型*/
packet[12]=0x08;
packet[13]=0x00;
/*版本号和头部长度*/
packet[14]=0x45;
/*服务类型*/
packet[15]=0x00;
/*封包总长度*/
packet[16]=0x00;
packet[17]=0x49;
/*id*/
packet[18]=0xef;
packet[19]=0xfb;
/*flag*/
packet[20]=0x00;
/*offset*/
packet[21]=0x00;
/*ttl*/
packet[22]=0x80;
/*protocol*/
packet[23]=0x11;
/*checksum*/
packet[24]=0x00;
packet[25]=0x00;//0x87;
/*sourceip*/
packet[26]=192;
packet[27]=168;
packet[28]=0;
packet[29]=89;
/*desip*/
packet[30]=0xff;
packet[31]=0xff;
packet[32]=0xff;
packet[33]=0xff;
/*udp source port*/
packet[34]=0x03; //1004
packet[35]=0xec;
/*dest port*/
packet[36]=0x03;
packet[37]=0xec;
/*UDP LEN*/
packet[38]=0x00;
packet[39]=0x35;
/*checksum*/ //如何填写校验和
packet[40]=0x00;
packet[41]=0x00;
计算校验和的代码如下:
//计算ip校验和
USHORT ipchecksum=checksum((USHORT *)(packet+14), 20);
union //共用体
{ USHORT i;
u_char a[2];
}ipcksum;
ipcksum.i=ipchecksum;
printf("%x\n",ipchecksum);
printf("%x\n",ipcksum.a[0]);
printf("%x\n",ipcksum.a[1]);
packet[24]=ipcksum.a[0];
packet[25]=ipcksum.a[1];
/*udp校验和计算*/
char *ptr=buff;
int chksumlen=0;
ULONG zero=0;
//ip源地址与目的地址
memcpy(ptr,packet+26,8);
ptr+=8;
chksumlen+=8;
//8位0
memcpy(ptr,&zero,1);
ptr+=1;
chksumlen+=1;
//协议
memcpy(ptr,packet+23,1);
ptr+=1;
chksumlen+=1;
//udp长度
memcpy(ptr,packet+38,1);
ptr+=1;
chksumlen+=1;
memcpy(ptr,packet+39,1);
ptr+=1;
chksumlen+=1;
//udp包头
memcpy(ptr,packet+34,8);
ptr+=8;
chksumlen+=8;
/* //udp源端口号
memcpy(ptr,packet+34,1);
ptr+=1;
chksumlen+=1;
memcpy(ptr,packet+35,1);
ptr+=1;
chksumlen+=1;
//目的端口号
memcpy(ptr,packet+36,1);
ptr+=1;
chksumlen+=1;
memcpy(ptr,packet+37,1);
ptr+=1;
chksumlen+=1;
//又是udp长度
memcpy(ptr,packet+38,1);
ptr+=1;
chksumlen+=1;
memcpy(ptr,packet+39,1);
ptr+=1;
chksumlen+=1;
//16位udp校验和
memcpy(ptr,&zero,sizeof(USHORT));
ptr+=sizeof(USHORT);
chksumlen+=sizeof(USHORT);
*/
//净荷
for(int q=0;q<payloadlen;q++,ptr++)
*ptr=strMessage[q];
chksumlen+=payloadlen;
//补齐到下一个16位边界
for(int m=0;m<payloadlen%2;m++)
{ *ptr=0; ptr++; chksumlen++;
}
USHORT udpchecksum=checksum((USHORT*)buff,chksumlen);
printf("%x\n",udpchecksum);
union //共用体
{ USHORT t;
u_char b[2];
}udpcksum;
udpcksum.t=udpchecksum;
printf("%x\n",udpcksum.b[0]);
printf("%x\n",udpcksum.b[1]);
packet[40]=udpcksum.b[0];
packet[41]=udpcksum.b[1];
其中用到的子函数 计算校验和子函数为:
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >>16) + (cksum &0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}