|
@@ -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);
|
|
|
|
+}
|