roni bar yanai
roni bar yanai

Reputation: 1492

Read routing table from user space

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?

Upvotes: 1

Views: 793

Answers (2)

Ctx
Ctx

Reputation: 18420

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).

Upvotes: 2

lnksz
lnksz

Reputation: 501

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

Upvotes: 2

Related Questions