注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

蒙奇D小豌豆的博客

蒙奇D小豌豆的学习记录

 
 
 

日志

 
 

Multiqueue tun/tap device  

2014-09-23 11:00:59|  分类: network |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
int tun_alloc_mq(const char *dev, int flags, int queues, int *fds, int persist)
{
    struct ifreq ifr;
    int fd, err, i;

    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 =  flags | IFF_NO_PI | IFF_MULTI_QUEUE;
    strcpy(ifr.ifr_name, dev);

    for (i = 0; i < queues; i++)
    {
        if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
            goto err;
        err = ioctl(fd, TUNSETIFF, (void *)&ifr);
           if (err)
        {    
            perror("setIff");
            close(fd);
               goto err;
        }
           fds[i] = fd;
    }

    /*set dev to persist*/
    if(ioctl(fd, TUNSETPERSIST, persist) < 0)
    {
           perror("TUNSETPERSIST");
           close(fd);
        goto err;
     }
      
    return 0;

err:
    for (--i; i >= 0; i--)
        close(fds[i]);
    return err;

}

/**
 *  ifconfig vnet0 up
 */  
int interface_up(char *interface_name)  
{  
    int s;  
 
    if((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)  
    {  
        printf("Error create socket :%d\n", errno);  
        return -1;  
    }  
 
    struct ifreq ifr;  
    strcpy(ifr.ifr_name, interface_name);  
 
    short flag;  
    flag = IFF_UP;  
    if(ioctl(s, SIOCGIFFLAGS, &ifr) < 0)  
    {  
        printf("Error up %s :%d\n", interface_name, errno);  
        return -1;  
    }  
 
    ifr.ifr_ifru.ifru_flags |= flag;  
 
    if(ioctl(s, SIOCSIFFLAGS, &ifr) < 0)  
    {  
        printf("Error up %s :%d\n", interface_name, errno);  
        return -1;  
    }  

    close(s);
 
    return 0;  
}  
/* ifconfig vnet0 up*/
int interface_down(char *interface_name)  
{  
    int s;  
 
    if((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)  
    {  
        printf("Error create socket :%d\n", errno);  
        return -1;  
    }  
 
    struct ifreq ifr;  
    strcpy(ifr.ifr_name, interface_name);  
 
    short flag;  
    flag = IFF_UP;  
    if(ioctl(s, SIOCGIFFLAGS, &ifr) < 0)  
    {  
        printf("Error up %s :%d\n", interface_name, errno);  
        return -1;  
    }  
 
    ifr.ifr_ifru.ifru_flags &= ~flag;  
 
    if(ioctl(s, SIOCSIFFLAGS, &ifr) < 0)  
    {  
        printf("Error down %s :%d\n", interface_name, errno);  
        return -1;  
    }  

    close(s);
 
    return 0;  
}  
 
/**
 *  ifconfig vnet0 ip_addr
 */  
int set_ipaddr(char *interface_name, char *ip)  
{  
    int s;  
 
    if((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)  
    {  
        printf("Error up %s :%d\n", interface_name, errno);  
        return -1;  
    }  
 
    struct ifreq ifr;  
    strcpy(ifr.ifr_name, interface_name);  
 
    struct sockaddr_in addr;  
    bzero(&addr, sizeof(struct sockaddr_in));  
    addr.sin_family = PF_INET;  
    inet_aton(ip, &addr.sin_addr);  
 
    memcpy(&ifr.ifr_ifru.ifru_addr, &addr, sizeof(struct sockaddr_in));  
 
    if(ioctl(s, SIOCSIFADDR, &ifr) < 0)  
    {  
        printf("Error set %s ip :%d\n", interface_name, errno);  
        return -1;  
    }  

    close(s);
 
    return 0;  
}  
 

int main(int argc, char *argv[])
{
    char tap_name[IFNAMSIZ];
    int tapfd[6], ret = 0;

    if(argc <= 2)
    {
        printf("%s devname persist [ipaddr]\n", argv[0]);
        return -1;
    }

    memset(tap_name, 0, IFNAMSIZ);
    strcpy(tap_name, argv[1]);
     
    
    if (atoi(argv[2]))
    {
        ret = tun_alloc_mq(tap_name, IFF_TAP, 6, tapfd, 1);
        /* tup interface: L3 device, IFF_TAP: tap interface: L2 device */
        assert(ret == 0);        
    }
    else
    {
        ret = tun_alloc_mq(tap_name, IFF_TAP, 2, tapfd, 0 );
        assert(ret == 0);
        ret = interface_down(tap_name);
        assert(ret == 0);

        printf("set %s interface down\n", tap_name);
        return 0;
    }

    //while(1);

    printf("Set '%s' persistent:%d\n", tap_name, atoi(argv[2]));
    assert(argc == 4);

    ret = set_ipaddr(tap_name, argv[3]);
    assert(ret == 0);

    printf("set %s ip addr:%s\n", tap_name, argv[3]);

    ret = interface_up(tap_name);
    assert(ret == 0);

    printf("set %s interface up\n", tap_name);

    int nreadm, i;
    unsigned char buf[1514];
    
    
    while(1)
    {
        unsigned char ip[4];  
 
           ret = read(tapfd[0], buf, sizeof(buf));  
           if (ret < 0)  
               break;  
        printf("read %d bytes\n", ret);
        for(i=0; i<ret; i++)
        {
            printf("%x, ", buf[i]);
        }

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

        ret = write(tapfd[0], buf, ret);
        if (ret < 0)
            break;
        printf("\n");
    }
    
    sleep(3);
    close(tapfd[0]);
    close(tapfd[1]);

    return 0;
}
  评论这张
 
阅读(366)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018