1

I want to find the route of a packet in user space. I have dst ip and I want to read the kernel tables, so it will give me the result according to current ip route cfg. any way of doing that in C?

roni bar yanai
  • 1,492
  • 10
  • 12
  • Yes, there is a way to do that in C. If you show what you've tried, and what problems you have with it, someone is bound to show you how to address the problem. – ryyker Jan 20 '20 at 13:07
  • What exactly do you want as a result? The next-hop IP address, the outgoing interface, a destination MAC address? – Ctx Jan 20 '20 at 13:15
  • in fact I want all of them, but mostly I want the outgoing interface index – roni bar yanai Jan 20 '20 at 13:18

2 Answers2

2

You can do the following to get the interface index:

First, create a UDP socket to your destination:

int fd = socket(AF_INET, SOCK_DGRAM, 0);

struct sockaddr_in in;

in.sin_family = AF_INET;
in.sin_port = htons(1234);
in.sin_addr.s_addr = inet_addr("1.2.3.4");
connect(fd, (struct sockaddr *)&in, sizeof(struct sockaddr_in));

Then, call getsockname() to determine the interface addr of the outgoing interface for this socket:

int inlen = sizeof(in);
getsockname(fd, (struct sockaddr *)&in, &inlen);

Now, get all system interface structures and look for the correct interface address:

struct ifaddrs *ifa, *ifap;

getifaddrs(&ifa);
ifap = ifa;
char *ifname = NULL;
while (ifa) {
   if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr ==
       in.sin_addr.s_addr) {
      ifname = strdup(ifa->ifa_name);
      break;
   }
   ifa = ifa->ifa_next;
}
freeifaddrs(ifap);

Finally, get the interface index for the interface name:

struct ifreq iface;

strncpy(iface.ifr_name, interface, IFNAMSIZ);
iface.ifr_name[IFNAMSIZ-1] = 0;
int len = sizeof(iface);
ioctl(fd, SIOCGIFINDEX, &iface, &len);

int ifindex = iface.ifr_ifindex;

Looks a bit complicated, but is independent from netlink (which isn't much easier either).

Ctx
  • 18,090
  • 24
  • 36
  • 51
1

Asking the kernel via nlmsg looks legit and worked for me in the past.

I started off from this answer back then:

https://stackoverflow.com/a/27331273/6232305

lnksz
  • 421
  • 3
  • 15