为什么raw socket sendto()函数失败了10022?

时间:2014-03-22 04:56:30

标签: c++ c sockets networking tcp

我正在开发VS2010下的ICMP,TCP,UDP等协议模糊器。我已经通过原始套接字接口成功发送了ICMP和UDP数据包。但是我在发送TCP时遇到了问题。

我的环境:Windows 7 Ultimate x64,管理员帐户。

这是我的方式:

1)自己构建传输头和数据。

2)使用原始套接字作为IPv4标头及其下方。 RawConnect()函数用于创建这样的原始套接字。 strIP是IP地址,strProtocol是需要指定的IP协议号(如ICMP为1,IGMP为2,TCP为6,UDP为17)。因为我自己没有构造IP头(m_bSelfConstructIPHeader = FALSE),所以IP协议号是必要的。我不知道我是否正确使用它?

3)使用sendto()函数发送缓冲区,返回-1,WSAGetLastError()返回10022,表示“提供了无效参数。”

下面是代码,thx!

#include "stdafx.h"

#include "AFRawSocket.h"

#define IP_HDRINCL 2

AFRawSocket::AFRawSocket()
{
    m_socket = NULL;
    m_bSelfConstructIPHeader = FALSE;
}

CString AFRawSocket::itos(int i)
{
    CString strTemp;
    strTemp.Format(_T("%d"), i);
    return strTemp;
}

int AFRawSocket::stoi(CString s)
{
    return _wtoi(s);
}

//
// CStringAתCStringW
//
CStringW AFRawSocket::CStrA2CStrW(const CStringA &cstrSrcA)
{
    int len = MultiByteToWideChar(CP_ACP, 0, LPCSTR(cstrSrcA), -1, NULL, 0);
    wchar_t *wstr = new wchar_t[len];
    memset(wstr, 0, len*sizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, 0, LPCSTR(cstrSrcA), -1, wstr, len);
    CStringW cstrDestW = wstr;
    delete[] wstr;

    return cstrDestW;
}

//
// CStringWתCStringA
//
CStringA AFRawSocket::CStrW2CStrA(const CStringW &cstrSrcW)
{
    int len = WideCharToMultiByte(CP_ACP, 0, LPCWSTR(cstrSrcW), -1, NULL, 0, NULL, NULL);
    char *str = new char[len];
    memset(str, 0, len);
    WideCharToMultiByte(CP_ACP, 0, LPCWSTR(cstrSrcW), -1, str, len, NULL, NULL);
    CStringA cstrDestA = str;
    delete[] str;

    return cstrDestA;
}

void AFRawSocket::SetSelfConstructIPHeader(BOOL bSelfConstructIPHeader)
{
    m_bSelfConstructIPHeader = bSelfConstructIPHeader;
}

BOOL AFRawSocket::RawConnect(CString strIP, CString strProtocol)
{
    int optval;
    CStringA straIP = CStrW2CStrA(strIP);

    int iProtocol;
    if (strProtocol == _T("N/A"))
    {
        iProtocol = 0;
    }
    else
    {
        iProtocol = stoi(strProtocol);
    }

    sockaddr_in mysock;
    ZeroMemory((char*)&mysock,sizeof(mysock));//初始化
    mysock.sin_family=AF_INET;
    mysock.sin_addr.s_addr=inet_addr(straIP);

    //Create Raw TCP Packet
    //printf("\nCreating Raw TCP Socket...");
    //ETH_P_ALL
    //AF_PACKET

//  if (iProtocol == IPPROTO_TCP)
//  {
//      iProtocol = IPPROTO_UDP;
//  }

    if((m_socket = socket(AF_INET, SOCK_RAW, iProtocol/*IPPROTO_RAW*/))==SOCKET_ERROR)
    {
        //printf("Creation of raw socket failed.");
        MyMessageBox_Error(_T("RawConnect"));
        return FALSE;
    }
    //printf("Raw TCP Socket Created successfully.");
    ////////////////////////////////////////////////

    if (m_bSelfConstructIPHeader)
    {
        //Put Socket in RAW Mode.
        //printf("\nSetting the socket in RAW mode...");
        if(setsockopt(m_socket, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
        {
            //printf("failed to set socket in raw mode.");
            MyMessageBox_Error(_T("RawConnect"));
            return FALSE;
        }
        //printf("Successful.");
        ////////////////////////////////////////////////
    }


//  //Target Hostname
//  printf("\nEnter hostname : ");
//  gets(host);
//  printf("\nResolving Hostname...");
//  if((server=gethostbyname(host))==0)
//  {
//      printf("Unable to resolve.");
//      return 0;
//  }
    ZeroMemory(&m_dest, sizeof(m_dest));
    m_dest.sin_family = AF_INET;
    //m_dest.sin_port   = htons(0);  //your destination port
    m_dest.sin_addr.s_addr=inet_addr(straIP);
    //m_dest.sin_addr.s_addr=inet_addr("8.8.8.8");
    //m_dest.sin_addr.s_addr=inet_addr("202.112.128.50");
    //memcpy(&m_dest.sin_addr.s_addr,&mysock.sin_addr.s_addr,4);
    //printf("Resolved.");
    /////////////////////////////////////////////////

//  if (bind(m_socket, (SOCKADDR *) &m_dest, sizeof(m_dest)) < 0)
//  {
//      int iError = WSAGetLastError();
//      MyMessageBox_Error(_T("RawConnect"));
//      return FALSE;
//  }

    return TRUE;
}

void AFRawSocket::RawSend(LPBYTE lpBuffer, DWORD dwSize)
{
    int iRet = sendto(m_socket , (const char *) lpBuffer, dwSize, 0, (SOCKADDR *)&m_dest, sizeof(m_dest));
    //if (iRet == SOCKET_ERROR)
    if (iRet <= 0)
    {
        //printf("Error sending Packet : %d",WSAGetLastError());
        int iError  =WSAGetLastError();
        MyMessageBox_Error(_T("RawSend"));
    }
}

void AFRawSocket::RawDisconnect()
{
    if (m_socket)
    {
        closesocket(m_socket);
        m_socket = NULL;
    }
}

0 个答案:

没有答案