Tag Archives: netlink

Reading routing table using C program

Reading routing table using C program
#include”sys/socket.h”
#include”sys/types.h”
#include”unistd.h”
#include”stdio.h”
#include”stdlib.h”
#include”string.h”
#include”asm/types.h”
#include”linux/netlink.h”
#include”linux/rtnetlink.h”
#include”sys/ioctl.h”
#include”net/if.h”
#include”net/route.h”

bool CAddressHelper::GetDevGateWay(string &p_sDevName,
std::list

& p_Gateways) {

//#pragma pack(2)
// Structure for sending the request
typedef struct {
struct nlmsghdr nlMsgHdr;
struct rtmsg rtMsg;
char buf[1024];
} route_request;

struct RouteInfo {
unsigned long dstAddr;
unsigned long mask;
unsigned long gateWay;
unsigned long flags;
unsigned long srcAddr;
unsigned char proto;
char ifName[IF_NAMESIZE];
};

int route_sock, i, j;
route_request NewRequest;
route_request *request = &NewRequest;
int retValue = -1, nbytes = 0, reply_len = 0;
char reply_ptr[1024];
ssize_t counter = 1024;
int count = 0;
struct rtmsg *rtp;
struct rtattr *rtap;
struct nlmsghdr *nlp;
int rtl;
struct RouteInfo route[24];
char* buf = reply_ptr;
unsigned long bufsize;

route_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

if (-1 == route_sock)
return false;

bzero(request, sizeof(route_request));

request->nlMsgHdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
request->nlMsgHdr.nlmsg_type = RTM_GETROUTE;
request->nlMsgHdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;

// set the routing message header
request->rtMsg.rtm_family = AF_INET;
request->rtMsg.rtm_table = RT_TABLE_MAIN; // RT_TABLE_MAIN

if ((retValue = send(route_sock, request, sizeof(route_request), 0)) < 0) { perror("send"); return false; } for (;;) { if (counter < sizeof(struct nlmsghdr)) { printf("Routing table is bigger than 1024\n"); return false; } nbytes = recv(route_sock, &reply_ptr[reply_len], counter, 0); if (nbytes < 0) { printf("Error in recv\n"); break; } if (nbytes == 0) printf("EOF in netlink\n"); nlp = (struct nlmsghdr*) (&reply_ptr[reply_len]); if (nlp->nlmsg_type == NLMSG_DONE) {
// All data has been received.
// Truncate the reply to exclude this message,
// i.e. do not increase reply_len.
break;
}

if (nlp->nlmsg_type == NLMSG_ERROR) {
printf(“Error in msg\n”);
return false;
}

reply_len += nbytes;
counter -= nbytes;

}

bufsize = reply_len;
// string to hold content of the route
// table (i.e. one entry)

// outer loop: loops thru all the NETLINK
// headers that also include the route entry
// header
nlp = (struct nlmsghdr *) buf;

for (i = -1; NLMSG_OK(nlp, bufsize); nlp = NLMSG_NEXT(nlp, bufsize))
{
// get route entry header
rtp = (struct rtmsg *) NLMSG_DATA(nlp);
// we are only concerned about the
// tableId route table
if (rtp->rtm_table != RT_TABLE_MAIN)
continue;
i++;
// init all the strings
bzero(&route[i], sizeof(struct RouteInfo));
//flags = rtp->rtm_flags;
route[i].proto = rtp->rtm_protocol;

// inner loop: loop thru all the attributes of
// one route entry
rtap = (struct rtattr *) RTM_RTA(rtp);
rtl = RTM_PAYLOAD(nlp);
for (; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap, rtl))
{
switch (rtap->rta_type) {
// destination IPv4 address
case RTA_DST:
count = 32 – rtp->rtm_dst_len;

route[i].dstAddr = *(unsigned long *) RTA_DATA(rtap);

route[i].mask = 0xffffffff;
for (; count != 0; count–)
route[i].mask = route[i].mask << 1; printf("dst:%s \tmask:0x%x \t",CAddressHelper::IntIP2str(route[i].dstAddr).c_str(), route[i].mask); break; case RTA_GATEWAY: route[i].gateWay = *(unsigned long *) RTA_DATA(rtap); printf("gw:%s\t",CAddressHelper::IntIP2str(route[i].gateWay).c_str()); break; case RTA_PREFSRC: route[i].srcAddr = *(unsigned long *) RTA_DATA(rtap); // printf("src:%s\t", CAddressHelper::IntIP2str(route[i].srcAddr).c_str()); break; // unique ID associated with the network // interface case RTA_OIF: CAddressHelper::GetInterfaceName(*((int *) RTA_DATA(rtap)), route[i].ifName); printf("ifname %s\n", route[i].ifName); break; default: break; } } //set Flags } // Print the route records // printf("Destination\tGateway \tNetmask \tflags \tIfname \n"); // printf("———–\t——- \t——–\t——\t—— \n"); for (j = 0; j <= i; j++) { if (p_sDevName == route[j].ifName&&route[j].gateWay!=0) { Address newGate; newGate.Ip = route[j].gateWay; p_Gateways.push_back(newGate); } printf("%s \t %s \t0x%08x \t%d \t%s\n", CAddressHelper::IntIP2str(route[j].dstAddr).c_str(), CAddressHelper::IntIP2str(route[j].gateWay).c_str(), route[j].mask, route[j].flags, route[j].ifName); } return true; }