Douglas Andreani před 5 roky
rodič
revize
6c408451ea
2 změnil soubory, kde provedl 134 přidání a 0 odebrání
  1. 117 0
      tun/netw.c
  2. 17 0
      tun/run.sh

+ 117 - 0
tun/netw.c

@@ -0,0 +1,117 @@
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define MTU 1500
+
+typedef struct ipv4 {
+    u_int16_t tun_flags; //tun specific 16 bits
+    u_int16_t tun_proto; //tun specific 16 bits
+    u_int8_t version; // 4 bits
+    u_int8_t header_length; // 4 bits
+    u_int8_t type_of_service; // 8 bits
+    u_int16_t total_length; //16 bits
+    u_int16_t identification; // 16 bits
+    u_int8_t flags; // 3 bits
+
+} ipv4_t;
+
+int create_tun(char *dev_name, int flags){
+    struct ifreq ifr;
+    int fd, err;
+    char *clonedev = "/dev/net/tun";
+
+    if ((fd = open(clonedev, O_RDWR)) < 0)
+    {
+        return fd;
+    }
+
+    memset(&ifr, 0, sizeof(ifr));
+    ifr.ifr_ifru.ifru_flags = flags;
+
+    if(*dev_name) {
+        strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, IFNAMSIZ);
+    }
+
+    if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
+    {
+        close(fd);
+        return err;
+    }
+
+    strcpy(dev_name, ifr.ifr_ifrn.ifrn_name);
+
+    return fd;
+}
+
+void print_packet(u_int8_t* buf, int buf_size) {
+    int i;
+
+    printf("received %d bytes: ", buf_size);
+
+    for (i = 0; i < buf_size; i++)
+    {
+        if (i > 0) printf(":");
+        printf("%02X", buf[i]);
+    }
+    printf("\n");
+}
+
+
+// 0100 0110 46
+// 1111 0000 
+// 0100 0000 40
+// 46 - 40 = 6
+
+// 0100 0110 46
+// 0000 1111 
+// 0000 0110 6
+// 46 - 6 = 40
+
+
+ipv4_t parse_packet(u_int8_t *buf, int buf_size) {
+    
+    ipv4_t p;
+    p.tun_flags = buf[1]<<8 | buf[0];
+    p.tun_proto = buf[2]<<8 | buf[3];
+    p.version =  buf[4] - (buf[4] & 00001111);
+    p.header_length = buf[4] - (buf[4] & 11110000);
+    p.type_of_service = buf[5];
+    p.total_length = buf[6]<<8 | buf[7];
+    p.identification = buf[8]<<8 | buf[9];
+    p.flags = buf[10] - (buf[10] & 00011111);
+    return p;
+}
+
+int main (int argc, char** argv) {
+    char tun_name[IFNAMSIZ];
+    u_int8_t buf[MTU];
+    int ret;
+    ipv4_t curr_packet;
+
+    sprintf(tun_name, "tun01");
+    int tunfd = create_tun(tun_name, (IFF_TUN));
+    if (tunfd < 0) {
+        fprintf(stderr, "could not allocate device tun.\n");
+        return(EXIT_FAILURE);
+    }
+    
+    for (;;) {
+        ret = read(tunfd, buf, MTU);
+        curr_packet = parse_packet(buf, ret);
+
+        if (curr_packet.tun_proto == 0x800) {
+            printf("proto: %02X\n", curr_packet.tun_proto);
+            printf("version: %02X\n", curr_packet.version);
+            printf("header length %02X\n", curr_packet.header_length);
+            print_packet(buf, ret);
+        }
+    }
+   
+    return (0);
+}

+ 17 - 0
tun/run.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+
+gcc -o netw netw.c
+
+ext=$?
+if [[ $ext -ne 0 ]]; then
+	exit $ext
+fi
+
+sudo setcap cap_net_admin=eip netw
+./netw &
+
+pid=$!
+sudo ip addr add 192.168.99.1/24 dev tun01
+sudo ip link set up dev tun01
+trap "kill $pid" INT TERM
+wait $pid