Raw socket packet receiver in C, strange output

Marcin Router

I wrote a simple packet receiver using raw sockets and I get strange outputs, f.e.:

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

When I'm browsing the internet, the packets are bigger, but the host name and address stays the same or almost the same.

Could someone help me identify the problem?

Here's the 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;
}
Sergio

Since you are receiving raw packet recvfrom() can not return IP address because data in general may not be an internet packet. For example it may be simply an arbitrary Ethernet packet, that was sent from some device that has no TCP/IP stack at all. Probably recvfrom() treats passed sockaddr pointer as struct sockaddr_ll * and returns physical layer address.

You can try to obtain correct IP address via parsing of received packet. If it is really IP packet - it will contain all headers, with source and destination addresses.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Raw socket packet receiver in C, strange output

From Dev

Raw socket packet sniffer in Python 3.6 on Windows

From Dev

How to send modified IPv6 packet through RAW socket?

From Dev

How to send modified IPv6 packet through RAW socket?

From Dev

C TCP Socket - Get packet destination name

From Dev

C-Server Socket become wrong Packet

From Dev

Is there a simple way to send a packet over a raw socket using Ruby's Socket class?

From Dev

Is there a simple way to send a packet over a raw socket using Ruby's Socket class?

From Dev

While loop for a raw_input gives strange output in Python

From Dev

Strange file output C++

From Dev

C - Why this strange output in printf()

From Dev

C raw sockets packet looks fine but doesn't escape network

From Dev

Why does a PF_PACKET RAW socket stop missing packets after "Wireshark" was launched?

From Dev

Why does a PF_PACKET RAW socket stop missing packets after "Wireshark" was launched?

From Dev

Read raw socket ip header? c++

From Dev

Reading the maximum size of an expected packet from a C socket

From Dev

Socket: Reading UDP Packet

From Dev

Socket broadcasting a packet

From Java

strange output of array as function argument in C

From Dev

Pthread_Create in C leads to strange output

From Dev

histogram program gives strange output C++

From Dev

strange string format percent c# output

From Dev

Strange output from Counting Sort in C

From Dev

Long int to char: strange output in C

From Dev

Strange broadcast receiver race condition

From Dev

Simple Raw Packet Sniffer In Python

From Dev

Get packet in a raw form with netfilter

From Dev

socket logback log receiver required

From Dev

python socket setsockopt with raw socket

Related Related

HotTag

Archive