From 0f0daf7852a0dc71a1a270e7936d2819789e7155 Mon Sep 17 00:00:00 2001 From: Jirka Klimes Date: Thu, 25 Feb 2010 16:52:10 -0800 Subject: [PATCH] core: determine classful IPv4 prefix if no DHCP netmask is provided (bgo #603098) --- libnm-util/Makefile.am | 2 +- libnm-util/libnm-util.ver | 1 + libnm-util/nm-utils.c | 25 ++++++++++++++++++++++- libnm-util/nm-utils.h | 3 ++- src/dhcp-manager/nm-dhcp-dhclient.c | 15 ++++++++------ system-settings/plugins/ifcfg-rh/reader.c | 11 ++-------- 6 files changed, 39 insertions(+), 18 deletions(-) diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 2aa4c4ed6e..55db3313c0 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \ - -version-info "2:0:1" + -version-info "3:0:2" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 17ce1749ff..3307b92ac1 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -345,6 +345,7 @@ global: nm_utils_ip4_addresses_to_gvalue; nm_utils_ip4_netmask_to_prefix; nm_utils_ip4_prefix_to_netmask; + nm_utils_ip4_get_default_prefix; nm_utils_ip4_routes_from_gvalue; nm_utils_ip4_routes_to_gvalue; nm_utils_ip6_addresses_from_gvalue; diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 8ec872d807..31aae7c02b 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -21,7 +21,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2009 Red Hat, Inc. + * (C) Copyright 2005 - 2010 Red Hat, Inc. */ #include @@ -1209,6 +1209,29 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix) } +/** + * nm_utils_ip4_get_default_prefix: + * @ip: an IPv4 address (in network byte order) + * + * When the Internet was originally set up, various ranges of IP addresses were + * segmented into three network classes: A, B, and C. This function will return + * a prefix that is associated with the IP address specified defining where it + * falls in the predefined classes. + * + * Returns: the default class prefix for the given IP + **/ +/* The function is originally from ipcalc.c of Red Hat's initscripts. */ +guint32 +nm_utils_ip4_get_default_prefix (guint32 ip) +{ + if (((ntohl (ip) & 0xFF000000) >> 24) <= 127) + return 8; /* Class A - 255.0.0.0 */ + else if (((ntohl (ip) & 0xFF000000) >> 24) <= 191) + return 16; /* Class B - 255.255.0.0 */ + + return 24; /* Class C - 255.255.255.0 */ +} + GSList * nm_utils_ip6_addresses_from_gvalue (const GValue *value) { diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index bbb304f4db..8308a233ac 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -20,7 +20,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2008 Red Hat, Inc. + * (C) Copyright 2005 - 2010 Red Hat, Inc. */ #ifndef NM_UTILS_H @@ -192,6 +192,7 @@ void nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value); guint32 nm_utils_ip4_netmask_to_prefix (guint32 netmask); guint32 nm_utils_ip4_prefix_to_netmask (guint32 prefix); +guint32 nm_utils_ip4_get_default_prefix (guint32 ip); GSList *nm_utils_ip6_addresses_from_gvalue (const GValue *value); void nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value); diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index 1c5625798a..ac8f29a109 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -237,13 +237,16 @@ nm_dhcp_dhclient_get_lease_config (const char *iface, const char *uuid) /* Netmask */ data = g_hash_table_lookup (hash, "option subnet-mask"); - if (!data) - data = "255.255.255.0"; /* FIXME: assume class C? */ - if (!inet_pton (AF_INET, data, &tmp)) { - g_warning ("%s: couldn't parse IP4 subnet mask '%s'", __func__, data); - goto error; + if (data) { + if (!inet_pton (AF_INET, data, &tmp)) { + g_warning ("%s: couldn't parse IP4 subnet mask '%s'", __func__, data); + goto error; + } + prefix = nm_utils_ip4_netmask_to_prefix (tmp.s_addr); + } else { + /* Get default netmask for the IP according to appropriate class. */ + prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); } - prefix = nm_utils_ip4_netmask_to_prefix (tmp.s_addr); nm_ip4_address_set_prefix (addr, prefix); /* Gateway */ diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 1b8ae93925..a445d5b177 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -606,16 +606,9 @@ read_full_ip4_address (shvarFile *ifcfg, /* Try to autodetermine the prefix for the address' class */ if (!nm_ip4_address_get_prefix (addr)) { - guint32 tmp_addr, prefix = 0; - - tmp_addr = nm_ip4_address_get_address (addr); - if (((ntohl(tmp_addr) & 0xFF000000) >> 24) <= 127) - prefix = 8; - else if (((ntohl(tmp_addr) & 0xFF000000) >> 24) <= 191) - prefix = 16; - else - prefix = 24; + guint32 prefix = 0; + prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); nm_ip4_address_set_prefix (addr, prefix); value = svGetValue (ifcfg, ip_tag, FALSE);