charles.cc.hsu charles.cc.hsu - 1 month ago 18
Linux Question

How to know the set for IP address from C in linux is successful or fail

I use this code to setup the IP address

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;
}


The code is modified from here How to set the IP address from C in linux.

My question is

How to know the ip address change successfully or not? Because the return value of ioctl always be 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


I have googled for hours but not found any solutions. So I post my question in here to ask experts in SO. Thanks in advance

Answer

Thank you all, below is the solution suggested by you experts:

#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;
}

Don't forget to grant your program with root privilege using following commands in your Makefile or command line:

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

Otherwise, you will get a error message ioctl: Operation not permitted