2008-07-07 Dan Williams <dcbw@redhat.com>

Convert to using IPv4 prefixes instead of netmasks.



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3812 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-07-07 18:57:37 +00:00
parent a2f98c6c59
commit e1e4100f76
23 changed files with 224 additions and 140 deletions

View file

@ -1,3 +1,7 @@
2008-07-07 Dan Williams <dcbw@redhat.com>
Convert to using IPv4 prefixes instead of netmasks.
2008-07-03 Dan Williams <dcbw@redhat.com>
* libnm-util/nm-setting-ip4-config.c

View file

@ -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"

View file

@ -3,7 +3,7 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP4Config">
<property name="Addresses" type="aau" access="read">
<tp:docstring>Tuples of IPv4 address/netmask/gateway. The gateway is optional, if not given should be 0.</tp:docstring>
<tp:docstring>Tuples of IPv4 address/prefix/gateway. The gateway is optional, if not given should be 0.</tp:docstring>
</property>
<property name="Hostname" type="s" access="read">
<tp:docstring>The hostname associated with this IPv4 address. FIXME: what about multiple hostnames?</tp:docstring>

View file

@ -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);

View file

@ -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;
}

View file

@ -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 */

View file

@ -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)
{

View file

@ -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);

View file

@ -62,17 +62,17 @@
#include <netlink/route/link.h>
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));
}

View file

@ -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 <jkmaline@cc.hut.fi> */
static int hex2num (char c)

View file

@ -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);

View file

@ -34,11 +34,11 @@
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#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);

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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));

View file

@ -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"

View file

@ -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__);

View file

@ -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));

View file

@ -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));

View file

@ -1,5 +1,7 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
@ -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 */

View file

@ -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);