简体   繁体   中英

Converting raw packet data received from a TUN interface

I'm trying to intercept packets going through a TUN interface. I want to convert the raw packet information to readable information so i can use it later.

I'm using the following code:

int main(){
    char tun_name[IFNAMSIZ];
    char data[1500];
    int nread = 0;
    int tun_fd = 0;

    /* Connect to the device */
    strcpy(tun_name, "tun1");
    tun_fd = tun_alloc(tun_name);  /* tun interface, no Ethernet headers*/
    if(tun_fd < 0){
        perror("Allocating interface");
        exit(1);
    }

    /* Now read data coming from the kernel */
    int i=0;
    int count=0;
    char src[INET_ADDRSTRLEN];
    u_int8_t protocol;

    while(1) {
        count ++;

        nread = read(tun_fd, data, sizeof(data));
        if(nread < 0) {
            perror("Reading from interface");
            close(tun_fd);
            exit(1);
        }

        struct ip *iphdr = (struct ip *) data;

        /* Do whatever with the data */
        printf("Packet N° %d\n", count);
        printf("Read %d bytes from device %s\n", nread, tun_name);

        protocol = iphdr->ip_p;
        inet_ntop(AF_INET, &(iphdr->ip_src), src, INET_ADDRSTRLEN);

        printf("\nProtocol: %d", protocol);
        printf("\nIP source address: %s", src);
        printf("\n\n");
    }
    return 0;
}

It seems that i can't read the protocol and the ip src address of the packet. I'm getting weired results.

Can you help please??

Thank you!

The problem was in this line:

tun_fd = tun_alloc(tun_name);  /* tun interface, no Ethernet headers*/

Here is the definition of the function tun_alloc():

int tun_alloc(char *dev) {

    struct ifreq ifr;
    int fd, err;
    char *clonedev = "/dev/net/tun";

    /* open the clone device */
    if( (fd = open(clonedev, O_RDWR)) < 0 ) {
        return fd;
    }

    /* preparation of the struct ifr, of type "struct ifreq" */
    memset(&ifr, 0, sizeof(ifr));

    ifr.ifr_flags = IFF_TUN;   /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */

    if (*dev) {
        strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     }

    /* try to create the device */
    if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
        close(fd); 
    return err;
    }
    strcpy(dev, ifr.ifr_name);
    return fd;

}

Here, in the creation of the TUN interface, we must use the "IFF_NO_PI" flag to delete packet added information and receive just the raw packet.

So, we must use this:

ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 

instead of just:

ifr.ifr_flags = IFF_TUN; 

Hope it helps, Thank you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM