2017-11-07 5 views
0

TUN에서 레이어 3 프레임을 수신하는 방법입니다. 이 문서의 내용에 기초하여 작성 : https://www.kernel.org/doc/Documentation/networking/tuntap.txt TUN에서받은 레이어 3 프레임을 구문 분석하기 위해 PCAP 또는 다른 라이브러리를 어떻게 사용할 수 있습니까?

  • http://backreference.org/2010/03/26/tuntap-interface-tutorial/
    1. http://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <net/if.h> 
    #include <linux/if_tun.h> 
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <sys/ioctl.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 
    #include <arpa/inet.h> 
    #include <sys/select.h> 
    #include <sys/time.h> 
    #include <errno.h> 
    #include <stdarg.h> 
    
    /* buffer for reading from tun/tap interface, must be >= 1500 */ 
    #define BUFSIZE 2000 
    
    int tun_alloc(char *dev) 
    { 
        struct ifreq ifr; 
        int fd, err; 
    
        if (!dev) { 
         return -1; 
        } 
    
        memset(&ifr, 0, sizeof(ifr)); 
        /* Flags: IFF_TUN - TUN device (no Ethernet headers) 
        *  IFF_TAP - TAP device 
        * 
        *  IFF_NO_PI - Do not provide packet information 
        *  IFF_MULTI_QUEUE - Create a queue of multiqueue device 
        */ 
        ifr.ifr_flags = IFF_TUN; 
        strcpy(ifr.ifr_name, dev); 
    
        if ((fd = open("/dev/net/tun", O_RDWR)) < 0) 
         return fd; 
    
        err = ioctl(fd, TUNSETIFF, (void *)&ifr); 
        if (err) { 
         close(fd); 
         goto err; 
        } 
    
        strcpy(dev, ifr.ifr_name); 
    
        return fd; 
    err: 
        close(fd); 
        return err; 
    } 
    
    int main() { 
    
        char *tun_name; 
        tun_name = malloc(IFNAMSIZ); 
        tun_name[0] = '\0'; 
    
        int tun_fd = tun_alloc(tun_name); 
        if (tun_fd < 0) { 
        puts("Try as root"); 
        exit(1); 
        } 
    
        if (ioctl(tun_fd, TUNSETPERSIST, 0) < 0) { 
        perror("disabling TUNSETPERSIST"); 
        exit(1); 
        } 
        printf("Set interface '%s' nonpersistent\n", tun_name); 
    
        struct layer3_frame 
        { 
         uint16_t flags; 
         uint16_t proto; 
         uint8_t version; 
         unsigned char payload[]; 
        } __attribute__((packed)); 
    
        int nread; 
        char buffer[BUFSIZE]; 
        while(1) { 
    
        nread = read(tun_fd, buffer, sizeof(buffer)); 
        if(nread < 0) { 
         perror("Reading from interface"); 
         close(tun_fd); 
         exit(1); 
        } 
    
        /* Do whatever with the data */ 
        printf("Read %d bytes from device %s\n", nread, tun_name); 
    
        struct layer3_frame* l3f = (struct layer3_frame*)(buffer); 
        printf("FLAGS %d, PROTO %d, VER %d", l3f->flags, l3f->proto, l3f->version); 
        // E.g. FLAGS 0, PROTO 56710, VER 96 
        // Why PROTO is not 4 or 6, why VER is not 4 or 6? 
        // MAIN: HOW TO USE PCAP TO PARSE l3f FURTHER 
        // AND GET INFO UP TO SNI (server name indication), e.g. 
    
        } 
    
        return 0; 
    
    } 
    

    에서 풀기 재생하려면
    gcc index.c
    sudo ./a.out
    sudo ip link set tun0 up

  • 답변

    0
    1. PCAP는 일반적으로 패킷을 분석하는 데 사용되지 않습니다.
    2. 당신은 그러나 사용할 수 있습니다 : PROTO에 대한 이상한 값에 대한
    #include <netinet/ip.h> 
    #include <netinet/ip6.h> 
    //... 
    
    struct layer3_frame 
    { 
        uint16_t flags; // FLAGS from TUN 
        uint16_t proto; // PRPTO from TUN 
        unsigned char payload[]; // FRAME/PACKET 
    } __attribute__((packed)); 
    
    const struct ip* ippacket = (struct ip*)(l3p->payload); 
    printf("Version is %d", ippacket->ip_v) 
    

    3. 56710이 printf("FFF: %x", ntohs(56710))을 시도처럼 당신이 86dd을 얻을 것이다 당신이 https://en.wikipedia.org/wiki/EtherType

    에서 찾아 볼 수 있습니다
    관련 문제