diff --git a/ChangeLog b/ChangeLog index 43f94df275..bd6a257964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-07-07 Dan Williams + + Convert to using IPv4 prefixes instead of netmasks. + 2008-07-03 Dan Williams * libnm-util/nm-setting-ip4-config.c diff --git a/include/NetworkManagerVPN.h b/include/NetworkManagerVPN.h index a01b1489b7..8b4c89c6ae 100644 --- a/include/NetworkManagerVPN.h +++ b/include/NetworkManagerVPN.h @@ -108,7 +108,7 @@ typedef enum NMVPNConnectionStateReason #define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY "gateway" #define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address" #define NM_VPN_PLUGIN_IP4_CONFIG_PTP "ptp" -#define NM_VPN_PLUGIN_IP4_CONFIG_NETMASK "netmask" +#define NM_VPN_PLUGIN_IP4_CONFIG_PREFIX "prefix" #define NM_VPN_PLUGIN_IP4_CONFIG_DNS "dns" #define NM_VPN_PLUGIN_IP4_CONFIG_NBNS "nbns" #define NM_VPN_PLUGIN_IP4_CONFIG_MSS "mss" diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml index 8e3bf573c1..8ac92a9a1f 100644 --- a/introspection/nm-ip4-config.xml +++ b/introspection/nm-ip4-config.xml @@ -3,7 +3,7 @@ - Tuples of IPv4 address/netmask/gateway. The gateway is optional, if not given should be 0. + Tuples of IPv4 address/prefix/gateway. The gateway is optional, if not given should be 0. The hostname associated with this IPv4 address. FIXME: what about multiple hostnames? diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index 3d6719203e..80844f4950 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -79,8 +79,8 @@ dump_ip4_config (NMIP4Config *cfg) g_print ("IP4 address: %s\n", tmp); g_free (tmp); - tmp = ip4_address_as_string (addr->netmask); - g_print ("IP4 netmask: %s\n", tmp); + tmp = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (addr->prefix)); + g_print ("IP4 prefix: %d (%s)\n", addr->prefix, tmp); g_free (tmp); tmp = ip4_address_as_string (addr->gateway); diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index a04b70320d..b3f5e6a893 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -70,6 +70,8 @@ static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingIP4Config *self = NM_SETTING_IP4_CONFIG (setting); + GSList *iter; + int i; if (!self->method) { g_set_error (error, @@ -132,6 +134,22 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + /* Validate addresses */ + for (iter = self->addresses, i = 0; iter; iter = g_slist_next (iter), i++) { + NMSettingIP4Address *addr = (NMSettingIP4Address *) iter->data; + + if (!addr->address) { + g_warning ("invalid IP4 address #%d", i); + return FALSE; + } + + if (!addr->prefix || addr->prefix > 32) { + g_warning ("invalid IP4 address prefix %d for address #%d", + addr->prefix, i); + return FALSE; + } + } + return TRUE; } diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index ec73d869d3..340662d12b 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -45,16 +45,16 @@ GQuark nm_setting_ip4_config_error_quark (void); #define NM_SETTING_IP4_CONFIG_METHOD_SHARED "shared" typedef struct { - guint32 address; - guint32 netmask; - guint32 gateway; + guint32 address; /* network byte order */ + guint32 prefix; + guint32 gateway; /* network byte order */ } NMSettingIP4Address; typedef struct { NMSetting parent; char *method; - GArray *dns; /* array of guint32 */ + GArray *dns; /* array of guint32; elements in network byte order */ GSList *dns_search; /* list of strings */ GSList *addresses; /* array of NMSettingIP4Address */ GSList *routes; /* array of NMSettingIP4Address */ diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index e23ba361bc..013328d578 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -815,7 +815,7 @@ nm_utils_ip4_addresses_from_gvalue (const GValue *value) addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr->address = g_array_index (array, guint32, 0); - addr->netmask = g_array_index (array, guint32, 1); + addr->prefix = g_array_index (array, guint32, 1); addr->gateway = g_array_index (array, guint32, 2); list = g_slist_prepend (list, addr); } @@ -838,7 +838,7 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); g_array_append_val (array, addr->address); - g_array_append_val (array, addr->netmask); + g_array_append_val (array, addr->prefix); g_array_append_val (array, addr->gateway); g_ptr_array_add (addresses, array); } @@ -846,6 +846,60 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) g_value_take_boxed (value, addresses); } +/* + * nm_utils_ip4_netmask_to_prefix + * + * Figure out the network prefix from a netmask. Netmask + * MUST be in network byte order. + * + */ +guint32 +nm_utils_ip4_netmask_to_prefix (guint32 netmask) +{ + guchar *p, *end; + guint32 prefix = 0; + + p = (guchar *) &netmask; + end = p + sizeof (guint32); + + while ((*p == 0xFF) && p < end) { + prefix += 8; + p++; + } + + if (p < end) { + guchar v = *p; + + while (v) { + prefix++; + v <<= 1; + } + } + + return prefix; +} + +/* + * nm_utils_ip4_prefix_to_netmask + * + * Figure out the netmask from a prefix. + * + */ +guint32 +nm_utils_ip4_prefix_to_netmask (guint32 prefix) +{ + guint32 msk = 0x80000000; + guint32 netmask = 0; + + while (prefix > 0) { + netmask |= msk; + msk >>= 1; + prefix--; + } + + return (guint32) htonl (netmask); +} + 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 f9694b4ec1..e14b616c85 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -180,6 +180,9 @@ gboolean nm_utils_security_valid (NMUtilsSecurityType type, GSList *nm_utils_ip4_addresses_from_gvalue (const GValue *value); void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value); +guint32 nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask); +guint32 nm_utils_ip4_prefix_to_netmask (guint32 ip4_prefix); + 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/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index ea5c1b27da..3763b84988 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -62,17 +62,17 @@ #include static gboolean -route_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 netmask) +route_in_same_subnet (NMIP4Config *config, guint32 prefix) { int num; int i; num = nm_ip4_config_get_num_addresses (config); for (i = 0; i < num; i++) { - const NMSettingIP4Address *cfg_addr; + const NMSettingIP4Address *addr; - cfg_addr = nm_ip4_config_get_address (config, i); - if ((dest & netmask) == (cfg_addr->address & cfg_addr->netmask)) + addr = nm_ip4_config_get_address (config, i); + if (prefix == addr->prefix) return TRUE; } @@ -96,38 +96,11 @@ create_route (int iface_idx, int mss) return route; } -static int -netmask_to_prefix (guint32 netmask) -{ - guchar *p; - guchar *end; - int prefix = 0; - - p = (guchar *) &netmask; - end = p + sizeof (guint32); - - while ((*p == 0xFF) && p < end) { - prefix += 8; - p++; - } - - if (p < end) { - guchar v = *p; - - while (v) { - prefix++; - v <<= 1; - } - } - - return prefix; -} - static void nm_system_device_set_ip4_route (const char *iface, NMIP4Config *iface_config, guint32 ip4_dest, - guint32 ip4_netmask, + guint32 ip4_prefix, guint32 ip4_gateway, int mss) { @@ -137,7 +110,7 @@ nm_system_device_set_ip4_route (const char *iface, struct nl_addr *gw_addr = NULL; int err, iface_idx; - if (iface_config && route_in_same_subnet (iface_config, ip4_dest, ip4_netmask)) + if (iface_config && route_in_same_subnet (iface_config, ip4_prefix)) return; nlh = nm_netlink_get_default_handle (); @@ -152,7 +125,7 @@ nm_system_device_set_ip4_route (const char *iface, /* Destination */ dest_addr = nl_addr_build (AF_INET, &ip4_dest, sizeof (ip4_dest)); g_return_if_fail (dest_addr != NULL); - nl_addr_set_prefixlen (dest_addr, netmask_to_prefix (ip4_netmask)); + nl_addr_set_prefixlen (dest_addr, (int) ip4_prefix); rtnl_route_set_dst (route, dest_addr); nl_addr_put (dest_addr); @@ -312,7 +285,7 @@ nm_system_device_set_from_ip4_config (const char *iface, nm_system_device_set_ip4_route (iface, config, route->address, - route->netmask, + route->prefix, route->gateway, nm_ip4_config_get_mss (config)); } @@ -366,7 +339,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, } nm_system_device_set_ip4_route (nm_device_get_ip_iface (active_device), - ad_config, vpn_gw, 0xFFFFFFFF, ad_gw, + ad_config, vpn_gw, 32, ad_gw, nm_ip4_config_get_mss (config)); } } @@ -390,7 +363,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, nm_system_device_set_ip4_route (iface, config, route->address, - route->netmask, + route->prefix, route->gateway, nm_ip4_config_get_mss (config)); } diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 904bf77f77..a4a56448eb 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -156,20 +156,54 @@ nm_utils_ip4_addr_to_nl_addr (guint32 ip4_addr) * MUST be in network byte order. * */ -int -nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask) +guint32 +nm_utils_ip4_netmask_to_prefix (guint32 netmask) { - int i = 1; + guchar *p, *end; + guint32 prefix = 0; - g_return_val_if_fail (ip4_netmask != 0, 0); + p = (guchar *) &netmask; + end = p + sizeof (guint32); - /* Just count how many bit shifts we need */ - ip4_netmask = ntohl (ip4_netmask); - while (!(ip4_netmask & 0x1) && ++i) - ip4_netmask = ip4_netmask >> 1; - return (32 - (i-1)); + while ((*p == 0xFF) && p < end) { + prefix += 8; + p++; + } + + if (p < end) { + guchar v = *p; + + while (v) { + prefix++; + v <<= 1; + } + } + + return prefix; } +/* + * nm_utils_ip4_prefix_to_netmask + * + * Figure out the netmask from a prefix. + * + */ +guint32 +nm_utils_ip4_prefix_to_netmask (guint32 prefix) +{ + guint32 msk = 0x80000000; + guint32 netmask = 0; + + while (prefix > 0) { + netmask |= msk; + msk >>= 1; + prefix--; + } + + return (guint32) htonl (netmask); +} + + /* From hostap, Copyright (c) 2002-2005, Jouni Malinen */ static int hex2num (char c) diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index e2d024aee5..82f68b72be 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -39,8 +39,6 @@ void nm_print_device_capabilities (NMDevice *dev); struct nl_addr *nm_utils_ip4_addr_to_nl_addr (guint32 ip4_addr); -int nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask); - char *nm_utils_hexstr2bin (const char *hex, size_t len); char *nm_ether_ntop (const struct ether_addr *mac); diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index b69b0dced2..cfcf21612c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -34,11 +34,11 @@ #include #include #include +#include #include "nm-dhcp-manager.h" #include "nm-marshal.h" #include "nm-utils.h" -#include "NetworkManagerUtils.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" @@ -1023,8 +1023,8 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, str = g_hash_table_lookup (device->options, "new_subnet_mask"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { - addr->netmask = tmp_addr.s_addr; - nm_info (" netmask %s", str); + addr->prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); + nm_info (" prefix %d (%s)", addr->prefix, str); } str = g_hash_table_lookup (device->options, "new_routers"); @@ -1126,7 +1126,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr->address = (guint32) rt_addr.s_addr; - addr->netmask = 0xFFFFFFFF; /* 255.255.255.255 */ + addr->prefix = 32; /* 255.255.255.255 */ addr->gateway = (guint32) rt_route.s_addr; nm_ip4_config_take_static_route (ip4_config, addr); diff --git a/src/nm-device.c b/src/nm-device.c index 733897133e..3f50823e56 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -648,7 +648,7 @@ nm_device_new_ip4_autoip_config (NMDevice *self) config = nm_ip4_config_new (); addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr->address = (guint32) ip.s_addr; - addr->netmask = (guint32) ntohl (0xFFFF0000); + addr->prefix = 16; nm_ip4_config_take_address (config, addr); return config; @@ -699,7 +699,7 @@ nm_device_new_ip4_shared_config (NMDevice *self) config = nm_ip4_config_new (); addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr->address = tmp_addr; - addr->netmask = (guint32) ntohl (0xFFFFFF00); /* 255.255.255.0 */ + addr->prefix = 24; /* 255.255.255.0 */ nm_ip4_config_take_address (config, addr); /* Remove the address lock when the object gets disposed */ diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 17d0e1a533..40acfc364a 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -490,13 +490,6 @@ static int ip4_addr_to_rtnl_peer (guint32 ip4_address, struct rtnl_addr *addr) return err; } -static void ip4_addr_to_rtnl_prefixlen (guint32 ip4_netmask, struct rtnl_addr *addr) -{ - g_return_if_fail (addr != NULL); - - rtnl_addr_set_prefixlen (addr, nm_utils_ip4_netmask_to_prefix (ip4_netmask)); -} - static int ip4_addr_to_rtnl_broadcast (guint32 ip4_broadcast, struct rtnl_addr *addr) { struct nl_addr * local = NULL; @@ -534,14 +527,15 @@ nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags) if (flags & NM_RTNL_ADDR_PTP_ADDR) success = (ip4_addr_to_rtnl_peer (priv->ptp_address, addr) >= 0); - if (flags & NM_RTNL_ADDR_NETMASK) - ip4_addr_to_rtnl_prefixlen (config_addr->netmask, addr); + if (flags & NM_RTNL_ADDR_PREFIX) + rtnl_addr_set_prefixlen (addr, config_addr->prefix); if (flags & NM_RTNL_ADDR_BROADCAST) { - guint32 hostmask, network, bcast; + guint32 hostmask, network, bcast, netmask; - network = ntohl (config_addr->address) & ntohl (config_addr->netmask); - hostmask = ~ntohl (config_addr->netmask); + netmask = nm_utils_ip4_prefix_to_netmask (config_addr->prefix); + network = ntohl (config_addr->address) & ntohl (netmask); + hostmask = ~ntohl (netmask); bcast = htonl (network | hostmask); success = (ip4_addr_to_rtnl_broadcast (bcast, addr) >= 0); @@ -597,7 +591,7 @@ ip4_addresses_to_gvalue (GSList *list, GValue *value) array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); g_array_append_val (array, ip4_addr->address); - g_array_append_val (array, ip4_addr->netmask); + g_array_append_val (array, ip4_addr->prefix); if (ip4_addr->gateway) g_array_append_val (array, ip4_addr->gateway); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 95af877fea..e071dd8e96 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -107,11 +107,11 @@ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss); #define NM_RTNL_ADDR_NONE 0x0000 #define NM_RTNL_ADDR_ADDR 0x0001 #define NM_RTNL_ADDR_PTP_ADDR 0x0002 -#define NM_RTNL_ADDR_NETMASK 0x0004 +#define NM_RTNL_ADDR_PREFIX 0x0004 #define NM_RTNL_ADDR_BROADCAST 0x0008 -#define NM_RTNL_ADDR_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_NETMASK | NM_RTNL_ADDR_BROADCAST) -#define NM_RTNL_ADDR_PTP_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_NETMASK | NM_RTNL_ADDR_PTP_ADDR) +#define NM_RTNL_ADDR_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_PREFIX | NM_RTNL_ADDR_BROADCAST) +#define NM_RTNL_ADDR_PTP_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_PREFIX | NM_RTNL_ADDR_PTP_ADDR) struct rtnl_addr *nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 6a7258e7fb..2dfe3e8122 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -339,12 +339,9 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, remove_timeout_handler (manager); - /* FIXME */ -/* g_source_remove (priv->ipconfig_timeout); */ -/* priv->ipconfig_timeout = 0; */ - config = nm_ip4_config_new (); addr = g_malloc0 (sizeof (NMSettingIP4Address)); + addr->prefix = 32; val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_GATEWAY); if (val) { @@ -356,18 +353,14 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, if (val) addr->address = g_value_get_uint (val); - val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_NETMASK); + val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_PREFIX); if (val) - addr->netmask = g_value_get_uint (val); - else { - /* If no netmask, default to Class C address */ - addr->netmask = htonl (0x000000FF); - } + addr->prefix = g_value_get_uint (val); - if (addr->netmask && addr->address) { + if (addr->address && addr->prefix) { nm_ip4_config_take_address (config, addr); } else { - nm_warning ("%s: invalid IPv4 address or netmask received!", __func__); + nm_warning ("%s: invalid IPv4 address received!", __func__); g_free (addr); goto out; } diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c index c4e2071b2a..3df478ddb3 100644 --- a/src/ppp-manager/nm-pppd-plugin.c +++ b/src/ppp-manager/nm-pppd-plugin.c @@ -15,6 +15,7 @@ #include "nm-ppp-status.h" #include "nm-pppd-plugin-glue.h" #include "nm-dbus-glib-types.h" +#include "nm-utils.h" int plugin_init (void); @@ -163,8 +164,7 @@ nm_ip_up (void *data, int arg) uint_to_gvalue (peer_opts.hisaddr)); } - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_NETMASK, - uint_to_gvalue (0xFFFFFFFF)); + g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_PREFIX, uint_to_gvalue (32)); if (opts.dnsaddr[0] || opts.dnsaddr[1]) { array = g_array_new (FALSE, FALSE, sizeof (guint32)); diff --git a/src/ppp-manager/nm-pppd-plugin.h b/src/ppp-manager/nm-pppd-plugin.h index a06b947ab9..9899641406 100644 --- a/src/ppp-manager/nm-pppd-plugin.h +++ b/src/ppp-manager/nm-pppd-plugin.h @@ -4,7 +4,7 @@ #define NM_PPP_IP4_CONFIG_INTERFACE "interface" #define NM_PPP_IP4_CONFIG_ADDRESS "address" -#define NM_PPP_IP4_CONFIG_NETMASK "netmask" +#define NM_PPP_IP4_CONFIG_PREFIX "prefix" #define NM_PPP_IP4_CONFIG_GATEWAY "gateway" #define NM_PPP_IP4_CONFIG_DNS "dns" #define NM_PPP_IP4_CONFIG_WINS "wins" diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 50f8540ede..9758bfd234 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -290,7 +290,7 @@ print_vpn_config (NMIP4Config *config, nm_info ("VPN Gateway: %s", ip_address_to_string (addr->gateway)); nm_info ("Tunnel Device: %s", tundev); nm_info ("Internal IP4 Address: %s", ip_address_to_string (addr->address)); - nm_info ("Internal IP4 Netmask: %s", ip_address_to_string (addr->netmask)); + nm_info ("Internal IP4 Prefix: %d", addr->prefix); nm_info ("Internal IP4 Point-to-Point Address: %s", ip_address_to_string (nm_ip4_config_get_ptp_address (config))); nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config)); @@ -298,9 +298,9 @@ print_vpn_config (NMIP4Config *config, num = nm_ip4_config_get_num_static_routes (config); for (i = 0; i < num; i++) { addr = nm_ip4_config_get_static_route (config, i); - nm_info ("Static Route: %s/%s Gateway: %s", + nm_info ("Static Route: %s/%d Gateway: %s", ip_address_to_string (addr->address), - ip_address_to_string (addr->netmask), + addr->prefix, ip_address_to_string (addr->gateway)); } @@ -344,7 +344,7 @@ merge_vpn_routes (NMVPNConnection *connection, NMIP4Config *config) errno = 0; prefix = strtol (p + 1, NULL, 10); - if (errno || prefix < 0 || prefix > 32) { + if (errno || prefix <= 0 || prefix > 32) { nm_warning ("Ignoring invalid route '%s'", route); goto next; } @@ -356,7 +356,7 @@ merge_vpn_routes (NMVPNConnection *connection, NMIP4Config *config) addr = g_new0 (NMSettingIP4Address, 1); addr->address = tmp.s_addr; - addr->netmask = ntohl (0xFFFFFFFF << (32 - prefix)); + addr->prefix = (guint32) prefix; addr->gateway = 0; nm_ip4_config_take_static_route (config, addr); @@ -390,6 +390,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, config = nm_ip4_config_new (); addr = g_malloc0 (sizeof (NMSettingIP4Address)); + addr->prefix = 24; /* default to class C */ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY); if (val) @@ -403,15 +404,11 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, if (val) nm_ip4_config_set_ptp_address (config, g_value_get_uint (val)); - val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NETMASK); + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX); if (val) - addr->netmask = g_value_get_uint (val); - else { - /* If no netmask, default to Class C address */ - addr->netmask = htonl (0x000000FF); - } + addr->prefix = g_value_get_uint (val); - if (addr->address && addr->netmask) { + if (addr->address && addr->prefix) { nm_ip4_config_take_address (config, addr); } else { g_warning ("%s: invalid IP4 config received!", __func__); diff --git a/system-settings/plugins/ifcfg-fedora/reader.c b/system-settings/plugins/ifcfg-fedora/reader.c index fdf1404b39..aef49f5a8b 100644 --- a/system-settings/plugins/ifcfg-fedora/reader.c +++ b/system-settings/plugins/ifcfg-fedora/reader.c @@ -164,6 +164,7 @@ make_ip4_setting (shvarFile *ifcfg, GError **error) char *value = NULL; NMSettingIP4Address tmp = { 0, 0, 0 }; char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + guint32 netmask = 0; value = svGetValue (ifcfg, "BOOTPROTO"); if (value && (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp"))) @@ -195,14 +196,15 @@ make_ip4_setting (shvarFile *ifcfg, GError **error) } } - get_one_ip4_addr (ifcfg, "NETMASK", &tmp.netmask, error); + get_one_ip4_addr (ifcfg, "NETMASK", &netmask, error); if (*error) goto error; + tmp.prefix = nm_utils_ip4_netmask_to_prefix (netmask); done: s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); s_ip4->method = g_strdup (method); - if (tmp.address || tmp.netmask || tmp.gateway) { + if (tmp.address || tmp.prefix || tmp.gateway) { NMSettingIP4Address *addr; addr = g_new0 (NMSettingIP4Address, 1); memcpy (addr, &tmp, sizeof (NMSettingIP4Address)); diff --git a/system-settings/plugins/ifcfg-suse/parser.c b/system-settings/plugins/ifcfg-suse/parser.c index 65db38d89c..1f1ee4b4bf 100644 --- a/system-settings/plugins/ifcfg-suse/parser.c +++ b/system-settings/plugins/ifcfg-suse/parser.c @@ -95,20 +95,6 @@ make_connection_setting (shvarFile *file, return (NMSetting *) s_con; } -static guint32 -ip4_prefix_to_netmask (int prefix) -{ - guint32 msk = 0x80000000; - guint32 netmask = 0; - - while (prefix > 0) { - netmask |= msk; - msk >>= 1; - prefix--; - } - - return htonl (netmask); -} static NMSetting * make_ip4_setting (shvarFile *ifcfg) @@ -145,7 +131,7 @@ make_ip4_setting (shvarFile *ifcfg) tmp.address = ip4_addr.s_addr; if (g_strv_length (pieces) == 2) - tmp.netmask = ip4_prefix_to_netmask (atoi (pieces[1])); + tmp.prefix = atoi (pieces[1]); } else g_warning ("Ignoring invalid IP4 address '%s'", str); @@ -153,31 +139,37 @@ make_ip4_setting (shvarFile *ifcfg) g_free (str); } - if (tmp.address && tmp.netmask == 0) { + if (tmp.address && tmp.prefix == 0) { str = svGetValue (ifcfg, "PREFIXLEN"); if (str) { - tmp.netmask = ip4_prefix_to_netmask (atoi (str)); + tmp.prefix = atoi (str); g_free (str); } } - if (tmp.address && tmp.netmask == 0) { + if (tmp.address && tmp.prefix == 0) { str = svGetValue (ifcfg, "NETMASK"); if (str) { struct in_addr mask_addr; if (inet_pton (AF_INET, str, &mask_addr) > 0) - tmp.netmask = mask_addr.s_addr; + tmp.prefix = nm_utils_ip4_netmask_to_prefix (mask_addr.s_addr); else { g_warning ("Ignoring invalid IP4 addres: invalid netmask: '%s'", str); tmp.address = 0; - tmp.netmask = 0; + tmp.prefix = 0; } g_free (str); } } - if (tmp.address || tmp.netmask) { + if (!tmp.prefix || tmp.prefix > 32) { + g_warning ("Ignoring invalid IP4 addres: invalid prefix: '%d'", tmp.prefix); + tmp.address = 0; + tmp.prefix = 0; + } + + if (tmp.address) { NMSettingIP4Address *addr; addr = g_new0 (NMSettingIP4Address, 1); memcpy (addr, &tmp, sizeof (NMSettingIP4Address)); diff --git a/system-settings/plugins/keyfile/reader.c b/system-settings/plugins/keyfile/reader.c index 0aa7be7d77..72a2ed81a3 100644 --- a/system-settings/plugins/keyfile/reader.c +++ b/system-settings/plugins/keyfile/reader.c @@ -1,5 +1,7 @@ /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ +#include +#include #include #include #include @@ -88,6 +90,7 @@ read_array_of_array_of_uint (GKeyFile *file, int ret; GArray *address; guint32 empty = 0; + int j; key_name = g_strdup_printf ("address%d", i); tmp = g_key_file_get_string_list (file, setting->name, key_name, &length, NULL); @@ -103,17 +106,33 @@ read_array_of_array_of_uint (GKeyFile *file, /* convert the string array into IP addresses */ address = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - for (iter = tmp; *iter; iter++) { + for (iter = tmp, j = 0; *iter; iter++, j++) { struct in_addr addr; - ret = inet_pton (AF_INET, *iter, &addr); - if (ret <= 0) { - g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter); - g_array_free (address, TRUE); - goto next; - } + if (j == 1) { + /* prefix */ + long tmp_prefix; + guint32 prefix; - g_array_append_val (address, addr.s_addr); + errno = 0; + tmp_prefix = strtol (*iter, NULL, 10); + if (errno || (tmp_prefix < 0) || (tmp_prefix > 32)) { + g_warning ("%s: ignoring invalid IPv4 %s prefix '%s'", __func__, key_name, *iter); + g_array_free (address, TRUE); + goto next; + } + prefix = (guint32) tmp_prefix; + g_array_append_val (address, prefix); + } else { + /* address and gateway */ + ret = inet_pton (AF_INET, *iter, &addr); + if (ret <= 0) { + g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter); + g_array_free (address, TRUE); + goto next; + } + g_array_append_val (address, addr.s_addr); + } } /* fill in blank gateway if not specified */ diff --git a/test/nm-tool.c b/test/nm-tool.c index 47d73d6b15..4e3dee922d 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -339,13 +339,16 @@ detail_device (gpointer data, gpointer user_data) for (iter = (GSList *) nm_ip4_config_get_addresses (cfg); iter; iter = g_slist_next (iter)) { NMSettingIP4Address *addr = iter->data; + char *tmp2; tmp = ip4_address_as_string (addr->address); print_string (" Address", tmp); g_free (tmp); - tmp = ip4_address_as_string (addr->netmask); - print_string (" Netmask", tmp); + tmp2 = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (addr->prefix)); + tmp = g_strdup_printf ("%d (%s)", addr->prefix, tmp2); + g_free (tmp2); + print_string (" Prefix", tmp); g_free (tmp); tmp = ip4_address_as_string (addr->gateway);