diff options
author | David Cantrell <dcantrell@redhat.com> | 2008-08-28 13:37:15 -1000 |
---|---|---|
committer | David Cantrell <dcantrell@redhat.com> | 2008-08-28 13:39:47 -1000 |
commit | debfe5428f1ed5f4464511027cc5077efaca7d5a (patch) | |
tree | b6286319fc7753543655bb375e0696094c3f85d2 /isys | |
parent | bcfcd77cf99faacf419448f5b16ca97a70765c51 (diff) | |
download | anaconda-debfe5428f1ed5f4464511027cc5077efaca7d5a.tar.gz anaconda-debfe5428f1ed5f4464511027cc5077efaca7d5a.tar.xz anaconda-debfe5428f1ed5f4464511027cc5077efaca7d5a.zip |
Rewrite iface_ip2str() to talk to NetworkManager over D-Bus
I'm rewriting all of this file eventually, but for today you
get the rewrite of iface_ip2str().
Diffstat (limited to 'isys')
-rw-r--r-- | isys/Makefile | 8 | ||||
-rw-r--r-- | isys/iface.c | 214 | ||||
-rw-r--r-- | isys/iface.h | 11 |
3 files changed, 127 insertions, 106 deletions
diff --git a/isys/Makefile b/isys/Makefile index 00ba5b90a..595f4b8ac 100644 --- a/isys/Makefile +++ b/isys/Makefile @@ -34,6 +34,14 @@ endif PYMODULES = _isys.so SUBDIRS = +# D-Bus +LOADLIBES += $(shell pkg-config --libs dbus-1) +CFLAGS += $(shell pkg-config --cflags dbus-1) + +# NetworkManager +LOADLIBES += $(shell pkg-config --libs NetworkManager) +CFLAGS += $(shell pkg-config --cflags NetworkManager) + # libnl LOADLIBES += $(shell pkg-config --libs libnl-1) CFLAGS += $(shell pkg-config --cflags libnl-1) diff --git a/isys/iface.c b/isys/iface.c index 93cef022f..979938b09 100644 --- a/isys/iface.c +++ b/isys/iface.c @@ -35,6 +35,7 @@ #include <netdb.h> #include <signal.h> #include <netinet/in.h> + #include <netlink/netlink.h> #include <netlink/socket.h> #include <netlink/route/rtnl.h> @@ -42,13 +43,15 @@ #include <netlink/route/addr.h> #include <netlink/route/link.h> +#include <dbus/dbus.h> +#include <NetworkManager.h> + #include "iface.h" #include "str.h" /* Internal-only function prototypes. */ static struct nl_handle *_iface_get_handle(void); static struct nl_cache *_iface_get_link_cache(struct nl_handle **); -static int _iface_name_to_index(char *); static int _iface_have_valid_addr(void *addr, int family, int length); static int _iface_redirect_io(char *device, int fd, int mode); @@ -90,24 +93,6 @@ static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { } /* - * Convert an interface name to index number. - */ -static int _iface_name_to_index(char *ifname) { - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - - if (ifname == NULL) { - return -1; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return -1; - } - - return rtnl_link_name2i(cache, ifname); -} - -/* * Determine if a struct in_addr or struct in6_addr contains a valid address. */ static int _iface_have_valid_addr(void *addr, int family, int length) { @@ -163,114 +148,145 @@ int _iface_redirect_io(char *device, int fd, int mode) { } /* - * 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. + * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), + * return the IP address in human readable format (i.e., the output from + * inet_ntop()). Return NULL for no match or error. */ -char *iface_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; +char *iface_ip2str(char *ifname, int family) { + char *ipaddr = NULL; + char *nm_iface = NM_DBUS_INTERFACE; + char *property = NULL; + char *device_path = NULL; + char *interface = NULL; + struct in_addr addr; + DBusConnection *connection = NULL; + DBusError error; + DBusMessage *message = NULL, *reply = NULL, *devreply = NULL; + DBusMessageIter iter, a_iter, d_iter, v_iter; - if ((ifindex = _iface_name_to_index(ifname)) == -1) { - goto ip2str_error; + if (ifname == NULL) { + return NULL; } - if ((cache = rtnl_addr_alloc_cache(handle)) == NULL) { - goto ip2str_error; + /* DCFIXME: add IPv6 once NM gains support */ + if (family != AF_INET) { + return NULL; } - /* find the IPv4 and IPv6 addresses for this interface */ - if ((obj = nl_cache_get_first(cache)) == NULL) { - goto ip2str_error; + dbus_error_init(&error); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + dbus_error_free(&error); + return NULL; } - do { - raddr = (struct rtnl_addr *) obj; + message = dbus_message_new_method_call(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_SERVICE, + "GetDevices"); + if (!message) { + return NULL; + } - if (rtnl_addr_get_ifindex(raddr) == ifindex) { - family = rtnl_addr_get_family(raddr); + reply = dbus_connection_send_with_reply_and_block(connection, + message, + -1, &error); + dbus_message_unref(message); + if (!reply) { + return NULL; + } - 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; - } + dbus_message_iter_init(reply, &iter); + dbus_message_iter_recurse(&iter, &a_iter); - if (family == AF_INET6 && bufv6 != NULL) { - continue; - } + while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID) { + dbus_message_iter_get_basic(&a_iter, &device_path); - /* get the address */ - addr = rtnl_addr_get_local(raddr); + message = dbus_message_new_method_call(NM_DBUS_SERVICE, + device_path, + DBUS_INTERFACE_PROPERTIES, + "Get"); + if (!message) { + return NULL; + } + + property = "Interface"; + if (!dbus_message_append_args(message, + DBUS_TYPE_STRING, &nm_iface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + dbus_message_unref(message); + return NULL; + } + + devreply = dbus_connection_send_with_reply_and_block(connection, + message, + -1, &error); + dbus_message_unref(message); + if (!devreply) { + continue; + } + + dbus_message_iter_init(devreply, &d_iter); + while (dbus_message_iter_get_arg_type(&d_iter) != DBUS_TYPE_INVALID) { + dbus_message_iter_recurse(&d_iter, &v_iter); + dbus_message_iter_get_basic(&v_iter, &interface); + + if (!strcmp(ifname, interface)) { + message = dbus_message_new_method_call(NM_DBUS_SERVICE, + device_path, DBUS_INTERFACE_PROPERTIES, "Get"); + if (!message) { + return NULL; + } - /* convert to human readable format */ if (family == AF_INET) { - buflen = INET_ADDRSTRLEN; - } else if (family == AF_INET6) { - buflen = INET6_ADDRSTRLEN; + property = "Ip4Address"; } - buflen += 1; + if (!dbus_message_append_args(message, + DBUS_TYPE_STRING, &nm_iface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + dbus_message_unref(message); + return NULL; + } - if ((buf = calloc(sizeof(char *), buflen)) == NULL) { - nl_addr_destroy(addr); - goto ip2str_error; + devreply = dbus_connection_send_with_reply_and_block(connection, + message, -1, &error); + dbus_message_unref(message); + if (!devreply) { + return NULL; } - buf = nl_addr2str(addr, buf, buflen); - nl_addr_destroy(addr); + dbus_message_iter_init(devreply, &d_iter); + dbus_message_iter_recurse(&d_iter, &v_iter); + if (dbus_message_iter_get_arg_type(&v_iter)==DBUS_TYPE_UINT32) { + memset(&addr, 0, sizeof(addr)); + dbus_message_iter_get_basic(&v_iter, &addr.s_addr); - /* trim the prefix notation */ - if ((pos = index(buf, '/')) != NULL) { - *pos = '\0'; - if ((buf = realloc(buf, strlen(buf) + 1)) == NULL) { - nl_addr_destroy(addr); - goto ip2str_error; + if ((ipaddr = malloc(INET_ADDRSTRLEN+1)) == NULL) { + abort(); } - } - /* save the IP address in the right buffer */ - if (family == AF_INET) { - bufv4 = strdup(buf); - } else if (family == AF_INET6) { - bufv6 = strdup(buf); - } + if (inet_ntop(family, &addr, ipaddr, + INET_ADDRSTRLEN) == NULL) { + abort(); + } - /* empty the main conversion buffer */ - if (buf) { - free(buf); - buf = NULL; + dbus_connection_unref(connection); + return ipaddr; } } - } - } while ((obj = nl_cache_get_next(obj)) != NULL); -ip2str_error: - nl_close(handle); - nl_handle_destroy(handle); - /* 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 { - return NULL; + dbus_message_iter_next(&d_iter); + } + + dbus_message_iter_next(&a_iter); } + + dbus_connection_unref(connection); + return NULL; } /* diff --git a/isys/iface.h b/isys/iface.h index 03cffee4e..43b29130a 100644 --- a/isys/iface.h +++ b/isys/iface.h @@ -111,14 +111,11 @@ typedef struct _iface_t { /* Function prototypes */ /* - * 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. + * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), + * return the IP address in human readable format (i.e., the output from + * inet_ntop()). Return NULL for no match or error. */ -char *iface_ip2str(char *); +char *iface_ip2str(char *, int); /* * Given an interface name (e.g., eth0), return the MAC address in human |