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  char ifname[IFNAMSIZ] = "tun%d";
13b9400f6cSShuo Chen  int fd = tun_alloc(ifname);
14b9400f6cSShuo Chen
15b9400f6cSShuo Chen  if (fd < 0)
16b9400f6cSShuo Chen  {
17b9400f6cSShuo Chen    fprintf(stderr, "tunnel interface allocation failed\n");
18b9400f6cSShuo Chen    exit(1);
19b9400f6cSShuo Chen  }
20b9400f6cSShuo Chen
21b9400f6cSShuo Chen  printf("allocted tunnel interface %s\n", ifname);
22b9400f6cSShuo Chen  sleep(1);
23b9400f6cSShuo Chen
24b9400f6cSShuo Chen  for (;;)
25b9400f6cSShuo Chen  {
26b2fec1eaSShuo Chen    union
27b2fec1eaSShuo Chen    {
28b2fec1eaSShuo Chen      unsigned char buf[ETH_FRAME_LEN];
29b2fec1eaSShuo Chen      struct iphdr iphdr;
30b2fec1eaSShuo Chen    };
31b2fec1eaSShuo Chen
32b2fec1eaSShuo Chen    const int iphdr_size = sizeof iphdr;
33b2fec1eaSShuo 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);
42b9400f6cSShuo Chen
43b2fec1eaSShuo Chen    const int iphdr_len = iphdr.ihl*4;
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