使用raw socket组包发送udp的包,总是报10049错误!
整个网上查了许多资料,觉得程序并无问题,全部源程序贴出来,大家指点一下!
全部分数都在这里,有解决的立即结贴
#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);
}