我正在开发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;
}
}