2013-11-24 46 views
0

我想寫迷你嗅探器。問題是那些來自我的地址的數據包。目前,我只打印「源」和「目的地」地址。如何解決這個程序?對不起,我的「英語」: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; 
} 
+0

您應該使用'h_addr_list [0]'代替。並且請注意,計算機可以安裝多個網絡,因此,如果要監視所有地址,您必須將每個地址綁定(')一個單獨的套接字,以便gethostbyname()報告。另外,'gethostbyname(gethostname)'有缺陷,所以使用'getaddrinfo()','GetAdaptersInfo()'或GetAdaptersAddresses()來獲取本地IP地址。 –

+0

考慮使用[Winpcap](http://www.winpcap.org)而不是使用套接字手動監視。 –

回答

0

如果我是正確的,要嗅探從遠程主機傳入數據包。在這種情況下,您可以看到下面的鏈接(對於Linux): link

您需要在混雜模式下使用接口運行程序。

+0

SIO_RCVALL啓用混雜模式。 –

+0

這是對的,但我說的是啓用Promisc模式的程序在鏈接工作整個網絡:) –