icmpecho.cc revision cc808594
1cc808594SShuo Chen#include "faketcp.h"
2b9400f6cSShuo Chen
3b9400f6cSShuo Chen#include <stdio.h>
4b9400f6cSShuo Chen#include <stdlib.h>
5cc808594SShuo Chen#include <string.h>
6b9400f6cSShuo Chen#include <unistd.h>
7b9400f6cSShuo Chen#include <netinet/ip.h>
8cc808594SShuo Chen#include <linux/if_ether.h>
9b9400f6cSShuo Chen
10b9400f6cSShuo Chenint main()
11b9400f6cSShuo Chen{
12b9400f6cSShuo Chen  union
13b9400f6cSShuo Chen  {
14cc808594SShuo Chen    unsigned char buf[ETH_FRAME_LEN];
15b9400f6cSShuo Chen    struct iphdr iphdr;
16b9400f6cSShuo Chen  };
17b9400f6cSShuo Chen
18b9400f6cSShuo Chen  const int iphdr_size = sizeof iphdr;
19b9400f6cSShuo Chen
20b9400f6cSShuo Chen  char ifname[IFNAMSIZ] = "tun%d";
21b9400f6cSShuo Chen  int fd = tun_alloc(ifname);
22b9400f6cSShuo Chen
23b9400f6cSShuo Chen  if (fd < 0)
24b9400f6cSShuo Chen  {
25b9400f6cSShuo Chen    fprintf(stderr, "tunnel interface allocation failed\n");
26b9400f6cSShuo Chen    exit(1);
27b9400f6cSShuo Chen  }
28b9400f6cSShuo Chen
29b9400f6cSShuo Chen  printf("allocted tunnel interface %s\n", ifname);
30b9400f6cSShuo Chen  sleep(1);
31b9400f6cSShuo Chen
32b9400f6cSShuo Chen  for (;;)
33b9400f6cSShuo Chen  {
34b9400f6cSShuo Chen    int nread = read(fd, buf, sizeof(buf));
35b9400f6cSShuo Chen    if (nread < 0)
36b9400f6cSShuo Chen    {
37b9400f6cSShuo Chen      perror("read");
38b9400f6cSShuo Chen      close(fd);
39b9400f6cSShuo Chen      exit(1);
40b9400f6cSShuo Chen    }
41b9400f6cSShuo Chen    printf("read %d bytes from tunnel interface %s.\n", nread, ifname);
42cc808594SShuo Chen    const int iphdr_len = iphdr.ihl*4;
43b9400f6cSShuo Chen
44b9400f6cSShuo Chen    if (nread >= iphdr_size
45b9400f6cSShuo Chen        && iphdr.version == 4
46cc808594SShuo Chen        && iphdr_len >= iphdr_size
47cc808594SShuo Chen        && iphdr_len <= nread
48b9400f6cSShuo Chen        && iphdr.tot_len == htons(nread)
49cc808594SShuo Chen        && in_checksum(buf, iphdr_len) == 0)
50b9400f6cSShuo Chen    {
51cc808594SShuo Chen      const void* payload = buf + iphdr_len;
52cc808594SShuo Chen      if (iphdr.protocol == IPPROTO_ICMP)
53b9400f6cSShuo Chen      {
54cc808594SShuo Chen        icmp_input(fd, buf, payload, nread);
55b9400f6cSShuo Chen      }
56b9400f6cSShuo Chen    }
57b9400f6cSShuo Chen    else
58b9400f6cSShuo Chen    {
59b9400f6cSShuo Chen      printf("bad packet\n");
60b9400f6cSShuo Chen      for (int i = 0; i < nread; ++i)
61b9400f6cSShuo Chen      {
62b9400f6cSShuo Chen        if (i % 4 == 0) printf("\n");
63b9400f6cSShuo Chen        printf("%02x ", buf[i]);
64b9400f6cSShuo Chen      }
65b9400f6cSShuo Chen      printf("\n");
66b9400f6cSShuo Chen    }
67b9400f6cSShuo Chen  }
68b9400f6cSShuo Chen
69b9400f6cSShuo Chen  return 0;
70b9400f6cSShuo Chen}
71