#include #include #include #include #include #include #include #include #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); }