将收到的ping包转发给tun设备并回应

组网环境:

将收到的ping包转发给tun设备并回应

A为host上的虚拟机,使用host-only的方式连接。

使用网上《Linux的TUN/TAP编程》中的例子,打开一个tun0端口,响应此端口收到的icmp报文。代码如下:

#include <sys/ioctl.h>

#include <linux/if_tun.h>

#include <stddef.h>

#include <net/if.h>

#include <fcntl.h>

#include <assert.h>



int tun_create(char *dev, int flags)

{

    struct ifreq ifr;

    int fd, err;



    assert(dev != NULL);



    if ((fd = open("/dev/net/tun", O_RDWR)) < 0) //open character device

        return fd;



    memset(&ifr, 0, sizeof(ifr));

    ifr.ifr_flags |= flags;

    if (*dev != '\0')

        strncpy(ifr.ifr_name, dev, IFNAMSIZ);



    err = ioctl(fd, TUNSETIFF, (void *)&ifr);



    if (err < 0)

    {

        close(fd);

        return err;

    }

    strcpy(dev, ifr.ifr_name);



    return fd;

}



int main(int argc, char *argv[])

{

    int tun, ret;

    char tun_name[IFNAMSIZ];

    unsigned char buf[4096] = {0};



    tun_name[0] = '\0';

    tun = tun_create(tun_name, IFF_TUN | IFF_NO_PI);

    if (tun < 0) {

        perror("tun_create");

        return 1;

    }

    printf("TUN name is %s\n", tun_name);



    while (1) {

        unsigned char ip[4];



        ret = read(tun, buf, sizeof(buf));

        if (ret < 0)

            break;

        int i = 0;

        for (i = 0; i < ret; i++)

        {

            printf("%02x ", buf + i);

            if (i % 16 == 0)

                printf("\n");

        }

        printf("\n");

        memcpy(ip, &buf[12], 4);

        memcpy(&buf[12], &buf[16], 4);

        memcpy(&buf[16], ip, 4);

        buf[20] = 0;

        *((unsigned short*)&buf[22]) += 8;

        printf("read %d bytes\n", ret);

        ret = write(tun, buf, ret);

        printf("write %d bytes\n", ret);

    }



    return 0;

}

运行程序,在A上打开tun0接口:

tony@ubuntu-a:~/code/nat-pt$ sudo ifconfig tun0 0.0.0.0 up

并增加一条路由,将目的IP为10.10.10.1的报文送至tun0接口:

tony@ubuntu-a:~/code/nat-pt$ sudo route add 10.10.10.1 dev tun0

在A上还要添加一条规则,将A的eth1接口收到的icmp报文的目的地址改为10.10.10.1:

tony@ubuntu-a:~/code$ sudo iptables -t nat -A PREROUTING -d 192.168.16.130 -p icmp -j DNAT --to-destination 10.10.10.1

这样,我们ping 192.168.16.130这个地址的时候,icmp报文被送到host后,目的地址变成10.10.10.1,然后命中路由,送至tun0,经过处理后,从tun0发出去。

 

你可能感兴趣的:(ping)