Set host default gateway in C program.

Hello everybody,
I'm having troubles on setting the default gateway address (and other addresses, such as netmask, or ip) of the host running a C program. I know it has to be with ioctl, but don't know how to do it.

Could somebody give me an example on how to set the default gateway address of a determinated device from the C program?

Any comment will be of help,
Thanks.

Usually, even in C, you'd just use the commandline tools. This will make for a much more portable program. Otherwise, the ioctl's will vary wildly across systems. I'm not sure it even uses ioctl to do so in linux at all, for that matter -- it might be netlink these days, which is a lot more impenetrable.

Suppose you have IP 192.168.1.2, mask 255.255.255.0, DNS server 192.168.1.1, gateway 192.168.1.1. You can change the IP and netmask of an interface with the ifconfig tool, like so:

/sbin/ifconfig eth0 ip 192.168.1.2 netmask 255.255.255.0

You can alter DNS parameters by managing the list of hosts in /etc/resolv.conf .

echo nameserver 192.168.1.1 > /etc/resolv.conf

And gateways are done through the route command.

/sbin/route add default gateway 192.168.1.1 eth0

If you really insist on doing it with ioctl, try runing strace ifconfig eth0 ip 192.168.1.2 netmask 255.255.255.0 to see what raw ioctl it uses; that's how I found things like the serial port ioctls...

Excellent man, great explanation, i'll try strace.
Thank you very much.

The ifconfig source code file you want to look at is changeif.c. You can find it via Koders Open Source Search Engine or in the source code of any of the major GNU/Linux distributions.

Just to update, i found a easier solution to this problem.

Intead of using system() to run command-line programs, you can add a default gateway route by ioctl with SIOCADDRT and SIOCDELRT, it's very simple.

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <net/route.h>
#include <sys/types.h>
#include <sys/ioctl.h>

int main(char** args) {
  int sockfd;
  struct rtentry route;
  struct sockaddr_in *addr;
  int err = 0;

  // create the socket
 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)))<0){
perror("socket");
exit(1);
}

  memset(&route, 0, sizeof(route));
  addr = (struct sockaddr_in*) &route.rt_gateway;
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = inet_addr("192.168.2.1");
  addr = (struct sockaddr_in*) &route.rt_dst;
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = inet_addr("0.0.0.0");
  addr = (struct sockaddr_in*) &route.rt_genmask;
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = inet_addr("0.0.0.0");
  route.rt_flags = RTF_UP | RTF_GATEWAY;
  route.rt_metric = 0;
  if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) {
    perror("SIOCADDRT failed");
    exit(1);
  }
}

Hope this helps someone.

1 Like