ifreq ifr 配置网口信息

//通过ifreq结构体来获取接口信息
struct ifreq
  {    
# define IFHWADDRLEN    6     
# define IFNAMSIZ   IF_NAMESIZE
    union
      {
    char ifrn_name[IFNAMSIZ];   /* Interface name, e.g. "en0".  */
      } ifr_ifrn;

    union
      {
    struct sockaddr ifru_addr;
    struct sockaddr ifru_dstaddr;  
    struct sockaddr ifru_broadaddr;
    struct sockaddr ifru_netmask;  
    struct sockaddr ifru_hwaddr;   
    short int ifru_flags;
    /*
enum net_device_flags {
    IFF_UP              = 1<<0,  /* sysfs */
    IFF_BROADCAST           = 1<<1,  /* __volatile__ */
    IFF_DEBUG           = 1<<2,  /* sysfs */
    IFF_LOOPBACK            = 1<<3,  /* __volatile__ */
    IFF_POINTOPOINT         = 1<<4,  /* __volatile__ */
    IFF_NOTRAILERS          = 1<<5,  /* sysfs */
    IFF_RUNNING         = 1<<6,  /* __volatile__ */
    IFF_NOARP           = 1<<7,  /* sysfs */
    IFF_PROMISC         = 1<<8,  /* sysfs */
    IFF_ALLMULTI            = 1<<9,  /* sysfs */
    IFF_MASTER          = 1<<10, /* __volatile__ */
    IFF_SLAVE           = 1<<11, /* __volatile__ */
    IFF_MULTICAST           = 1<<12, /* sysfs */
    IFF_PORTSEL         = 1<<13, /* sysfs */
    IFF_AUTOMEDIA           = 1<<14, /* sysfs */
    IFF_DYNAMIC         = 1<<15, /* sysfs */
    IFF_LOWER_UP            = 1<<16, /* __volatile__ */
    IFF_DORMANT         = 1<<17, /* __volatile__ */
    IFF_ECHO            = 1<<18, /* __volatile__ */
};
    */     
    int ifru_ivalue;          
    int ifru_mtu;             
    struct ifmap ifru_map;    
    char ifru_slave[IFNAMSIZ];  /* Just fits the size */
    char ifru_newname[IFNAMSIZ];   
    __caddr_t ifru_data;      
      } ifr_ifru;
  };
  int connman_inet_ifindex(const char *name)
{
    struct ifreq ifr; 
    int sk, err; 

    if (!name)
        return -1;

    sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    if (sk < 0) 
        return -1;

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);

    err = ioctl(sk, SIOCGIFINDEX, &ifr);

    close(sk);

    if (err < 0)
        return -1;

    return ifr.ifr_ifindex;
}


char *connman_inet_ifname(int index)
{
    struct ifreq ifr;
    int sk, err;

    if (index < 0)
        return NULL;

    sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    if (sk < 0)
        return NULL;

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_ifindex = index;

    err = ioctl(sk, SIOCGIFNAME, &ifr);

    close(sk);

    if (err < 0)
        return NULL;

    return strdup(ifr.ifr_name);  //需要手动释放内存  free
}

int connman_inet_ifup(int index)    //类似于 ifconfig up
{
    struct ifreq ifr;
    int sk, err;

    sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    if (sk < 0)
        return -errno;

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_ifindex = index;

    if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
        err = -errno;
        goto done;
    }

    if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
        err = -errno;
        goto done;
    }

    if (ifr.ifr_flags & IFF_UP) {
        err = -EALREADY;
        goto done;
    }

    ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);

    if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
        err = -errno;
        goto done;
    }

    err = 0;

done:
    close(sk);

    return err;
}

///sys/class/net/xxx/flags   最终就是修改内核,在应用层映射出来就是这个配置文件  内核映射在sys文件中
int connman_inet_ifdown(int index) //类似于 ifconfig down
{
    struct ifreq ifr, addr_ifr;
    struct sockaddr_in *addr;
    int sk, err;

    sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    if (sk < 0)
        return -errno;

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_ifindex = index;

    if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
        err = -errno;
        goto done;
    }

    if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
                err = -errno;
        goto done;
    }

    memset(&addr_ifr, 0, sizeof(addr_ifr));
    memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
    addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
    addr->sin_family = AF_INET;
    if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
        connman_warn("Could not clear IPv4 address index %d", index);

    if (!(ifr.ifr_flags & IFF_UP)) {
        err = -EALREADY;
        goto done;
    }

    ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;

    if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
        err = -errno;
    else
        err = 0;

done:
    close(sk);

    return err;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

slp941019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值