0

我正在尝试拦截通过 TUN 接口的数据包。我想将原始数据包信息转换为可读信息,以便以后使用。

我正在使用以下代码:

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;
}

似乎我无法读取数据包的协议和 ip src 地址。我得到了奇怪的结果。

你能帮忙吗?

谢谢!

4

1 回答 1

0

问题出在这一行:

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

下面是函数 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;

}

这里,在创建 TUN 接口时,我们必须使用“IFF_NO_PI”标志来删除数据包添加信息,只接收原始数据包。

所以,我们必须使用这个:

ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 

而不仅仅是:

ifr.ifr_flags = IFF_TUN; 

希望对你有帮助,谢谢。

于 2014-06-11T09:19:31.263 回答