static NetlinkList *getResultList(int p_socket, int p_request) { if(netlink_send(p_socket, p_request) < 0) { return NULL; } NetlinkList *l_list = NULL; NetlinkList *l_end = NULL; int l_size; int l_done = 0; while(!l_done) { struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); if(!l_hdr) { // error freeResultList(l_list); return NULL; } NetlinkList *l_item = newListItem(l_hdr, l_size); if(!l_list) { l_list = l_item; } else { l_end->m_next = l_item; } l_end = l_item; } return l_list; }
int getifaddrs(struct ifaddrs **ifap) { int l_socket; int l_result; int l_numLinks; NetlinkList *l_linkResults; NetlinkList *l_addrResults; if(!ifap) { return -1; } *ifap = NULL; l_socket = netlink_socket(); if(l_socket < 0) { return -1; } l_linkResults = getResultList(l_socket, RTM_GETLINK); if(!l_linkResults) { close(l_socket); return -1; } l_addrResults = getResultList(l_socket, RTM_GETADDR); if(!l_addrResults) { close(l_socket); freeResultList(l_linkResults); return -1; } l_result = 0; l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1) { l_result = -1; } freeResultList(l_linkResults); freeResultList(l_addrResults); close(l_socket); return l_result; }
int getifaddrs(struct ifaddrs **ifap) { if(!ifap) { return -1; } *ifap = NULL; int l_socket = netlink_socket(); if(l_socket < 0) { return -1; } NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK); if(!l_linkResults) { close(l_socket); return -1; } NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR); if(!l_addrResults) { close(l_socket); freeResultList(l_linkResults); return -1; } unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults); struct ifaddrs *l_links[l_numLinks]; memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *)); if (interpret(l_socket, l_linkResults, l_links, ifap) == -1) { return -1; } if (interpret(l_socket, l_addrResults, l_links, ifap) == -1) { return -1; } freeResultList(l_linkResults); freeResultList(l_addrResults); close(l_socket); return 0; }