使用raw socket组包发送udp的包,总是报10049错误!

marrymeng 2004-11-21 08:38:28
整个网上查了许多资料,觉得程序并无问题,全部源程序贴出来,大家指点一下!
全部分数都在这里,有解决的立即结贴

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>


using namespace std;

#pragma pack(1)
// The IP header structure
//
typedef struct _iphdr
{
unsigned char h_len:4; // Length
unsigned char ver:4; // IP Version
unsigned char tos; // Type of service
unsigned short totlen; // Total length of the packet
unsigned short id; // Unique identifier
unsigned short offset; // Fragment offset field
unsigned char ttl; // Time to live
unsigned char proto; // Protocol(TCP,UDP,ICMP,IGMP...)
unsigned short checksum; // IP checksum

unsigned int srcIP; // Source IP address
unsigned int destIP; // Destination IP address
}IpHeader, * LPIpHeader;

// The UDP header structure
//
typedef struct _udphdr
{
unsigned short sport; // Source Port
unsigned short dport; // Destination Port
unsigned short Length; // Length
unsigned short Checksum; // Checksum

}UdpHeader, * LPUdpHeader;

typedef struct _PSHeader
{
unsigned long srcaddr;
unsigned long destaddr;

unsigned char zero;
unsigned char protocol;
unsigned short len;

}PSHeader;

#pragma pack()

int initialize();
USHORT checksum(USHORT *buffer, int size);

void main()
{
initialize();
SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
SOCKADDR_IN sock_addr;
BOOL on = 1;
int ret = setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on));
if (ret == SOCKET_ERROR){
printf("Error setting opt: %d",WSAGetLastError());
return;
}

unsigned char sendBuf[2048];
memset(sendBuf,0,2048);

unsigned char chksumBuf[2048];
memset(chksumBuf,0,2048);
int chksumLen = 0;

unsigned char data[20];
memset(data,0,20);
strcpy((char*)data,"Hello");
int data_size = strlen((char*)data) + 1;

IpHeader *iphdr;
UdpHeader *udphdr;
int iUdpSize, error;
PSHeader pseudo_header;


iphdr = (IpHeader *) sendBuf; // the ip header now points to the top of the sendBuf
udphdr=(UdpHeader *) (sendBuf + sizeof(IpHeader)); // the udp header points to the part next to the ip header
memcpy(sendBuf+sizeof(IpHeader)+sizeof(UdpHeader),data, data_size);

sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons (80);
sock_addr.sin_addr.s_addr = inet_addr("192.168.0.8");

iphdr->ver = 4;
iphdr->h_len = 5;
iphdr->tos = 0;
iphdr->totlen = sizeof (IpHeader) + sizeof (UdpHeader) + data_size;
iphdr->id = 1;
iphdr->offset = 0;
iphdr->ttl = 255;
iphdr->proto = IPPROTO_UDP; //UDP
iphdr->checksum = 0;

iphdr->srcIP = inet_addr ("192.168.0.81"); // your source id
iphdr->destIP = sock_addr.sin_addr.s_addr;

// Initalize the UDP header
//
iUdpSize = sizeof(UdpHeader) + data_size;

udphdr->sport = htons(5150) ;
udphdr->dport = htons(5150) ;
udphdr->Length = htons(iUdpSize) ;
udphdr->Checksum = 0 ;

//calculate UDP CheckSum
pseudo_header.destaddr = inet_addr("192.168.0.8");
pseudo_header.srcaddr = inet_addr("192.168.0.81");
pseudo_header.zero = 0;
pseudo_header.protocol = IPPROTO_UDP;
pseudo_header.len = udphdr->Length;

memcpy(chksumBuf,(PVOID)&pseudo_header,sizeof(pseudo_header));
chksumLen += sizeof(pseudo_header);
memcpy(chksumBuf+chksumLen,udphdr,sizeof(UdpHeader));
chksumLen += sizeof(UdpHeader);
memcpy(chksumBuf+chksumLen,data,data_size);
chksumLen += data_size;

udphdr->Checksum = checksum((unsigned short*) chksumBuf,chksumLen);
iphdr->checksum = checksum((unsigned short *) iphdr, sizeof(IpHeader));

/*for(int i=0;i<40;i++)
printf("%x",sendBuf[i]);*/

error = sendto(sock,(char*)sendBuf,28+data_size,0,(LPSOCKADDR)&sock_addr,sizeof(SOCKADDR_IN));

if(error == SOCKET_ERROR)
cout << WSAGetLastError() << endl;
else
cout << "sent" << endl;
}



int initialize()
{
int t;
/* Before any Winsock function to work, we need to call to wsock.dll to initialize those
functions */
WSADATA wsa_data;
t = WSAStartup(MAKEWORD(2,2), &wsa_data);

if(t != 0)
return -1;
else
return 0;
}


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);
}
...全文
321 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
t83714 2005-03-12
  • 打赏
  • 举报
回复
把动态RTL去掉试试
marrymeng 2004-11-24
  • 打赏
  • 举报
回复
大家都进来解答一下吧!
marrymeng 2004-11-23
  • 打赏
  • 举报
回复
就是那个RawUDPSend.zip!
kingzai 2004-11-22
  • 打赏
  • 举报
回复
我觉得是你UDP的CheckSum是错的
UDP的CheckSum是:UDP头+数据

IP的CheckSum是: IP头 + UDP头+ 数据
/////////////////////////////////////
我从codeguru上给你贴的代码部分有错误,里面有个人已经改正了这个错误,并且帖出了源代码。
Mathew Joy
Reputation:

The error that you got is the address is wrong. The checksum was calculated wrongly including many other omission and mistakes. I've quickly created a working version of your code and attached. I recommend you to compare with your code study/play with it before setting out. Point is that you should understand the underlying working principle of it.
从http://www.codeguru.com/forum/showthread.php?s=c0a28c0f1357ea52f07c6671207125a7&p=999678#post999678
你可以下载到源代码
kingzai 2004-11-22
  • 打赏
  • 举报
回复
你下的是修改过之后的代码?
marrymeng 2004-11-22
  • 打赏
  • 举报
回复
10049错误我查过了,地址肯定没问题,一个是我自己的,一个是内网中的,可以ping通!

to:kingzai,我用的代码就是从你推荐那个地方下载的,你没看仔细吧??
oyljerry 2004-11-21
  • 打赏
  • 举报
回复
WSAEADDRNOTAVAIL (10049) Cannot assign requested address.
绑定的地址是不是不对

18,356

社区成员

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

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