【问题标题】:How to know the set for IP address from C in linux is successful or fail如何知道在linux中从C中设置IP地址是成功还是失败
【发布时间】:2016-10-09 23:36:38
【问题描述】:

我使用此代码设置 IP 地址

int
set_ip(const char *name, const char *ip)
{
  struct ifreq ifr;
  struct sockaddr_in *addr;
  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);

  strncpy(ifr.ifr_name, name, IFNAMSIZ);

  ifr.ifr_addr.sa_family = AF_INET;

  addr = (struct sockaddr_in*)&ifr.ifr_addr;

  /* inet_pton() returns 1 on success */
  /* network address was successfully converted */
  int s;
  s = inet_pton(AF_INET, ip, &addr->sin_addr);
  if (s <= 0) {
    if (s == 0)
      fprintf(stderr, "Set IP %s not in presentation format\n", ip);
    else
      perror ("inet_pton");
    exit (EXIT_FAILURE);
  }

  ioctl(fd, SIOCSIFADDR, &ifr);

  ioctl(fd, SIOCGIFFLAGS, &ifr);
  strncpy(ifr.ifr_name, name, IFNAMSIZ);
  ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);

  ioctl(fd, SIOCSIFFLAGS, &ifr);
  return 0;
}

代码从这里How to set the IP address from C in linux修改。

我的问题是

如何知道ip地址更改成功与否?因为ioctl的返回值总是0。

$ uname -a
Linux DMA1 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

我已经搜索了几个小时,但没有找到任何解决方案。所以我在这里发布我的问题来询问专家。提前致谢

【问题讨论】:

  • 通过检查ioctl(fd, SIOCSIFADDR, &amp;ifr)的返回值。
  • @NominalAnimal 我检查了,但即使将 ip 地址设置为 192.168.1.abc,ioctl 返回 0。
  • @NominalAnimal 也许我需要先检查 inet_pton 中的名称
  • 你为什么不查询ip地址看看是不是你要求的?
  • @charles.cc.hsu:不,你的代码检查ioctl(fd, SIOCSIFFLAGS, &amp;ifr)的返回值,这是一个完全不相关的操作。如果您确实添加了正确的错误检查,请修改您的问题以反映您使用的实际代码。

标签: c linux networking


【解决方案1】:

谢谢大家,以下是各位专家建议的解决方案:

#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h> // struct rtentry
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int 
set_addr (const char *name, const char *ip, unsigned long request)
{
  struct ifreq ifr;
  struct sockaddr_in *addr;
  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);

  strncpy(ifr.ifr_name, name, IFNAMSIZ);
  ifr.ifr_addr.sa_family = AF_INET;
  addr = (struct sockaddr_in*)&ifr.ifr_addr;

  // inet_pton() returns 1 on success
  // network address was successfully converted
  int s;
  s = inet_pton(AF_INET, ip, &addr->sin_addr);
  if (s <= 0) {
    if (s == 0)
      fprintf(stderr, "Set IP %s not in presentation format\n", ip);
    else
      perror ("inet_pton");
    exit (EXIT_FAILURE);
  }

  if (ioctl(fd, request, &ifr) != 0) { // SIOCSIFADDR
    perror ("ioctl");
    exit (EXIT_FAILURE);
  }

  ioctl(fd, SIOCGIFFLAGS, &ifr);

  strncpy(ifr.ifr_name, name, IFNAMSIZ);
  ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
  ioctl(fd, SIOCSIFFLAGS, &ifr);
  return 0;
}

不要忘记在 Makefile 或命令行中使用以下命令为您的程序授予 root 权限:

$ sudo chown root your_program
$ sudo chmod a+xs your_program

否则会收到错误消息ioctl: Operation not permitted

【讨论】:

    猜你喜欢
    • 2011-10-02
    • 2020-03-01
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2013-11-27
    • 1970-01-01
    相关资源
    最近更新 更多