C++ 为什么原始套接字sendto()函数在10022中失败?
我正在VS2010下为ICMP、TCP、UDP等开发一个协议模糊器。我已通过原始套接字接口成功发送ICMP和UDP数据包。但是我在发送TCP时遇到了一个问题 我的环境:Windows 7 Ultimate x64,管理员帐户 这是我的方式: 我自己构造传输头和数据 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,这意味着提供的参数无效 下面是代码,谢谢C++ 为什么原始套接字sendto()函数在10022中失败?,c++,c,sockets,networking,tcp,C++,C,Sockets,Networking,Tcp,我正在VS2010下为ICMP、TCP、UDP等开发一个协议模糊器。我已通过原始套接字接口成功发送ICMP和UDP数据包。但是我在发送TCP时遇到了一个问题 我的环境:Windows 7 Ultimate x64,管理员帐户 这是我的方式: 我自己构造传输头和数据 2将原始套接字用于IPv4标头及其以下版本。RawConnect函数用于创建这样一个原始套接字。strIP是一个IP地址,strProtocol是需要指定的IP协议号,如ICMP为1、IGMP为2、TCP为6、UDP为17。因为我自己
#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;
}
}
很少有版本的Windows支持原始套接字,请检查first.thx,但我是Win7 ultimate的管理员,同时我成功发送了自建Ip头、UDP和ICMP,只有TCP失败,所以我们可以假设原始套接字受支持吗?据我所知,我可能错了,Windows开始在WinXp中支持原始套接字,并将其保留到WinXp SP2,WinPCAP等驱动程序仍然可以使用它,但我不确定在用户空间中是否可以。在调用sendto之前,通过硬代码重新创建结构,您是否可以加倍确保您的目的地在某个时候没有损坏?@hsluoyz您可能会提到