static gboolean
ip_addresses_with_prefix_from_strv (GBinding     *binding,
                                    const GValue *source_value,
                                    GValue       *target_value,
                                    gpointer      user_data)
{
	int family = GPOINTER_TO_INT (user_data);
	char **strings;
	GPtrArray *addrs;
	NMIPAddress *addr;
	char *addrstr;
	guint32 prefix;
	int i;

	strings = g_value_get_boxed (source_value);
	/* Fetch the original property value, so as to preserve their extra attributes */
	g_object_get (g_binding_get_source (binding),
	              g_binding_get_source_property (binding), &addrs,
	              NULL);

	for (i = 0; strings[i]; i++) {
		if (i >= addrs->len) {
			if (family == AF_INET)
				addr = nm_ip_address_new (AF_INET, "0.0.0.0", 32, NULL);
			else
				addr = nm_ip_address_new (AF_INET6, "::", 128, NULL);
			g_ptr_array_add (addrs, addr);
		} else
			addr = addrs->pdata[i];

		if (!parse_addr_prefix (strings[i], family, &addrstr, &prefix)) {
			g_ptr_array_unref (addrs);
			return FALSE;
		}

		nm_ip_address_set_address (addr, addrstr);
		nm_ip_address_set_prefix (addr, prefix);
		g_free (addrstr);
	}

	g_ptr_array_set_size (addrs, i);
	g_value_take_boxed (target_value, addrs);
	return TRUE;
}
Example #2
0
/*
 * Parse IP address from string to NMIPAddress stucture.
 * ip_str is the IP address in the form address/prefix
 */
NMIPAddress *
nmc_parse_and_build_address (int family, const char *ip_str, GError **error)
{
	int max_prefix = (family == AF_INET) ? 32 : 128;
	NMIPAddress *addr = NULL;
	const char *ip;
	char *tmp;
	char *plen;
	long int prefix;
	GError *local = NULL;

	g_return_val_if_fail (ip_str != NULL, NULL);
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);

	tmp = g_strdup (ip_str);
	plen = strchr (tmp, '/');  /* prefix delimiter */
	if (plen)
		*plen++ = '\0';

	ip = tmp;

	prefix = max_prefix;
	if (plen) {
		if (!nmc_string_to_int (plen, TRUE, 1, max_prefix, &prefix)) {
			g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
			             _("invalid prefix '%s'; <1-%d> allowed"), plen, max_prefix);
			goto finish;
		}
	}

	addr = nm_ip_address_new (family, ip, (guint32) prefix, &local);
	if (!addr) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid IP address: %s"), local->message);
		g_clear_error (&local);
	}

finish:
	g_free (tmp);
	return addr;
}
Example #3
0
static gboolean
update_ip6_setting_from_if_block(NMConnection *connection,
						   if_block *block,
						   GError **error)
{
	NMSettingIPConfig *s_ip6 = NM_SETTING_IP_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_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
	} else {
		NMIPAddress *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) {
			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
			             "Missing IPv6 address");
			goto error;
		}

		/* Prefix */
		prefix_v = ifparser_getkey(block, "netmask");
		if (prefix_v)
			prefix_int = g_ascii_strtoll (prefix_v, NULL, 10);

		/* Add the new address to the setting */
		addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error);
		if (!addr)
			goto error;

		if (nm_setting_ip_config_add_address (s_ip6, addr)) {
			nm_log_info (LOGD_SETTINGS, "addresses count: %d",
			             nm_setting_ip_config_get_num_addresses (s_ip6));
		} else {
			nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP6 address");
		}
		nm_ip_address_unref (addr);

		/* gateway */
		gateway_v = ifparser_getkey (block, "gateway");
		if (gateway_v) {
			if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) {
				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
				             "Invalid IPv6 gateway '%s'", gateway_v);
				goto error;
			}
			if (!nm_setting_ip_config_get_gateway (s_ip6))
				g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL);
		}

		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_ip_config_get_num_dns (s_ip6))
			nm_log_info (LOGD_SETTINGS, "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_ip_config_add_dns_search (s_ip6, *iter))
					nm_log_warn (LOGD_SETTINGS, "    duplicate DNS domain '%s'", *iter);
			}
			g_strfreev (list);
		}

		g_object_set (s_ip6,
		              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
		              NULL);
	}

	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
	return TRUE;

error:
	g_object_unref (s_ip6);
	return FALSE;
}
Example #4
0
static gboolean
update_ip4_setting_from_if_block(NMConnection *connection,
						   if_block *block,
						   GError **error)
{

	NMSettingIPConfig *s_ip4 = NM_SETTING_IP_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 (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
	} else {
		guint32 tmp_mask;
		NMIPAddress *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) {
			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
			             "Missing IPv4 address");
			goto error;
		}

		/* mask/prefix */
		netmask_v = ifparser_getkey (block, "netmask");
		if (netmask_v) {
			if (strlen (netmask_v) < 7) {
				netmask_int = atoi (netmask_v);
			} else if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) {
				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
						   "Invalid IPv4 netmask '%s'", netmask_v);
				goto error;
			} else {
				netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask);
			}
		}

		/* Add the new address to the setting */
		addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error);
		if (!addr)
			goto error;

		if (nm_setting_ip_config_add_address (s_ip4, addr)) {
			nm_log_info (LOGD_SETTINGS, "addresses count: %d",
			             nm_setting_ip_config_get_num_addresses (s_ip4));
		} else {
			nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP4 address");
		}
		nm_ip_address_unref (addr);

		/* gateway */
		gateway_v = ifparser_getkey (block, "gateway");
		if (gateway_v) {
			if (!nm_utils_ipaddr_valid (AF_INET, gateway_v)) {
				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
				             "Invalid IPv4 gateway '%s'", gateway_v);
				goto error;
			}
			if (!nm_setting_ip_config_get_gateway (s_ip4))
				g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL);
		}

		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_ip_config_get_num_dns (s_ip4))
			nm_log_info (LOGD_SETTINGS, "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 (g_ascii_isspace (*iter[0]))
					continue;
				if (!nm_setting_ip_config_add_dns_search (s_ip4, *iter))
					nm_log_warn (LOGD_SETTINGS, "    duplicate DNS domain '%s'", *iter);
			}
			g_strfreev (list);
		}

		g_object_set (s_ip4, NM_SETTING_IP_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 gboolean
ui_to_setting (CEPageIP4 *self, GError **error)
{
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkTreeModel *model;
	GtkTreeIter tree_iter;
	int int_method = IP4_METHOD_AUTO;
	const char *method;
	GPtrArray *tmp_array = NULL;
	char **dns_servers = NULL;
	char **search_domains = NULL;
	GPtrArray *addresses = NULL;
	char *gateway = NULL;
	gboolean valid = FALSE, iter_valid;
	const char *text;
	gboolean ignore_auto_dns = FALSE;
	const char *dhcp_client_id = NULL;
	char **items = NULL, **iter;
	gboolean may_fail = FALSE;

	/* Method */
	if (gtk_combo_box_get_active_iter (priv->method, &tree_iter)) {
		gtk_tree_model_get (GTK_TREE_MODEL (priv->method_store), &tree_iter,
		                    METHOD_COL_NUM, &int_method, -1);
	}

	switch (int_method) {
	case IP4_METHOD_LINK_LOCAL:
		method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL;
		break;
	case IP4_METHOD_MANUAL:
		method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
		break;
	case IP4_METHOD_SHARED:
		method = NM_SETTING_IP4_CONFIG_METHOD_SHARED;
		break;
	case IP4_METHOD_DISABLED:
		method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
		break;
	case IP4_METHOD_AUTO_ADDRESSES:
		ignore_auto_dns = TRUE;
		/* fall through */
	default:
		method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
		break;
	}

	/* IP addresses */
	model = gtk_tree_view_get_model (priv->addr_list);
	iter_valid = gtk_tree_model_get_iter_first (model, &tree_iter);

	addresses = g_ptr_array_sized_new (1);
	while (iter_valid) {
		char *addr = NULL, *netmask = NULL, *addr_gw = NULL;
		NMIPAddress *nm_addr;
		guint32 prefix;

		gtk_tree_model_get (model, &tree_iter,
		                    COL_ADDRESS, &addr,
		                    COL_PREFIX, &netmask,
		                    COL_GATEWAY, &addr_gw,
		                    -1);

		if (   !addr
		    || !nm_utils_ipaddr_valid (AF_INET, addr)
		    || is_address_unspecified (addr)) {
			g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 address \"%s\" invalid"), addr ? addr : "");
			g_free (addr);
			g_free (netmask);
			g_free (addr_gw);
			goto out;
		}

		if (!parse_netmask (netmask, &prefix)) {
			g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 address netmask \"%s\" invalid"), netmask ? netmask : "");
			g_free (addr);
			g_free (netmask);
			g_free (addr_gw);
			goto out;
		}

		/* Gateway is optional... */
		if (addr_gw && *addr_gw && !nm_utils_ipaddr_valid (AF_INET, addr_gw)) {
			g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 gateway \"%s\" invalid"), addr_gw);
			g_free (addr);
			g_free (netmask);
			g_free (addr_gw);
			goto out;
		}

		nm_addr = nm_ip_address_new (AF_INET, addr, prefix, NULL);
		g_ptr_array_add (addresses, nm_addr);

		if (addresses->len == 1 && addr_gw && *addr_gw) {
			gateway = addr_gw;
			addr_gw = NULL;
		}

		g_free (addr);
		g_free (netmask);
		g_free (addr_gw);

		iter_valid = gtk_tree_model_iter_next (model, &tree_iter);
	}

	/* Don't pass empty array to the setting */
	if (!addresses->len) {
		g_ptr_array_free (addresses, TRUE);
		addresses = NULL;
	}

	/* DNS servers */
	tmp_array = g_ptr_array_new ();
	text = gtk_entry_get_text (GTK_ENTRY (priv->dns_servers));
	if (text && strlen (text)) {
		items = g_strsplit_set (text, ", ;:", 0);
		for (iter = items; *iter; iter++) {
			struct in_addr tmp_addr;
			char *stripped = g_strstrip (*iter);

			if (!*stripped)
				continue;

			if (inet_pton (AF_INET, stripped, &tmp_addr))
				g_ptr_array_add (tmp_array, g_strdup (stripped));
			else {
				g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 DNS server \"%s\" invalid"), stripped);
				g_strfreev (items);
				g_ptr_array_free (tmp_array, TRUE);
				goto out;
			}
		}
		g_strfreev (items);
	}
	g_ptr_array_add (tmp_array, NULL);
	dns_servers = (char **) g_ptr_array_free (tmp_array, FALSE);

	/* Search domains */
	tmp_array = g_ptr_array_new ();
	text = gtk_entry_get_text (GTK_ENTRY (priv->dns_searches));
	if (text && strlen (text)) {
		items = g_strsplit_set (text, ", ;:", 0);
		for (iter = items; *iter; iter++) {
			char *stripped = g_strstrip (*iter);

			if (strlen (stripped))
				g_ptr_array_add (tmp_array, g_strdup (stripped));
		}
		g_strfreev (items);
	}
	g_ptr_array_add (tmp_array, NULL);
	search_domains = (char **) g_ptr_array_free (tmp_array, FALSE);

	/* DHCP client ID */
	if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
		dhcp_client_id = gtk_entry_get_text (priv->dhcp_client_id);
		if (dhcp_client_id && !strlen (dhcp_client_id))
			dhcp_client_id = NULL;
	}

	may_fail = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->ip4_required));

	/* Update setting */
	g_object_set (priv->setting,
	              NM_SETTING_IP_CONFIG_METHOD, method,
	              NM_SETTING_IP_CONFIG_ADDRESSES, addresses,
	              NM_SETTING_IP_CONFIG_GATEWAY, gateway,
	              NM_SETTING_IP_CONFIG_DNS, dns_servers,
	              NM_SETTING_IP_CONFIG_DNS_SEARCH, search_domains,
	              NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
	              NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, dhcp_client_id,
	              NM_SETTING_IP_CONFIG_MAY_FAIL, may_fail,
	              NULL);
	valid = TRUE;

out:
	if (addresses) {
		g_ptr_array_foreach (addresses, (GFunc) free_one_addr, NULL);
		g_ptr_array_free (addresses, TRUE);
	}
	g_free (gateway);

	g_strfreev (dns_servers);
	g_strfreev (search_domains);

	return valid;
}