/* lies_paket.c - liest ein ICMP-Paket per RAW Socket (z. B. ping) */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/ether.h>

/* Gibt ein Byte binaer aus */
void print_bin(int x)
  {
  int i;
  char erg[10];
  erg[9] = '\0';
  erg[8] = ' ';

  for (i = 7; i >= 0 ; i--)
    {
    erg[i] = (x%2 == 0)?'0':'1';
    x = x >> 1;
    }
  printf("%s", erg);
  }

int main(int argc, char *argv[])
  {
  int j, k, sock, bytes;
  /* Puffer fuer ein Ethernet-Paket */
  unsigned char packet[ETHERMTU]; // ETHERMTU = 1500

  /* root-Rechte pruefen */
  if(getuid() != 0)
    {
    printf("\nDu musst Root sein, um das zu machen!\n");
    exit(1);
    }

  sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);

  if (sock == -1)
    {
    perror("socket() ging schief");
    if (errno == EACCES) printf(" (EACCES)\n");
    if (errno == EAFNOSUPPORT) printf(" (EAFNOSUPPORT)\n");
    return 1;
    }

  /* Paket lesen */
  bytes = read(sock, packet, sizeof(packet));

  /* Ausgabe binaer/ASCII, immer 4 Bytes pro Zeile */
  k = 0;  /* Bytezaehler */
  for (j = 0; j < bytes; j++)
    {
    k++;
    print_bin(packet[j]);
    if (packet[j] >= ' ' && packet[j] < 127)
      printf("%c ", packet[j]);
    else
      printf(". ");
    /* alle 4 Bytes Newline */
    if (!(k % 4)) { printf ("\n"); }
    }

  printf("\n");
  return 0;
  }

