如何捕获传入数据包?
问题描述:
我想写迷你嗅探器。问题是那些来自我的地址的数据包。目前,我只打印“源”和“目的地”地址。如何解决这个程序?对不起,我的“英语”:d感谢的如何捕获传入数据包?
Log: Source: 172.16.226.207 Destination: 173.194.112.78 Source: 172.16.226.207 Destination: 23.78.81.224 Source: 172.16.226.207 Destination: 69.171.247.29 Source: 172.16.226.207 Destination: 173.194.71.84 Source: 172.16.226.207 Destination: 173.194.71.94
#include <stdio.h>
#include <winsock2.h>
#include <conio.h>
#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000
typedef struct _IPHeader
{
unsigned char verlen;
unsigned char tos;
unsigned short length;
unsigned short id;
unsigned short offset;
unsigned char ttl;
unsigned char protocol;
unsigned short xsum;
unsigned long src;
unsigned long dest;
} IPHeader;
int main(void)
{
WSADATA wsaData;
SOCKET s;
HOSTENT* phe;
SOCKADDR_IN saClient;
IN_ADDR sa;
char name[128];
int error;
error = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error)
{
printf("WSAStartup failed with error: %d\n", error);
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
}
else
printf("The Winsock 2.2 dll was found\n");
s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
error = gethostname(name, sizeof(name));
if (error)
{
printf("gethsotname function failed with error: %d\n", error);
WSACleanup();
return 1;
}
else
printf("Host name: %s\n", name);
phe = gethostbyname(name);
error = WSAGetLastError();
if (error)
{
printf("gethostbyname function failed with error: %d\n", error);
WSACleanup();
return 1;
}
ZeroMemory(&saClient, sizeof(saClient));
saClient.sin_family = AF_INET;
saClient.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[1])->s_addr;
error = bind(s, (SOCKADDR *)&saClient, sizeof(SOCKADDR));
if (error == SOCKET_ERROR)
{
printf("bind function failed with error: %d\n", error);
closesocket(s);
WSACleanup();
return 1;
}
unsigned long flag = 1;
ioctlsocket(s, SIO_RCVALL, &flag);
// Packet processing
char buffer[MAX_PACKET_SIZE];
printf("\n");
IPHeader* hdr;
while (!_kbhit())
{
error = recv(s, buffer, sizeof(buffer), 0);
if (error > sizeof(IPHeader))
{
hdr = (IPHeader *)buffer;
sa.s_addr = hdr->src;
printf("Source: %s\n", inet_ntoa(sa));
sa.s_addr = hdr->dest;
printf("Destination: %s\n\n", inet_ntoa(sa));
}
else if (error == 0)
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", error);
}
closesocket(s);
WSACleanup();
return 0;
}
答
如果我是正确的,要嗅探从远程主机传入数据包。在这种情况下,您可以看到下面的链接(对于Linux
): link
您需要在混杂模式下使用接口运行程序。
+0
SIO_RCVALL启用混杂模式。 –
+0
这是对的,但我说的是启用Promisc模式的程序在链接工作整个网络:) –
您应该使用'h_addr_list [0]'代替。并且请注意,计算机可以安装多个网络,因此,如果要监视所有地址,您必须将每个地址绑定(')一个单独的套接字,以便gethostbyname()报告。另外,'gethostbyname(gethostname)'有缺陷,所以使用'getaddrinfo()','GetAdaptersInfo()'或GetAdaptersAddresses()来获取本地IP地址。 –
考虑使用[Winpcap](http://www.winpcap.org)而不是使用套接字手动监视。 –