我想寫迷你嗅探器。問題是那些來自我的地址的數據包。目前,我只打印「源」和「目的地」地址。如何解決這個程序?對不起,我的「英語」: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;
}
您應該使用'h_addr_list [0]'代替。並且請注意,計算機可以安裝多個網絡,因此,如果要監視所有地址,您必須將每個地址綁定(')一個單獨的套接字,以便gethostbyname()報告。另外,'gethostbyname(gethostname)'有缺陷,所以使用'getaddrinfo()','GetAdaptersInfo()'或GetAdaptersAddresses()來獲取本地IP地址。 –
考慮使用[Winpcap](http://www.winpcap.org)而不是使用套接字手動監視。 –