在linux系统中如何编程删除一个接口的ip地址

在linux系统中如何删除一个接口的ip地址?

由于软件需要,有时候需要对linux的网卡配置多个ip地址,如监控系统中的网卡处于网络分域或者是多个网段中,在程序配置网卡地址时需要增加或者删除ip地址:

一般使用ioctl系统调用来更改网络接口的属性:

一、删除应该使用SIOCDIFADDR,但是在ipv4中没有实现这个调用,在ipv6中实现了

所以在ipv4下调用会出现 Invalid argument的错误

二、这里有一种变通的方法来删除ip地址,即使用SIOCSIFADDR来给接口设置0.0.0.0的地址,效果是对应接口上ip地址被删除了,

具体的操作:

  • 通过SIOCGIFCONF来枚举所有的带不同IP的接口
  • 在这些接口中使用SIOCGIFADDR获取IP
  • 如果发现要删除IP,使用SIOCSIFADDR "0.0.0.0"来删除IP

三、举例

    int fd;
    int interfaceNum = 0;
    struct ifreq buf[32];
    struct ifconf ifc;
    struct ifreq ifrcopy;
    int okNetA = 1;
    int okNetB = 1;

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("socket");
        close(fd);
        return false;
    }


    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = (caddr_t)buf;
    if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
    {
        interfaceNum = ifc.ifc_len / sizeof(struct ifreq);
        while (interfaceNum-- > 0) //逐个提取
        {
            if ((okNetA && !strnicmp(buf[interfaceNum].ifr_name, ifname_a, strlen(ifname_a))) ||
                (okNetB && !strnicmp(buf[interfaceNum].ifr_name, ifname_b, strlen(ifname_b))))
            {
                ifrcopy = buf[interfaceNum];
              
                if (!ioctl(fd, SIOCGIFADDR, (char *)&ifrcopy))
              {
                  char ip[32];
                  snprintf(ip, sizeof(ip), "%s",
                      (char *)inet_ntoa(((struct sockaddr_in *) &
                    (ifrcopy.ifr_addr))->sin_addr));
                  printf("device ip: %s\n", ip);
              /*}
              else
              {
                  printf("ioctl: %s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
                  close(fd);
                  return -1;*/
              }
              
              struct sockaddr_in sai;              
              memset(&sai, 0, sizeof(struct sockaddr));
            sai.sin_family = AF_INET;
            sai.sin_port = 0;
            sai.sin_addr.s_addr = 0;

            memcpy( (char *)&(ifrcopy.ifr_addr), (char *) &sai, sizeof(struct sockaddr));
                        
            if (ioctl(fd, SIOCSIFADDR, (caddr_t)&ifrcopy,sizeof(ifrcopy)))
            {
                printf("ioctl: %s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);  
                    //close(fd);
                    //return false;
            }
        }
    }

 

四、参考资料:

http://mailman.icsi.berkeley.edu/pipermail/xorp-hackers/2003-October/000010.html

https://stackoverflow.com/questions/5308090/set-ip-address-using-siocsifaddr-ioctl

https://www.ibm.com/support/knowledgecenter/ssw_aix_72/communicationtechref/ioctl_socket_control_operations.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值