I want to parse the routes returned by the kernel when invoking the sysctl
function with the arguments: { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP2, 0 }
.
After doing that I get several routing messages, in all of them I have found the issue: the struct sockaddr*
at index RTAX_NETMASK
doesn't contain a valid struct sockaddr
.
The code to extract the addresses from the struct rt_msghdr2
returned by sysctl
is the following:
// ROUNDUP Taken from route.c
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
struct rt_msghdr2* routeMsg = (struct rt_msgdr2*)buffer;
struct sockaddr* sockAddrArray[RTAX_MAX];
memset(sockAddrArray, 0, sizeof(sockAddrArray));
struct sockaddr* currentSockAddr;
currentSockAddr = (struct sockaddr*)(routeMsg + 1);
for (int i = 0; i < RTAX_MAX; i++) {
if (routeMsg->rtm_addrs & (1 << i)) {
sockAddrArray[i] = currentSockAddr;
currentSockAddr = (struct sockaddr *)(ROUNDUP(currentSockAddr->sa_len) + (char *)currentSockAddr);
}
else {
sockAddrArray[i] = NULL;
}
}
Even though the routeMsg
states that it has a netmask, when I check the contents I find that it has something like this:
sockAddrArray[RTAX_NETMASK]->sa_len = 0
sockAddrArray[RTAX_NETMASK]->sa_type = \xff
sockAddrArray[RTAX_NETMASK]->sa_data = { \xff, \xff, \0, ...}
The weird thing is that the matching route on the host (based on the network and gateway addresses) has the netmask 255.255.255.0
which matches too well to the direct content of the of the netmask sockaddr
.
Of course, I cannot trust anything else that comes after the RTAX_NETMASK
in the array as it will be incorrectly parsed.
Does someone know why this happens?