我正在尝试创建一个程序,可以接收并显示所有传入的数据包到我的家庭网络。这只是一个有趣的'项目,因为我试图更好地使用计算机网络。
我找到了几个关于使用套接字的教程,我试图模仿他们正在做的事情。 (目前使用this(初始化内容来自this)教程)。
但是,我在使代码工作时遇到了一些问题。这是我到目前为止的代码:(因为我知道我只会在Windows上使用它,我只是省略了mac和unix的其他marcos)#define PLATFORM_WINDOWS 1
#if defined(_WIN32)
#define PLATFORM PLATFORM_WINDOWS
#endif
#if PLATFORM == PLATFORM_WINDOWS
#include <WinSock2.h>
#endif
#pragma comment( lib, "wsock32.lib" );
#pragma comment( lib, "Ws2_32.lib" );
#include <iostream>
bool InitializeSockets()
{
#if PLATFORM == PLATFORM_WINDOWS
WSADATA WsaData;
return WSAStartup( MAKEWORD(2,2), &WsaData);
#else
return true;
#endif
}
void ShutdownSockets()
{
#if PLATFORM == PLATFORM_WINDOWS
WSACleanup();
#endif
}
void printIpPacket(unsigned char* data, int length)
{
printf("-----------------Packet Begins-----------------\n");
printf("IP Version: %i, Packet Size: %ibytes, Id: %i\n",
(data[0]>>4), (data[2]*256)+data[3], (data[4]*256)+data[5]);
printf("Fragment: %i, TTL: %i, HL: %iwds, Protocol: %i\n",
((int)(data[6]>>4)*256)+data[7], data[8], ((char)(data[0]<<4))>>4, data[9]);
printf("Source: %i.%i.%i.%i, Destination: %i.%i.%i.%i\n",
data[12], data[13], data[14], data[15],
data[16], data[17], data[18], data[19]);
//the data inside the packet starts at --> data+(((char)(data[0]<<4))>>2)
//new data length --> length-(((char)(data[0]<<4))>>2)
//continue printing the rest of the headers :o
printf("\n------------------Packet Ends------------------\n");
}
int main()
{
InitializeSockets();
int thisSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
int optVal = 1;
setsockopt(thisSocket, IPPROTO_IP, 2, (char *)&optVal, sizeof(optVal));
int inn = 1, outt;
long rett;
int err = WSAIoctl(thisSocket, 0x98000001, &inn, sizeof(inn), &outt, sizeof(outt), &rett, 0, 0);
int a = WSAGetLastError();
}
我在使WSAIoctl
功能正常工作时遇到了一些麻烦。该教程声称可以使用的代码甚至无法编译。我收到错误:
error C2664: 'WSAIoctl' : cannot convert parameter 7 from 'long *' to 'LPDWORD'
因此,我将WSAIoctl函数行更改为:
int err = WSAIoctl(thisSocket, 0x98000001, &inn, sizeof(inn), &outt, sizeof(outt), (LPDWORD)&rett, 0, 0);
这已编译,但随后WSAGetLastError()返回错误代码10022,根据this表示无效参数。
所以我想,&#34;好吧,我想我应该传递正确的类型,而不是试图强制将错误类型转换为正确的类型。&#34;
然后我创建了一个变量
LPDWORD rett = new DWORD;
这样做,我编译成功,但我再次收到错误代码10022。
此时,我不知道还能做什么。有人可以帮助我让这个程序工作吗?
答案 0 :(得分:0)
尝试更像这样的事情:
#define PLATFORM_WINDOWS 1
#if defined(_WIN32)
#define PLATFORM PLATFORM_WINDOWS
#endif
#if PLATFORM == PLATFORM_WINDOWS
#include <WinSock2.h>
#endif
#pragma comment( lib, "wsock32.lib" );
#pragma comment( lib, "Ws2_32.lib" );
#include <iostream>
bool InitializeSockets()
{
#if PLATFORM == PLATFORM_WINDOWS
WSADATA WsaData;
int a = WSAStartup( MAKEWORD(2,2), &WsaData);
if (a != 0)
{
printf("WSAStartup() failed. Error %d\n", a);
return false;
}
#endif
return true;
}
void ShutdownSockets()
{
#if PLATFORM == PLATFORM_WINDOWS
WSACleanup();
#endif
}
#if PLATFORM != PLATFORM_WINDOWS
void closesocket(int socket)
{
close(socket);
}
#endif
int GetLastSocketError()
{
#if PLATFORM == PLATFORM_WINDOWS
return WSAGetLastError();
#else
return errno;
#endif
}
int main()
{
if (!InitializeSockets())
return -1;
int thisSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (thisSocket == -1)
{
printf("socket() failed. Error %d\n", GetLastSocketError());
ShutdownSockets();
return -1;
}
sockaddr_in bindaddr = {0};
bindaddr.sin_family = AF_INET;
// set bindaddr.sin_addr.s_addr to the desired local IP that you want to sniff from...
if (bind(thisSocket, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
{
printf("bind() failed. Error %d\n", GetLastSocketError());
closesocket(thisSocket);
ShutdownSockets();
return -1;
}
u_long optVal = 1;
if (setsockopt(thisSocket, IPPROTO_IP, IP_HDRINCL, (char *)&optVal, sizeof(optVal)) == -1)
{
printf("setsockopt() failed. Error %d\n", GetLastSocketError());
closesocket(thisSocket);
ShutdownSockets();
return -1;
}
#if PLATFORM == PLATFORM_WINDOWS
DWORD inn = RCVALL_ON;
if (WSAIoctl(thisSocket, SIO_RCVALL, &inn, sizeof(inn), NULL, 0, NULL, NULL, NULL) == -1)
{
printf("WSAIoctl() failed. Error %d\n", GetLastSocketError());
closesocket(thisSocket);
ShutdownSockets();
return -1;
}
#endif
u_char Buffer[0xffff];
while(1)
{
int len = recvfrom(thisSocket, (char*)Buffer, sizeof(Buffer), NULL, 0, 0);
if (len == -1)
{
printf("recvfrom() failed. Error %d\n", GetLastSocketError());
closesocket(thisSocket);
ShutdownSockets();
return -1;
}
printIpPacket(Buffer, len);
}
closesocket(thisSocket);
ShutdownSockets();
return 0;
}