Skip to content

Instantly share code, notes, and snippets.

@KISSMonX
Forked from austinmarton/recvRawEth.c
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save KISSMonX/b3403c00a37bd52aaad6 to your computer and use it in GitHub Desktop.

Select an option

Save KISSMonX/b3403c00a37bd52aaad6 to your computer and use it in GitHub Desktop.

Revisions

  1. @austinmarton austinmarton revised this gist Jun 3, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion recvRawEth.c
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ int main(int argc, char *argv[])
    return -1;
    }

    /* Set MUX to promiscuous mode - do we need to do this every time? */
    /* Set interface to promiscuous mode - do we need to do this every time? */
    strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
    ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
    ifopts.ifr_flags |= IFF_PROMISC;
  2. @austinmarton austinmarton created this gist Jun 3, 2012.
    134 changes: 134 additions & 0 deletions recvRawEth.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,134 @@
    /*
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation, either version 3 of the License, or
    * (at your option) any later version.
    */

    #include <arpa/inet.h>
    #include <linux/if_packet.h>
    #include <linux/ip.h>
    #include <linux/udp.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
    #include <net/if.h>
    #include <netinet/ether.h>

    #define DEST_MAC0 0x00
    #define DEST_MAC1 0x00
    #define DEST_MAC2 0x00
    #define DEST_MAC3 0x00
    #define DEST_MAC4 0x00
    #define DEST_MAC5 0x00

    #define ETHER_TYPE 0x0800

    #define DEFAULT_IF "eth0"
    #define BUF_SIZ 1024

    int main(int argc, char *argv[])
    {
    char sender[INET6_ADDRSTRLEN];
    int sockfd, ret, i;
    int sockopt;
    ssize_t numbytes;
    struct ifreq ifopts; /* set promiscuous mode */
    struct ifreq if_ip; /* get ip addr */
    struct sockaddr_storage their_addr;
    uint8_t buf[BUF_SIZ];
    char ifName[IFNAMSIZ];

    /* Get interface name */
    if (argc > 1)
    strcpy(ifName, argv[1]);
    else
    strcpy(ifName, DEFAULT_IF);

    /* Header structures */
    struct ether_header *eh = (struct ether_header *) buf;
    struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
    struct udphdr *udph = (struct udphdr *) (buf + sizeof(struct iphdr) + sizeof(struct ether_header));

    memset(&if_ip, 0, sizeof(struct ifreq));

    /* Open PF_PACKET socket, listening for EtherType ETHER_TYPE */
    if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
    perror("listener: socket");
    return -1;
    }

    /* Set MUX to promiscuous mode - do we need to do this every time? */
    strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
    ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
    ifopts.ifr_flags |= IFF_PROMISC;
    ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
    /* Allow the socket to be reused - incase connection is closed prematurely */
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
    perror("setsockopt");
    close(sockfd);
    exit(EXIT_FAILURE);
    }
    /* Bind to device */
    if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1) {
    perror("SO_BINDTODEVICE");
    close(sockfd);
    exit(EXIT_FAILURE);
    }

    repeat: printf("listener: Waiting to recvfrom...\n");
    numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
    printf("listener: got packet %lu bytes\n", numbytes);

    /* Check the packet is for me */
    if (eh->ether_dhost[0] == DEST_MAC0 &&
    eh->ether_dhost[1] == DEST_MAC1 &&
    eh->ether_dhost[2] == DEST_MAC2 &&
    eh->ether_dhost[3] == DEST_MAC3 &&
    eh->ether_dhost[4] == DEST_MAC4 &&
    eh->ether_dhost[5] == DEST_MAC5) {
    printf("Correct destination MAC address\n");
    } else {
    printf("Wrong destination MAC: %x:%x:%x:%x:%x:%x\n",
    eh->ether_dhost[0],
    eh->ether_dhost[1],
    eh->ether_dhost[2],
    eh->ether_dhost[3],
    eh->ether_dhost[4],
    eh->ether_dhost[5]);
    ret = -1;
    goto done;
    }

    /* Get source IP */
    ((struct sockaddr_in *)&their_addr)->sin_addr.s_addr = iph->saddr;
    inet_ntop(AF_INET, &((struct sockaddr_in*)&their_addr)->sin_addr, sender, sizeof sender);

    /* Look up my device IP addr if possible */
    strncpy(if_ip.ifr_name, ifName, IFNAMSIZ-1);
    if (ioctl(sockfd, SIOCGIFADDR, &if_ip) >= 0) { /* if we can't check then don't */
    printf("Source IP: %s\n My IP: %s\n", sender,
    inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
    /* ignore if I sent it */
    if (strcmp(sender, inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr)) == 0) {
    printf("but I sent it :(\n");
    ret = -1;
    goto done;
    }
    }

    /* UDP payload length */
    ret = ntohs(udph->len) - sizeof(struct udphdr);

    /* Print packet */
    printf("\tData:");
    for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
    printf("\n");

    done: goto repeat;

    close(sockfd);
    return ret;
    }