From: David L. Cantrell Jr <dcantrell@xxxxxxxxxx> Reduce nl.c to enough to communicate with libnl. We already have libnl, so we might as well use it. Plus, the latest version has a reasonable API, so I'm totally against using it. The _isys module and loader have been updated to call the new functions: nl_mac2str() and nl_ip2str() to get the MAC address or IP address for the specified interface. This patch also drops our need for glib for isys. Yeah, I added the dep and I'm removing it. --- isys/Makefile | 13 +- isys/isys.c | 6 +- isys/nl.c | 699 +++++++++++--------------------------------------- isys/nl.h | 31 +-- loader2/net.c | 2 +- loader2/nfsinstall.c | 5 +- loader2/urlinstall.c | 5 +- 7 files changed, 166 insertions(+), 595 deletions(-) diff --git a/isys/Makefile b/isys/Makefile index d5d0f09..7f2d304 100644 --- a/isys/Makefile +++ b/isys/Makefile @@ -35,9 +35,9 @@ endif PYMODULES = _isys.so SUBDIRS = -# glib -LOADLIBES += $(shell pkg-config --libs glib-2.0) -CFLAGS += $(shell pkg-config --cflags glib-2.0) +# libnl +LOADLIBES += $(shell pkg-config --libs libnl-1) +CFLAGS += $(shell pkg-config --cflags libnl-1) # libdhcp LOADLIBES += $(shell pkg-config --libs libdhcp) @@ -101,14 +101,9 @@ nfsmount.do: nfs_mountversion.h nfs_mountversion.h: /usr/include/linux/nfs_mount.h grep NFS_MOUNT_VERSION $< | sed -e 's/NFS/KERNEL_NFS/' > $@ -nltest: str.o nl.c nl.h - $(CC) -c $(CFLAGS) -DTESTING nl.c -o nl.o - $(CC) -DTESTING nl.o -o nl $(LOADLIBES) str.o - depend: nfs_mountversion.h $(CPP) -M $(CFLAGS) $(SOURCES) > .depend ifeq (.depend,$(wildcard .depend)) include .depend -endif - +endif diff --git a/isys/isys.c b/isys/isys.c index 1a37359..9395f0f 100644 --- a/isys/isys.c +++ b/isys/isys.c @@ -1041,7 +1041,7 @@ static PyObject * doGetMacAddress(PyObject * s, PyObject * args) { if (!PyArg_ParseTuple(args, "s", &dev)) return NULL; - ret = netlink_interfaces_mac2str(dev); + ret = nl_mac2str(dev); return Py_BuildValue("s", ret); } @@ -1063,9 +1063,9 @@ static PyObject * doGetIPAddress(PyObject * s, PyObject * args) { char *ret = NULL; if (!PyArg_ParseTuple(args, "s", &dev)) - return NULL; + return NULL; - ret = netlink_interfaces_ip2str(dev); + ret = nl_ip2str(dev); return Py_BuildValue("s", ret); } diff --git a/isys/nl.c b/isys/nl.c index 84d7006..87178e5 100644 --- a/isys/nl.c +++ b/isys/nl.c @@ -21,612 +21,211 @@ #include <stdio.h> #include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include <sys/socket.h> -#include <sys/types.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <linux/if.h> -#include <arpa/inet.h> -#include <net/if_arp.h> - -#include <glib.h> +#include <netinet/in.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <netlink/route/addr.h> +#include <netlink/route/link.h> #include "nl.h" #include "str.h" -/* A linked list of interface_info_t structures (see nl.h) */ -static GSList *interfaces = NULL; - -/** - * Not really Netlink-specific, but handy nonetheless. Takes a MAC address - * and converts it to the familiar hexidecimal notation for easy reading. - * - * @param mac The unsigned char MAC address value. - * @param buf The string to write the formatted address to. - * @return Pointer to buf. - */ -char *netlink_format_mac_addr(char *buf, unsigned char *mac) { - if (buf == NULL) { - if ((buf = malloc(20)) == NULL) { - perror("malloc in netlink_format_mac_addr"); - return NULL; - } - } - - sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - return str2upper(buf); -} - -/** - * Convert cylon-readable IP address to human-readable format (either v4 - * or v6). - * - * @param family The address family. - * @param intf The interface_info_t structure with the IP address info. - * @param buf The buffer to write the formatted IP address to. - * @return A pointer to buf. - */ -char *netlink_format_ip_addr(int family, interface_info_t *intf, char *buf) { - int iplen; - - if (family == AF_INET6) - iplen = INET6_ADDRSTRLEN; - else - iplen = INET_ADDRSTRLEN; - - if (buf == NULL) { - if ((buf = malloc(iplen)) == NULL) { - perror("malloc in netlink_format_ip_addr"); - return NULL; - } - - memset(buf, 0, iplen); - } - - switch (family) { - case AF_INET: - inet_ntop(family, &(intf->ip_addr), buf, iplen); - break; - case AF_INET6: - inet_ntop(family, &(intf->ip6_addr), buf, iplen); - break; - } - - return buf; -} - -/** - * Create a new PF_NETLINK socket for communication with the kernel Netlink - * layer. Open with NETLINK_ROUTE protocol since we want IPv4 and IPv6 - * interface, address, and routing information. - * - * @return Handle to new socket or -1 on error. - */ -int netlink_create_socket(void) { - int sock; - - sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (sock < 0) { - perror("netlink socket"); - return -1; - } - - return sock; -} - -/** - * Send a dump request message for the specified information in the - * specified family type. Family may be AF_INET or AF_INET6, for - * example. The request type should be a GET type as specified in - * /usr/include/linux/rtnetlink.h (for example, RTM_GETLINK). - * - * @param sock The Netlink socket to use. - * @param type The Netlink request type. - * @param family The address family. - * @return The number of characters sent or -1 on error. - */ -int netlink_send_dump_request(int sock, int type, int family) { - int ret; - char buf[BUFSZ]; - struct sockaddr_nl snl; - struct nlmsghdr *nlh; - struct rtgenmsg *g; - - memset(&snl, 0, sizeof(snl)); - snl.nl_family = AF_NETLINK; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - g = (struct rtgenmsg *)(buf + sizeof(struct nlmsghdr)); - - nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); - nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; - nlh->nlmsg_type = type; - g->rtgen_family = family; - - ret = sendto(sock, buf, nlh->nlmsg_len, 0, (struct sockaddr *)&snl, - sizeof(snl)); - if (ret < 0) { - perror("netlink_send_dump_request sendto"); - return -1; - } - - return ret; -} - -/** - * Look for an IP address for the given interface. - * - * @param index The interface index number. - * @param family The address family (AF_INET or AF_INET6). - * @param addr Pointer to where we should write the IP address. - * @return -1 on error, 0 on success. +/* + * Return an NETLINK_ROUTE cache. */ -int netlink_get_interface_ip(int index, int family, void *addr) { - int sock, ret, len, alen; - ssize_t bufsz, readsz; - char *buf = NULL; - struct nlmsghdr *nlh; - struct ifaddrmsg *ifa; - struct rtattr *rta; - struct rtattr *tb[IFLA_MAX+1]; - - /* get a socket */ - if ((sock = netlink_create_socket()) == -1) { - perror("netlink_create_socket in netlink_get_interface_ip"); - close(sock); - return -1; - } - - /* send dump request */ - ret = netlink_send_dump_request(sock, RTM_GETADDR, family); - if (ret <= 0) { - if (ret < 0) - perror("netlink_send_dump_request in netlink_get_interface_ip"); - close(sock); - return ret < 0 ? -1 : 0; - } +struct nl_cache *nl_get_link_cache(struct nl_handle **handle) { + struct nl_cache *cache = NULL; - /* MSG_TRUNC doesn't actually seem to /work/ with netlink on RHEL 5, - * so we do this lame growth game until we have a buffer big enough. - * When we're done (which is the first time if MSG_TRUNC does its job), - * bufsz is the size of the message. Then we allocate a real buffer and - * do recvfrom again without MSG_PEEK. */ - len = 32; - do { - len <<= 1; - char tmpbuf[len]; - bufsz = recvfrom(sock, tmpbuf, len, MSG_PEEK|MSG_TRUNC|MSG_WAITALL, - NULL, 0); - if (bufsz < 0 && errno == EAGAIN) - bufsz = len; - } while (bufsz == len); - - if (bufsz <= 0) { - if (bufsz < 0) - perror("1st recvfrom in netlink_get_interface_ip"); - close(sock); - return -1; - } - - if ((buf = alloca(bufsz)) == NULL) { - perror("alloca on msg buf in netlink_get_interface_ip"); - close(sock); - return -1; + if ((*handle = nl_handle_alloc()) == NULL) { + perror("nl_handle_alloc() failure in nl_get_link_cache()"); + return NULL; } - memset(buf, '\0', bufsz); - while ((readsz = recvfrom(sock, buf, bufsz, MSG_WAITALL, NULL, 0)) <= 0) { - if (readsz < 0) { - if (errno == EAGAIN) - continue; - perror("2nd recvfrom in netlink_get_interface_ip"); - } - close(sock); - return -1; + if (nl_connect(*handle, NETLINK_ROUTE)) { + perror("nl_connect() failure in nl_get_link_cache()"); + nl_handle_destroy(*handle); + return NULL; } - nlh = (struct nlmsghdr *) buf; - while (NLMSG_OK(nlh, readsz)) { - switch (nlh->nlmsg_type) { - case NLMSG_DONE: - break; - case RTM_NEWADDR: - break; - default: - nlh = NLMSG_NEXT(nlh, readsz); - continue; - } - - /* RTM_NEWADDR */ - ifa = NLMSG_DATA(nlh); - rta = IFA_RTA(ifa); - len = IFA_PAYLOAD(nlh); - - if (ifa->ifa_family != family) { - nlh = NLMSG_NEXT(nlh, readsz); - continue; - } - - while (RTA_OK(rta, len)) { - if (rta->rta_type <= len) - tb[rta->rta_type] = rta; - rta = RTA_NEXT(rta, len); - } - - alen = RTA_PAYLOAD(tb[IFA_ADDRESS]); - - /* write the address */ - if (tb[IFA_ADDRESS] && ifa->ifa_index == index) { - switch (family) { - case AF_INET: - memset(addr, 0, sizeof(struct in_addr)); - memcpy(addr, (struct in_addr *)RTA_DATA(tb[IFA_ADDRESS]), alen); - break; - case AF_INET6: - memset(addr, 0, sizeof(struct in6_addr)); - memcpy(addr, (struct in6_addr *)RTA_DATA(tb[IFA_ADDRESS]), alen); - break; - } - - close(sock); - return 0; - } - - /* next netlink msg */ - nlh = NLMSG_NEXT(nlh, readsz); + if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { + perror("rtnl_link_alloc_cache() failure in nl_get_link_cache()"); + nl_close(*handle); + nl_handle_destroy(*handle); + return NULL; } - close(sock); - return 0; + return cache; } -/** - * Initialize the interfaces linked list with the interface name, MAC - * address, and IP addresses. This function is only called once to - * initialize the structure, but may be called again if the structure - * should be reinitialized. - * - * @return 0 on succes, -1 on error. +/* + * Given an interface name (e.g., eth0), return the IP address in human + * readable format (i.e., the output from inet_ntop()). Return NULL for + * no match. NOTE: This function will check for IPv6 and IPv4 + * addresses. In the case where the interface has both, the IPv4 address + * is returned. The only way you will get an IPv6 address from this function + * is if that's the only address configured for the interface. */ -int netlink_init_interfaces_list(void) { - int sock, len, alen, r, namelen; - ssize_t bufsz, readsz; - char *buf = NULL; - struct nlmsghdr *nlh; - struct ifinfomsg *ifi; - struct rtattr *rta; - struct rtattr *tb[IFLA_MAX+1]; - interface_info_t *intfinfo; - - /* if interfaces has stuff, free it now and read again */ - if (interfaces != NULL) - netlink_interfaces_list_free(); - - /* get a socket */ - if ((sock = netlink_create_socket()) == -1) { - perror("netlink_create_socket in netlink_init_interfaces_list"); - close(sock); - return -1; +char *nl_ip2str(char *ifname) { + int ifindex = -1, buflen = 0, family = 0; + char *buf = NULL, *bufv4 = NULL, *bufv6 = NULL, *pos = NULL; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct nl_object *obj = NULL; + struct rtnl_addr *raddr = NULL; + struct nl_addr *addr = NULL; + + if (ifname == NULL) { + perror("Missing ifname in nl_ip2str()"); + return NULL; } - /* send dump request */ - r = netlink_send_dump_request(sock, RTM_GETLINK, AF_NETLINK); - if (r <= 0) { - if (r < 0) - perror("netlink_send_dump_request in netlink_init_interfaces_list"); - close(sock); - return r < 0 ? -1 : r; + if ((cache = nl_get_link_cache(&handle)) == NULL) { + perror("nl_get_link_cache() failure in nl_ip2str()"); + return NULL; } - /* MSG_TRUNC doesn't actually seem to /work/ with netlink on RHEL 5, - * so we do this lame growth game until we have a buffer big enough. - * When we're done (which is the first time if MSG_TRUNC does its job), - * bufsz is the size of the message. Then we allocate a real buffer and - * do recvfrom again without MSG_PEEK. */ - len = 32; - do { - len <<= 1; - char tmpbuf[len]; - bufsz = recvfrom(sock, tmpbuf, len, MSG_PEEK|MSG_TRUNC|MSG_WAITALL, - NULL, 0); - if (bufsz < 0 && errno == EAGAIN) - bufsz = len; - } while (bufsz == len); - - if (bufsz <= 0) { - if (bufsz < 0) - perror("1st recvfrom in netlink_get_interface_list"); - close(sock); - return -1; - } + ifindex = rtnl_link_name2i(cache, ifname); - if ((buf = alloca(bufsz)) == NULL) { - perror("alloca on msg buf in netlink_get_interface_list"); - close(sock); - return -1; + if ((cache = rtnl_addr_alloc_cache(handle)) == NULL) { + perror("rtnl_addr_alloc_cache() failure in nl_ip2str()"); + goto ip2str_error; } - memset(buf, '\0', bufsz); - while ((readsz = recvfrom(sock, buf, bufsz, MSG_WAITALL, NULL, 0)) <= 0) { - if (readsz < 0) { - if (errno == EAGAIN) - continue; - perror("2nd recvfrom in netlink_get_interface_list"); - } - close(sock); - return -1; - } + /* find the IPv4 and IPv6 addresses for this interface */ + obj = nl_cache_get_first(cache); + while (obj) { + raddr = (struct rtnl_addr *) obj; - nlh = (struct nlmsghdr *) buf; - while (NLMSG_OK(nlh, readsz)) { - switch (nlh->nlmsg_type) { - case NLMSG_DONE: - break; - case RTM_NEWLINK: - break; - default: - nlh = NLMSG_NEXT(nlh, readsz); - continue; - } - - /* RTM_NEWLINK */ - memset(tb, 0, sizeof(tb)); - memset(tb, 0, sizeof(struct rtattr *) * (IFLA_MAX + 1)); + if (rtnl_addr_get_ifindex(raddr) == ifindex) { + family = rtnl_addr_get_family(raddr); - ifi = NLMSG_DATA(nlh); - rta = IFLA_RTA(ifi); - len = IFLA_PAYLOAD(nlh); + if (family == AF_INET || family == AF_INET6) { + /* skip if we have already saved an address */ + /* FIXME: we should handle multiple addresses for the same + * family per interface + */ + if (family == AF_INET && bufv4 != NULL) { + continue; + } - /* we only do things with ethernet mac addrs, so ... */ - if (ifi->ifi_type != ARPHRD_ETHER) { - nlh = NLMSG_NEXT(nlh, readsz); - continue; - } + if (family == AF_INET6 && bufv6 != NULL) { + continue; + } - namelen = 0; + /* get the address */ + addr = rtnl_addr_get_local(raddr); - while (RTA_OK(rta, len)) { - if (rta->rta_type <= len) { - if (rta->rta_type == IFLA_IFNAME) { - namelen = rta->rta_len; + /* convert to human readable format */ + if (family == AF_INET) { + buflen = INET_ADDRSTRLEN; + } else if (family == AF_INET6) { + buflen = INET6_ADDRSTRLEN; } - tb[rta->rta_type] = rta; - } - - rta = RTA_NEXT(rta, len); - } + buflen += 1; - if (tb[IFLA_ADDRESS] != NULL) - alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]); - else - alen = 0; - - /* we have an ethernet MAC addr if alen=6 */ - if (alen == 6) { - /* make some room! */ - intfinfo = malloc(sizeof(struct _interface_info_t)); - if (intfinfo == NULL) { - perror("malloc in netlink_init_interfaces_list"); - close(sock); - return -1; - } + if ((buf = malloc(buflen)) == NULL) { + perror("malloc() failure on buf in nl_ip2str()"); + nl_addr_destroy(addr); + goto ip2str_error; + } - /* copy the interface index */ - intfinfo->i = ifi->ifi_index; + buf = nl_addr2str(addr, buf, buflen); + nl_addr_destroy(addr); + + /* trim the prefix notation */ + if ((pos = index(buf, '/')) != NULL) { + *pos = '\0'; + if ((buf = realloc(buf, strlen(buf) + 1)) == NULL) { + perror("realloc() failure on buf in nl_ip2str()"); + nl_addr_destroy(addr); + goto ip2str_error; + } + } - /* copy the interface name (eth0, eth1, ...) */ - if (namelen > 0) { - intfinfo->name = strndup((char *) RTA_DATA(tb[IFLA_IFNAME]), - namelen); - } else { - intfinfo->name = NULL; - } + /* save the IP address in the right buffer */ + if (family == AF_INET) { + bufv4 = strdup(buf); + } else if (family == AF_INET6) { + bufv6 = strdup(buf); + } - /* copy the MAC addr */ - memcpy(&intfinfo->mac, RTA_DATA(tb[IFLA_ADDRESS]), alen); - - if (ifi->ifi_flags & IFF_RUNNING) { - /* get the IPv4 address of this interface (if any) */ - r = netlink_get_interface_ip(intfinfo->i, AF_INET, &intfinfo->ip_addr); - if (r < 0) - memset(&intfinfo->ip_addr, 0, sizeof(struct in_addr)); - - /* get the IPv6 address of this interface (if any) */ - r = netlink_get_interface_ip(intfinfo->i, AF_INET6, &intfinfo->ip6_addr); - if (r < 0) - memset(&intfinfo->ip6_addr, 0, sizeof(struct in6_addr)); - } else { - memset(&intfinfo->ip_addr, 0, sizeof(struct in_addr)); - memset(&intfinfo->ip6_addr, 0, sizeof(struct in6_addr)); + /* empty the main conversion buffer */ + if (buf) { + free(buf); + buf = NULL; + } } - - /* add this interface */ - interfaces = g_slist_append(interfaces, intfinfo); } - /* next netlink msg */ - nlh = NLMSG_NEXT(nlh, readsz); + obj = nl_cache_get_next(obj); } - close(sock); - return 0; -} - -/** - * Take the cylon-readable IP address for the specified device and format - * it for human reading. NOTE: This function will check for IPv6 and IPv4 - * addresses. In the case where the interface has both, the IPv4 address - * is returned. The only way you will get an IPv6 address from this function - * is if that's the only address configured for the interface. - * - * @param ifname The interface name (e.g., eth0). - * @return The human-readable IP address (either IPv4 or IPv6) or NULL on - * error/no match. - */ -char *netlink_interfaces_ip2str(char *ifname) { - char *ret = NULL; - GSList *e; - interface_info_t *intf; +ip2str_error: + nl_close(handle); + nl_handle_destroy(handle); - if (ifname == NULL) - return NULL; - - /* init the interfaces list if it's empty or if nothing is found */ - e = g_slist_find_custom(interfaces,ifname,&_netlink_interfaces_elem_find); - if (interfaces == NULL || e == NULL) { - int r = netlink_init_interfaces_list(); - - if (r < 0) { - perror("netlink_init_interfaces_list in netlink_interface_ip2str"); - return NULL; - } - } - - /* search */ - e = g_slist_find_custom(interfaces,ifname,&_netlink_interfaces_elem_find); - if (e == NULL) { - return NULL; + /* return IPv4 address if we have both families + * return IPv6 address if we only have IPv6 family + * return NULL otherwise + */ + if ((bufv4 && bufv6) || (bufv4 && !bufv6)) { + return bufv4; + } else if (!bufv4 && bufv6) { + return bufv6; } else { - intf = (interface_info_t *) e->data; - - if (intf->ip_addr.s_addr == 0 && intf->ip6_addr.s6_addr[0] == 0) - /* neither IP set, return null */ - ret = NULL; - else if (intf->ip_addr.s_addr == 0 && intf->ip6_addr.s6_addr[0] != 0) - /* only IPv6 addr, return that */ - ret = netlink_format_ip_addr(AF_INET6, intf, ret); - else if (intf->ip_addr.s_addr != 0) - /* if IPv4 is set, return that (regardless of IPv6 value) */ - ret = netlink_format_ip_addr(AF_INET, intf, ret); - else - /* we have no idea what happened, return NULL */ - ret = NULL; - - return ret; + return NULL; } } /** - * Take the cylon-readable MAC address for the specified device and - * format it for human reading. - * - * @param ifname The interface name (e.g., eth0). - * @return The human-readable MAC address (e.g., 01:0A:3E:4B:91:12) or NULL - * on error. + * Given an interface name (e.g., eth0), return the MAC address in human + * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. */ -char *netlink_interfaces_mac2str(char *ifname) { - char *ret = NULL; - GSList *e; - interface_info_t *intf; - int r; +char *nl_mac2str(char *ifname) { + int buflen = 20; + char *buf = NULL; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct nl_addr *addr = NULL; - if (ifname == NULL) + if (ifname == NULL) { + perror("Missing ifname in nl_mac2str()"); return NULL; - - /* init the interfaces list if it's empty */ - if (interfaces == NULL) { - r = netlink_init_interfaces_list(); - - if (r < 0) { - perror("netlink_init_interfaces_list in netlink_interface_mac2str"); - return NULL; - } } - e = g_slist_find_custom(interfaces,ifname,&_netlink_interfaces_elem_find); - if (e == NULL) { + if ((cache = nl_get_link_cache(&handle)) == NULL) { + perror("nl_get_link_cache() failure in nl_mac2str()"); return NULL; - } else { - intf = (interface_info_t *) e->data; - ret = netlink_format_mac_addr(ret, intf->mac); - return ret; } -} - -/** - * Free memory for each element of the specified linked list. Frees the - * list after all elements have been freed (say 'free' some more). - */ -void netlink_interfaces_list_free(void) { - g_slist_foreach(interfaces, &_netlink_interfaces_elem_free, NULL); - g_slist_free(interfaces); - interfaces = NULL; -} -/** - * Callback function for netlink_interfaces_list_free. Frees an individual - * list element. - * - * @see netlink_interfaces_list_free - */ -void _netlink_interfaces_elem_free(gpointer data, gpointer user_data) { - free(data); - return; -} + if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { + perror("rtnl_link_get_by_name() failure in nl_mac2str()"); + goto mac2str_error2; + } -/** - * Compares one list element to the specified interface name. Callback - * function used to locate a list element by interface name. - * - * @see netlink_interfaces_mac2str - * @see netlink_interfaces_ip2str - */ -gint _netlink_interfaces_elem_find(gconstpointer a, gconstpointer b) { - char *ifname = (char *) b; - GSList *elemdata = (GSList *) a; - interface_info_t *intf; - - intf = (interface_info_t *) elemdata; - if (intf->name == NULL) - return -1; - else - return strncmp(ifname, intf->name, strlen(ifname)); -} + if ((addr = rtnl_link_get_addr(link)) == NULL) { + perror("rtnl_link_get_addr() failure in nl_mac2str()"); + goto mac2str_error3; + } -#ifdef TESTING -void print_interfaces(gpointer data, gpointer user_data) { - char *buf = NULL; - char *ipbuf = NULL; - interface_info_t *intf; - - intf = (interface_info_t *) data; - printf("Interface %d\n", intf->i); - printf(" Name: %s\n", intf->name); - if (intf->ip_addr.s_addr != 0) - printf(" IPv4: %s\n", netlink_format_ip_addr(AF_INET, intf, ipbuf)); - else - printf(" IPv4: not set\n"); - if (intf->ip6_addr.s6_addr[0] != 0) - printf(" IPv6: %s\n", netlink_format_ip_addr(AF_INET6, intf, ipbuf)); - else - printf(" IPv6: not set\n"); - printf(" MAC: %s\n\n", netlink_format_mac_addr(buf, intf->mac)); - - printf(" mac2str test for %s: |%s|\n", intf->name, netlink_interfaces_mac2str(intf->name)); - printf(" ip2str test for %s: |%s|\n", intf->name, netlink_interfaces_ip2str(intf->name)); - - printf("----------------------------------------------------------------\n"); - - return; -} + if ((buf = malloc(buflen)) == NULL) { + perror("malloc() failure on buf in nl_mac2str()"); + goto mac2str_error4; + } -int main(void) { - if (netlink_init_interfaces_list() == -1) { - fprintf(stderr, "netlink_init_interfaces_list failure: %s\n", __func__); - fflush(stderr); - return EXIT_FAILURE; + if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) { + buf = str2upper(buf); } - g_slist_foreach(interfaces, print_interfaces, NULL); +mac2str_error4: + nl_addr_destroy(addr); +mac2str_error3: + rtnl_link_put(link); +mac2str_error2: + nl_close(handle); + nl_handle_destroy(handle); - return EXIT_SUCCESS; + return buf; } -#endif diff --git a/isys/nl.h b/isys/nl.h index d182aa6..0a3b4f6 100644 --- a/isys/nl.h +++ b/isys/nl.h @@ -19,31 +19,10 @@ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> */ -#include <netinet/in.h> -#include <glib.h> - -#define BUFSZ 4096 - -/* Information per interface */ -typedef struct _interface_info_t { - int i; /* interface index */ - char *name; /* name (eth0, eth1, ...) */ - struct in_addr ip_addr; /* IPv4 address (0=none) */ - struct in6_addr ip6_addr; /* IPv6 address (0=none) */ - unsigned char mac[8]; /* MAC address */ -} interface_info_t; +#include <netlink/cache.h> +#include <netlink/socket.h> /* Function prototypes */ -char *netlink_format_mac_addr(char *buf, unsigned char *mac); -char *netlink_format_ip_addr(int family, interface_info_t *intf, char *buf); -int netlink_create_socket(void); -int netlink_send_dump_request(int sock, int type, int family); -int netlink_get_interface_ip(int index, int family, void *addr); -int netlink_init_interfaces_list(void); -void netlink_interfaces_list_free(void); -char *netlink_interfaces_mac2str(char *ifname); -char *netlink_interfaces_ip2str(char *ifname); - -/* Private function prototypes -- used by the functions above */ -void _netlink_interfaces_elem_free(gpointer data, gpointer user_data); -gint _netlink_interfaces_elem_find(gconstpointer a, gconstpointer b); +struct nl_cache *nl_get_link_cache(struct nl_handle **handle); +char *nl_mac2str(char *ifname); +char *nl_ip2str(char *ifname); diff --git a/loader2/net.c b/loader2/net.c index ba500d9..31d3351 100644 --- a/loader2/net.c +++ b/loader2/net.c @@ -1795,7 +1795,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { } else if (ksMacAddr != NULL) { /* maybe it's a mac address */ char *devmacaddr = NULL; - devmacaddr = netlink_interfaces_mac2str(devs[i]->device); + devmacaddr = nl_mac2str(devs[i]->device); if ((devmacaddr != NULL) && !strcmp(ksMacAddr, devmacaddr)) { foundDev = 1; free(loaderData->netDev); diff --git a/loader2/nfsinstall.c b/loader2/nfsinstall.c index 18fb67e..d150370 100644 --- a/loader2/nfsinstall.c +++ b/loader2/nfsinstall.c @@ -360,9 +360,8 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { } /* get the IP of the target system */ - netlink_init_interfaces_list(); - if ((ip = netlink_interfaces_ip2str(loaderData->netDev)) == NULL) { - logMessage(ERROR, "netlink_interfaces_ip2str returned NULL"); + if ((ip = nl_ip2str(loaderData->netDev)) == NULL) { + logMessage(ERROR, "nl_ip2str returned NULL"); return 1; } diff --git a/loader2/urlinstall.c b/loader2/urlinstall.c index 58cdc63..3fff562 100644 --- a/loader2/urlinstall.c +++ b/loader2/urlinstall.c @@ -310,8 +310,7 @@ int getFileFromUrl(char * url, char * dest, memset(&ui, 0, sizeof(ui)); ui.protocol = proto; - netlink_init_interfaces_list(); - if ((ip = netlink_interfaces_ip2str(loaderData->netDev)) == NULL) { + if ((ip = nl_ip2str(loaderData->netDev)) == NULL) { logMessage(ERROR, "getFileFromUrl: no client IP information"); return 1; } @@ -359,7 +358,7 @@ int getFileFromUrl(char * url, char * dest, devices = getDevices(DEVICE_NETWORK); for (i = 0; devices && devices[i]; i++) { dev = devices[i]->device; - mac = netlink_interfaces_mac2str(dev); + mac = nl_mac2str(dev); if (mac) { q = asprintf(&tmpstr, "X-RHN-Provisioning-MAC-%d: %s %s\r\n", -- 1.5.3.8 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list