2016-07-08 7 views
1

Ich schrieb einen einfachen Paketempfänger mit Raw-Sockets und ich bekomme seltsame Ausgänge, zB:Raw Socket Paketempfänger in C, merkwürdige Ausgabe

Received packet: size: 124, type: PACKET_HOST (0) 
Sender info: Name: n003-000-000-000.static.ge.com, IP: 3.0.0.0 
Data: 
74 2f 68 3c d1 9f 00 37 b7 d1 5a a7 08 00 45 00 00 6e 00 00 40 
00 40 11 b6 e9 c0 a8 01 01 c0 a8 01 44 00 35 94 08 00 5a 3b aa 
e1 78 81 80 00 01 00 01 00 00 00 00 01 30 01 30 01 30 01 33 07 
69 6e 2d 61 64 64 72 04 61 72 70 61 00 00 0c 00 01 c0 0c 00 0c 
00 01 00 00 65 95 00 20 10 6e 30 30 33 2d 30 30 30 2d 30 30 30 
2d 30 30 30 06 73 74 61 74 69 63 02 67 65 03 63 6f 6d 00 

Wenn ich im Internet bin gerade, die Pakete sind größer, aber Der Hostname und die Adresse bleiben gleich oder fast gleich.

Könnte jemand mir helfen, das Problem zu identifizieren?

Hier ist der Code:

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <net/if.h> 
#include <sys/ioctl.h> 
#include <linux/if_ether.h> 
#include <netdb.h> 
#include <linux/if_packet.h> 
#include <netinet/ether.h> 

#define PACKET_SIZE 1 << 16 

void usage(); 
void packetTypeToStr(int type, char *str); 

int main(int argc, char **argv) { 
    const char *iface_name; 
    if (argc == 2) { 
     iface_name = argv[1]; 
    } else if (argc > 2) { 
     usage(); 
     return 1; 
    } else { 
     iface_name = "wlan0"; 
    } 

    // Opening socket in raw mode 
    int socketFileDesc = 0; 
    if ((socketFileDesc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { 
     perror("socket"); 
     return errno; 
    } 
    printf("Opened raw socket\n"); 

    // Acquiring the index of the interface 
    struct ifreq iface; 
    memset(&iface, 0, sizeof(struct ifreq)); 
    strncpy(iface.ifr_name, iface_name, strlen(iface_name) + 1); 
    if (ioctl(socketFileDesc, SIOCGIFINDEX, &iface) < 0) { 
     perror("SIOCGIFINDEX"); 
     usage(); 
     close(socketFileDesc); 
     return errno; 
    } 
    int index = iface.ifr_ifindex; 
    printf("Index of the interface %s: %d\n", iface_name, index); 

    // Acquiring the mac address of the interface 
    struct ifreq iface_mac; 
    memset(&iface_mac, 0, sizeof(struct ifreq)); 
    strncpy(iface_mac.ifr_name, iface_name, strlen(iface_name) + 1); 
    if (ioctl(socketFileDesc, SIOCGIFHWADDR, &iface_mac) < 0) { 
     perror("SIOCGIFHWADDR"); 
     usage(); 
     close(socketFileDesc); 
     return errno; 
    } 
    printf("MAC address of the interface %s: %s\n", iface_name, ether_ntoa((struct ether_addr*)iface_mac.ifr_hwaddr.sa_data)); 


    // Setting interface in promiscuous mode 
    struct ifreq iface_options; 
    memset(&iface_options, 0, sizeof(struct ifreq)); 
    strncpy(iface_options.ifr_name, iface_name, strlen(iface_name) + 1); 
    if (ioctl(socketFileDesc, SIOCGIFFLAGS, &iface_options) < 0) { 
     perror("SIOCGIFFLAGS"); 
     close(socketFileDesc); 
     return errno; 
    } 
    iface_options.ifr_flags |= IFF_PROMISC; 
    if (ioctl(socketFileDesc, SIOCSIFFLAGS, &iface_options) < 0) { 
     perror("SIOCGIFFLAGS"); 
     close(socketFileDesc); 
     return errno; 
    } 
    printf("Interface %s set in promiscuous mode\n", iface_name); 

    // Binding socket to the interface 
    struct sockaddr_ll socketAddress; 
    memset(&socketAddress, 0, sizeof(socketAddress)); 
    socketAddress.sll_family = AF_PACKET; 
    socketAddress.sll_protocol = htons(ETH_P_ALL); 
    socketAddress.sll_ifindex = index; 
    if (bind(socketFileDesc, (struct sockaddr *) &socketAddress, sizeof(socketAddress)) < 0) { 
     perror("bind"); 
     close(socketFileDesc); 
     return errno; 
    } 
    printf("Socket bound to the interface: %s\nWaiting for packets...\n", iface_name); 

    // Receiving packets in a loop 
    while (1) { 
     ssize_t n = 0; 
     uint8_t packet[PACKET_SIZE]; 
     bzero(packet, sizeof(packet)); 
     struct sockaddr_in address; 
     socklen_t length = sizeof(address); 

     if ((n = recvfrom(socketFileDesc, packet, sizeof(packet), 0, (struct sockaddr *) &address, &length)) < 0) { 
      perror("recvfrom"); 
      close(socketFileDesc); 
      return errno; 
     } 
     // Null-terminated data 
     if (n > 0) 
      packet[n - 1] = '\0'; 
     else 
      continue; 

     // IP address 
     char ip[INET_ADDRSTRLEN]; 
     inet_ntop(AF_INET, &(address.sin_addr), ip, length); 

     // Host name 
     struct hostent *host = gethostbyaddr(&(address.sin_addr), length, AF_INET); 
     if (host == NULL) { 
      herror("gethostbyaddr"); 
      return h_errno; 
     } 
     const char *hostName = host->h_name; 

     // Packet type 
     char packetType[BUFSIZ]; 
     int type = ((struct sockaddr_ll *) &address)->sll_pkttype; 
     packetTypeToStr(type, packetType); 

     // Printing info and data 
     printf("\n\nReceived packet: size: %li, type: %s\n" 
         "Sender info: Name: %s, IP: %s\n", 
       n, packetType, hostName, ip); 
     printf("Data:\n"); 
     int i = 0; 
     for (; i < n; ++i) 
      printf("%02x ", packet[i]); 
    } 
    return 0; 
} 

Antwort

1

Da Sie recvfrom() roh Paket empfangen kann keine IP-Adresse zurück, da die Daten in der Regel nicht ein Internet-Paket sein. Zum Beispiel kann es einfach ein beliebiges Ethernet-Paket sein, das von irgendeinem Gerät gesendet wurde, das überhaupt keinen TCP/IP-Stapel hat. Wahrscheinlich recvfrom() behandelt sockaddr Zeiger als struct sockaddr_ll * übergeben und gibt Adresse der physikalischen Schicht zurück.

Sie können versuchen, die korrekte IP-Adresse durch Parsing des empfangenen Pakets zu erhalten. Wenn es wirklich ein IP-Paket ist, wird es alle Header mit Quell- und Zieladressen enthalten.