summary refs log tree commit diff
path: root/src/settings/plugins/ifupdown/parser.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2012-03-24 01:37:02 +0100
committerMichael Biebl <biebl@debian.org>2012-03-24 01:37:02 +0100
commitde06e5715e780baade318f3490ac7a4c9ce84e32 (patch)
tree23fbc3fafc12072476eff98bee60100eb54c29db /src/settings/plugins/ifupdown/parser.c
parentb436a68a20ff3114ded32a7a3d70cdd4954039f9 (diff)
Imported Upstream version 0.9.4.0 upstream/0.9.4.0
Diffstat (limited to 'src/settings/plugins/ifupdown/parser.c')
-rw-r--r--src/settings/plugins/ifupdown/parser.c315
1 files changed, 243 insertions, 72 deletions
diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c
index dc2f8abf..6927f43f 100644
--- a/src/settings/plugins/ifupdown/parser.c
+++ b/src/settings/plugins/ifupdown/parser.c
@@ -25,6 +25,7 @@
 #include <arpa/inet.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include <nm-connection.h>
 #include <NetworkManager.h>
@@ -311,8 +312,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection,
 		return;
 	}
 
-	s_wireless = NM_SETTING_WIRELESS(nm_connection_get_setting(connection,
-												    NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless(connection);
 	g_return_if_fail(s_wireless);
 
 	PLUGIN_PRINT ("SCPlugin-Ifupdown","update wireless security settings (%s).", block->name);
@@ -433,96 +433,263 @@ eni_plugin_error_quark() {
 
 	return error_quark;
 }
-	
 
 static void
+ifupdown_ip4_add_dns (NMSettingIP4Config *s_ip4, const char *dns)
+{
+	struct in_addr addr;
+	char **list, **iter;
+
+	if (dns == NULL)
+		return;
+
+	list = g_strsplit_set (dns, " \t", -1);
+	for (iter = list; iter && *iter; iter++) {
+		g_strstrip (*iter);
+		if (isblank (*iter[0]))
+			continue;
+		if (!inet_pton (AF_INET, *iter, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: ignoring invalid nameserver '%s'", *iter);
+			continue;
+		}
+
+		if (!nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: duplicate DNS domain '%s'", *iter);
+		}
+	}
+	g_strfreev (list);
+}
+
+static gboolean
 update_ip4_setting_from_if_block(NMConnection *connection,
-						   if_block *block)
+						   if_block *block,
+						   GError **error)
 {
 
-	NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new());
+	NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new());
 	const char *type = ifparser_getkey(block, "inet");
 	gboolean is_static = type && !strcmp("static", type);
 
-	if(!is_static) {
-		g_object_set(ip4_setting,
-				   NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
-				   NULL);
+	if (!is_static) {
+		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
 	} else {
- 		struct in_addr tmp_ip4_addr;
-		NMIP4Address *ip4_addr = nm_ip4_address_new ();
-
-		const char *address_v = ifparser_getkey(block, "address");
-		const char *netmask_v = ifparser_getkey(block, "netmask");
-		const char *gateway_v = ifparser_getkey(block, "gateway");
-		const char *nameserver_v = ifparser_getkey(block, "dns-nameserver");
-		const char *nameservers_v = ifparser_getkey(block, "dns-nameservers");
-		GSList* nameservers_list = NULL;
-		GSList* nameservers_list_i = NULL;
-		GError *error = NULL;
-
-		if(nameservers_v)
-			nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v);
-		if(nameserver_v)
-			nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v));
-
-		if (!address_v)
-			address_v = g_strdup ("0.0.0.0");
-
-		if (inet_pton (AF_INET, address_v, &tmp_ip4_addr))
-			nm_ip4_address_set_address (ip4_addr, tmp_ip4_addr.s_addr);
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "address", address_v);
-		if (!netmask_v)
-			netmask_v = g_strdup( "255.255.255.255");
-
-		if (inet_pton (AF_INET, netmask_v, &tmp_ip4_addr))
-			nm_ip4_address_set_prefix (ip4_addr, nm_utils_ip4_netmask_to_prefix(tmp_ip4_addr.s_addr));
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "netmask", netmask_v);
+		struct in_addr tmp_addr, tmp_mask, tmp_gw;
+		NMIP4Address *addr;
+		const char *address_v;
+		const char *netmask_v;
+		const char *gateway_v;
+		const char *nameserver_v;
+		const char *nameservers_v;
+		const char *search_v;
+		char **list, **iter;
+		guint32 netmask_int = 32;
+
+		/* Address */
+		address_v = ifparser_getkey (block, "address");
+		if (!address_v || !inet_pton (AF_INET, address_v, &tmp_addr)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+			             "Missing IPv4 address '%s'",
+			             address_v ? address_v : "(none)");
+			goto error;
+		}
 
+		/* mask/prefix */
+		netmask_v = ifparser_getkey (block, "netmask");
+		if (netmask_v) {
+			if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) {
+				g_set_error (error, eni_plugin_error_quark (), 0,
+						   "Invalid IPv4 netmask '%s'", netmask_v);
+				goto error;
+			}
+			netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask.s_addr);
+		}
+
+		/* gateway */
+		gateway_v = ifparser_getkey (block, "gateway");
 		if (!gateway_v)
-			gateway_v = g_strdup (address_v);
+			gateway_v = address_v;  /* dcbw: whaaa?? */
+		if (!inet_pton (AF_INET, gateway_v, &tmp_gw)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+					   "Invalid IPv4 gateway '%s'", gateway_v);
+			goto error;
+		}
 
-		if (inet_pton (AF_INET, gateway_v, &tmp_ip4_addr))
-			nm_ip4_address_set_gateway (ip4_addr, tmp_ip4_addr.s_addr);
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "gateway", gateway_v);
+		/* Add the new address to the setting */
+		addr = nm_ip4_address_new ();
+		nm_ip4_address_set_address (addr, tmp_addr.s_addr);
+		nm_ip4_address_set_prefix (addr, netmask_int);
+		nm_ip4_address_set_gateway (addr, tmp_gw.s_addr);
 
-		if (nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) {
+		if (nm_setting_ip4_config_add_address (s_ip4, addr)) {
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
-			             nm_setting_ip4_config_get_num_addresses (ip4_setting));
+			             nm_setting_ip4_config_get_num_addresses (s_ip4));
 		} else {
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP4 address");
 		}
 
-		while(nameservers_list_i) {
-			gchar *dns = nameservers_list_i->data;
-			nameservers_list_i = nameservers_list_i -> next;
-			if(!dns)
-				continue;
-			if (inet_pton (AF_INET, dns, &tmp_ip4_addr)) {
-				if (!nm_setting_ip4_config_add_dns (ip4_setting, tmp_ip4_addr.s_addr))
-					PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns);
-			} else
-				g_set_error (&error, eni_plugin_error_quark (), 0,
-						   "Invalid %s IP4 address nameserver '%s'", "nameserver", dns);
+		nameserver_v = ifparser_getkey (block, "dns-nameserver");
+		ifupdown_ip4_add_dns (s_ip4, nameserver_v);
+
+		nameservers_v = ifparser_getkey (block, "dns-nameservers");
+		ifupdown_ip4_add_dns (s_ip4, nameservers_v);
+
+		if (!nm_setting_ip4_config_get_num_dns (s_ip4))
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
+
+		/* DNS searches */
+		search_v = ifparser_getkey (block, "dns-search");
+		if (search_v) {
+			list = g_strsplit_set (search_v, " \t", -1);
+			for (iter = list; iter && *iter; iter++) {
+				g_strstrip (*iter);
+				if (isblank (*iter[0]))
+					continue;
+				if (!nm_setting_ip4_config_add_dns_search (s_ip4, *iter)) {
+					PLUGIN_WARN ("SCPlugin-Ifupdown",
+							   "    warning: duplicate DNS domain '%s'", *iter);
+				}
+			}
+			g_strfreev (list);
 		}
-		if (!nm_setting_ip4_config_get_num_dns (ip4_setting))
+
+		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
+	}
+
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+	return TRUE;
+
+error:
+	g_object_unref (s_ip4);
+	return FALSE;
+}
+
+static void
+ifupdown_ip6_add_dns (NMSettingIP6Config *s_ip6, const char *dns)
+{
+	struct in6_addr addr;
+	char **list, **iter;
+
+	if (dns == NULL)
+		return;
+
+	list = g_strsplit_set (dns, " \t", -1);
+	for (iter = list; iter && *iter; iter++) {
+		g_strstrip (*iter);
+		if (isblank (*iter[0]))
+			continue;
+		if (!inet_pton (AF_INET6, *iter, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: ignoring invalid nameserver '%s'", *iter);
+			continue;
+		}
+
+		if (!nm_setting_ip6_config_add_dns (s_ip6, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: duplicate DNS domain '%s'", *iter);
+		}
+	}
+	g_strfreev (list);
+}
+
+static gboolean
+update_ip6_setting_from_if_block(NMConnection *connection,
+						   if_block *block,
+						   GError **error)
+{
+	NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new());
+	const char *type = ifparser_getkey(block, "inet6");
+	gboolean is_static = type && (!strcmp("static", type) ||
+							!strcmp("v4tunnel", type));
+
+	if (!is_static) {
+		g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+	} else {
+		struct in6_addr tmp_addr, tmp_gw;
+		NMIP6Address *addr;
+		const char *address_v;
+		const char *prefix_v;
+		const char *gateway_v;
+		const char *nameserver_v;
+		const char *nameservers_v;
+		const char *search_v;
+		int prefix_int = 128;
+		char **list, **iter;
+
+		/* Address */
+		address_v = ifparser_getkey(block, "address");
+		if (!address_v || !inet_pton (AF_INET6, address_v, &tmp_addr)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+			             "Missing IPv6 address '%s'",
+			             address_v ? address_v : "(none)");
+			goto error;
+		}
+
+		/* Prefix */
+		prefix_v = ifparser_getkey(block, "netmask");
+		if (prefix_v)
+			prefix_int = g_ascii_strtoll (prefix_v, NULL, 10);
+
+		/* Gateway */
+		gateway_v = ifparser_getkey (block, "gateway");
+		if (!gateway_v)
+			gateway_v = address_v;  /* dcbw: whaaa?? */
+		if (!inet_pton (AF_INET6, gateway_v, &tmp_gw)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+					   "Invalid IPv6 gateway '%s'", gateway_v);
+			goto error;
+		}
+
+		/* Add the new address to the setting */
+		addr = nm_ip6_address_new ();
+		nm_ip6_address_set_address (addr, &tmp_addr);
+		nm_ip6_address_set_prefix (addr, prefix_int);
+		nm_ip6_address_set_gateway (addr, &tmp_gw);
+
+		if (nm_setting_ip6_config_add_address (s_ip6, addr)) {
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
+					   nm_setting_ip6_config_get_num_addresses (s_ip6));
+		} else {
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP6 address");
+		}
+
+		nameserver_v = ifparser_getkey(block, "dns-nameserver");
+		ifupdown_ip6_add_dns (s_ip6, nameserver_v);
+
+		nameservers_v = ifparser_getkey(block, "dns-nameservers");
+		ifupdown_ip6_add_dns (s_ip6, nameservers_v);
+
+		if (!nm_setting_ip6_config_get_num_dns (s_ip6))
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
 
-		g_object_set(ip4_setting,
-				   NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
-				   NULL);
+		/* DNS searches */
+		search_v = ifparser_getkey (block, "dns-search");
+		if (search_v) {
+			list = g_strsplit_set (search_v, " \t", -1);
+			for (iter = list; iter && *iter; iter++) {
+				g_strstrip (*iter);
+				if (isblank (*iter[0]))
+					continue;
+				if (!nm_setting_ip6_config_add_dns_search (s_ip6, *iter)) {
+					PLUGIN_WARN ("SCPlugin-Ifupdown",
+							   "    warning: duplicate DNS domain '%s'", *iter);
+				}
+			}
+			g_strfreev (list);
+		}
 
-		g_slist_foreach (nameservers_list, (GFunc) g_free, NULL);
-		g_slist_free (nameservers_list);
+		g_object_set (s_ip6,
+		              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+		              NULL);
 	}
 
-	nm_connection_add_setting(connection, NM_SETTING(ip4_setting));
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+	return TRUE;
+
+error:
+	g_object_unref (s_ip6);
+	return FALSE;
 }
 
 gboolean
@@ -537,7 +704,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
 	NMSettingConnection *s_con;
 	gboolean success = FALSE;
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	if(!s_con) {
 		s_con = NM_SETTING_CONNECTION (nm_setting_connection_new());
 		g_assert (s_con);
@@ -562,15 +729,19 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
 			   block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
 
 	if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type))
-		update_wired_setting_from_if_block (connection, block);	
+		update_wired_setting_from_if_block (connection, block);
 	else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
 		update_wireless_setting_from_if_block (connection, block);
 		update_wireless_security_setting_from_if_block (connection, block);
 	}
 
-	update_ip4_setting_from_if_block (connection, block);
+	if (ifparser_haskey(block, "inet6"))
+		success = update_ip6_setting_from_if_block (connection, block, error);
+	else
+		success = update_ip4_setting_from_if_block (connection, block, error);
 
-	success = nm_connection_verify (connection, error);
+	if (success == TRUE)
+		success = nm_connection_verify (connection, error);
 
 	g_free (idstr);
 	return success;