2017-11-07 6 views
0

これはTUNからレイヤ3フレームを受信する方法です。 ドキュメントに基づいて書かれた:TUNから受信したレイヤ3フレームを解析するために、PCAPまたは他のライブラリを使用する方法を教えてください。

  1. https://www.kernel.org/doc/Documentation/networking/tuntap.txt
  2. http://backreference.org/2010/03/26/tuntap-interface-tutorial/
  3. 再生するには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は通常、パケットの解析には使用されません。 56710試しのような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.あなたがhttps://en.wikipedia.org/wiki/EtherType

を見上げることが86DDを取得します printf("FFF: %x", ntohs(56710)):あなたはしかし、使用することができます
  • 関連する問題