udp检验和计算实现的代码 出错 请问原因

lixd1231 2008-07-31 11:26:03
我最近开始学习数据包伪造 之前做的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);
}






...全文
425 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
laibach0304 2008-08-19
  • 打赏
  • 举报
回复
udp校验和要校验的范围你清楚吗?
是伪首部和udp首部联合校验的结果。
伪首部包括4字节的源地址,4字节的目的地址,1个字节的0,1个字节的17,和2个字节的UDP长度
udp首部说一点,校验和字段要先清零
具体见tcpip详解第2卷的23.6.2

还有udp校验和是可选项,不是每个系统都会计算的
xxn2007 2008-08-01
  • 打赏
  • 举报
回复
好像右移的次数不对吧,用下面的试试

USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}

while (cksum>>16)
cksum = (cksum >> 16) + (cksum & 0xffff);

return (USHORT)(~cksum);
}

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧