Ejemplo n.º 1
0
static void
cell_error_data_func (GtkTreeViewColumn *tree_column,
                      GtkCellRenderer *cell,
                      GtkTreeModel *tree_model,
                      GtkTreeIter *iter,
                      gpointer data)
{
	guint32 col = GPOINTER_TO_UINT (data);
	char *value = NULL;
	const char *color = NULL;
	guint32 prefix;
	gboolean invalid = FALSE;

	gtk_tree_model_get (tree_model, iter, col, &value, -1);

	if (col == COL_ADDRESS)
		invalid =    !value || !*value || !nm_utils_ipaddr_valid (AF_INET, value)
		          || is_address_unspecified (value);
	else if (col == COL_PREFIX)
		invalid = !parse_netmask (value, &prefix);
	else if (col == COL_GATEWAY) {
		invalid = value && *value && !nm_utils_ipaddr_valid (AF_INET, value);

		/* Check gateway against address and prefix */
		if (!invalid && possibly_wrong_gateway (tree_model, iter, value))
			color = "#DDC000"; /* darker than "yellow", else selected text is hard to read */
	} else
		g_warn_if_reached ();

	if (invalid)
		color = "red";
	utils_set_cell_background (cell, color, color ? value : NULL);
	g_free (value);
}
Ejemplo n.º 2
0
static ip_block *
create_ip4_block (gchar * ip)
{
	ip_block *iblock = g_slice_new0 (ip_block);
	guint32 tmp_ip4_addr;
	int i;
	guint length;
	gchar **ip_mask;

	/* prefix format */
	if (strstr (ip, "/")) {
		gchar *prefix;

		ip_mask = g_strsplit (ip, "/", 0);
		length = g_strv_length (ip_mask);
		if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0]))
			goto error;
		iblock->ip = g_strdup (ip_mask[0]);
		prefix = ip_mask[1];
		i = 0;
		while (i < length && g_ascii_isdigit (prefix[i]))
			i++;
		prefix[i] = '\0';
		iblock->prefix = (guint32) atoi (ip_mask[1]);
	} else if (strstr (ip, "netmask")) {
		ip_mask = g_strsplit (ip, " ", 0);
		length = g_strv_length (ip_mask);
		if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0]))
			goto error;
		iblock->ip = g_strdup (ip_mask[0]);
		i = 0;
		while (i < length && !strstr (ip_mask[++i], "netmask")) ;
		while (i < length && ip_mask[++i][0] == '\0') ;
		if (i >= length)
			goto error;
		if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr))
			goto error;
		iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr);
	} else {
		g_slice_free (ip_block, iblock);
		if (!is_ip6_address (ip) && !strstr (ip, "dhcp"))
			nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip);
		return NULL;
	}
	if (iblock->prefix == 0 || iblock->prefix > 32) {
		nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip);
		goto error;
	}
	g_strfreev (ip_mask);
	return iblock;
error:
	if (!is_ip6_address (ip))
		nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip);
	g_strfreev (ip_mask);
	g_free (iblock->ip);
	g_slice_free (ip_block, iblock);
	return NULL;
}
Ejemplo n.º 3
0
static gboolean
ip_route_transform_from_next_hop_string (GBinding     *binding,
                                         const GValue *source_value,
                                         GValue       *target_value,
                                         gpointer      user_data)
{
	int family = GPOINTER_TO_INT (user_data);
	NMIPRoute *route;
	const char *text;

	text = g_value_get_string (source_value);
	if (*text) {
		if (!nm_utils_ipaddr_valid (family, text))
			return FALSE;
	} else
		text = NULL;

	/* Fetch the original property value */
	g_object_get (g_binding_get_source (binding),
	              g_binding_get_source_property (binding), &route,
	              NULL);

	nm_ip_route_set_next_hop (route, text);

	g_value_take_boxed (target_value, route);
	return TRUE;
}
Ejemplo n.º 4
0
static char *
get_ip6_next_hop (gchar * next_hop)
{
	gchar *tmp;

	if (!next_hop)
		return NULL;
	tmp = find_gateway_str (next_hop);
	if (!tmp) {
		nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop);
		return NULL;
	}
	tmp = g_strdup (tmp);
	strip_string (tmp, ' ');
	strip_string (tmp, '"');
	g_strstrip (tmp);
	if (!nm_utils_ipaddr_valid (AF_INET6, tmp))
		goto error;
	return tmp;
error:
	if (!is_ip4_address (tmp))
		nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp);
	g_free (tmp);

	return NULL;
}
Ejemplo n.º 5
0
static char *
get_ip4_gateway (gchar * gateway)
{
	gchar *tmp, *split;

	if (!gateway)
		return NULL;
	tmp = find_gateway_str (gateway);
	if (!tmp) {
		nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway);
		return NULL;
	}
	tmp = g_strdup (tmp);
	strip_string (tmp, ' ');
	strip_string (tmp, '"');

	// Only one gateway is selected
	if ((split = strstr (tmp, "\"")) != NULL)
		*split = '\0';

	if (!nm_utils_ipaddr_valid (AF_INET, tmp))
		goto error;
	return tmp;
error:
	if (!is_ip6_address (tmp))
		nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp);
	g_free (tmp);
	return NULL;
}
Ejemplo n.º 6
0
static ip_block *
create_ip_block (gchar * ip)
{
	ip_block *iblock = g_slice_new0 (ip_block);
	gchar *dup_ip = g_strdup (ip);
	gchar *prefix = NULL;

	if ((prefix = strstr (dup_ip, "/")) != NULL) {
		*prefix = '\0';
		prefix++;
	}
	if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip))
		goto error;
	iblock->ip = dup_ip;
	if (prefix) {
		errno = 0;
		iblock->prefix = strtol (prefix, NULL, 10);
		if (errno || iblock->prefix <= 0 || iblock->prefix > 128) {
			goto error;
		}
	} else
		iblock->prefix = 64;
	return iblock;
error:
	if (!is_ip4_address (ip))
		nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip);
	g_slice_free (ip_block, iblock);
	g_free (dup_ip);
	return NULL;
}
Ejemplo n.º 7
0
static gboolean
ip_gateway_from_string (GBinding     *binding,
                        const GValue *source_value,
                        GValue       *target_value,
                        gpointer      user_data)
{
	int family = GPOINTER_TO_INT (user_data);
	const char *gateway;

	gateway = g_value_get_string (source_value);
	if (gateway && !nm_utils_ipaddr_valid (family, gateway))
		gateway = NULL;

	g_value_set_string (target_value, gateway);
	return TRUE;
}
Ejemplo n.º 8
0
static gboolean
possibly_wrong_gateway (GtkTreeModel *model, GtkTreeIter *iter, const char *gw_str)
{
	char *addr_str, *prefix_str;
	gboolean addr_valid;
	guint32 prefix;

	gtk_tree_model_get (model, iter, COL_ADDRESS, &addr_str, -1);
	gtk_tree_model_get (model, iter, COL_PREFIX, &prefix_str, -1);
	addr_valid =   addr_str && *addr_str && nm_utils_ipaddr_valid (AF_INET, addr_str) && !is_address_unspecified (addr_str)
	            && parse_netmask (prefix_str, &prefix);

	if (addr_valid && !gateway_matches_address (gw_str, addr_str, prefix))
		return TRUE;
	else
		return FALSE;
}
Ejemplo n.º 9
0
static gboolean
ip_addresses_check_and_copy (GBinding     *binding,
                             const GValue *source_value,
                             GValue       *target_value,
                             gpointer      user_data)
{
	int family = GPOINTER_TO_INT (user_data);
	char **strings;
	int i;

	strings = g_value_get_boxed (source_value);

	for (i = 0; strings[i]; i++) {
		if (!nm_utils_ipaddr_valid (family, strings[i]))
			return FALSE;
	}

	g_value_set_boxed (target_value, strings);
	return TRUE;
}
Ejemplo n.º 10
0
static gboolean
parse_addr_prefix (const char  *text,
                   int          family,
                   char       **addr,
                   guint32     *prefix)
{
	const char *slash;
	char *addrstr, *end;
	gboolean valid;

	slash = strchr (text, '/');

	if (slash)
		addrstr = g_strndup (text, slash - text);
	else
		addrstr = g_strdup (text);
	valid = nm_utils_ipaddr_valid (family, addrstr);

	if (slash) {
		*prefix = strtoul (slash + 1, &end, 10);
		if (   *end
		    || *prefix == 0
		    || (family == AF_INET && *prefix > 32)
		    || (family == AF_INET6 && *prefix > 128))
			valid = FALSE;
	} else if (prefix) {
		if (family == AF_INET)
			*prefix = 32;
		else
			*prefix = 128;
	}

	if (addr && valid)
		*addr = addrstr;
	else
		g_free (addrstr);
	return valid;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
/*
 * nmc_parse_and_build_route:
 * @family: AF_INET or AF_INET6
 * @first: the route destination in the form of "address/prefix"
     (/prefix is optional)
 * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be
     either next hop address or metric. (It can be NULL when @third is NULL).
 * @third: (allow-none): route metric
 * @error: location to store GError
 *
 * Parse route from strings and return an #NMIPRoute
 *
 * Returns: %TRUE on success, %FALSE on failure
 */
NMIPRoute *
nmc_parse_and_build_route (int family,
                           const char *first,
                           const char *second,
                           const char *third,
                           GError **error)
{
	int max_prefix = (family == AF_INET) ? 32 : 128;
	char *dest = NULL, *plen = NULL;
	const char *next_hop = NULL;
	const char *canon_dest;
	long int prefix = max_prefix, metric = -1;
	NMIPRoute *route = NULL;
	gboolean success = FALSE;
	GError *local = NULL;

	g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE);
	g_return_val_if_fail (first != NULL, FALSE);
	g_return_val_if_fail (second || !third, FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

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

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

	if (second) {
		if (third || nm_utils_ipaddr_valid (family, second))
			next_hop = second;
		else {
			/* 'second' can be a metric */
			if (!nmc_string_to_int (second, TRUE, 0, G_MAXUINT32, &metric)) {
				g_set_error (error, 1, 0, _("the second component of route ('%s') is neither "
				                            "a next hop address nor a metric"), second);
				goto finish;
			}
		}
	}

	if (third) {
		if (!nmc_string_to_int (third, TRUE, 0, G_MAXUINT32, &metric)) {
			g_set_error (error, 1, 0, _("invalid metric '%s'"), third);
			goto finish;
		}
	}

	route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &local);
	if (!route) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid route: %s"), local->message);
		g_clear_error (&local);
		goto finish;
	}

	/* We don't accept default routes as NetworkManager handles it
	 * itself. But we have to check this after @route has normalized the
	 * dest string.
	 */
	canon_dest = nm_ip_route_get_dest (route);
	if (!strcmp (canon_dest, "0.0.0.0") || !strcmp (canon_dest, "::")) {
		g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		                     _("default route cannot be added (NetworkManager handles it by itself)"));
		g_clear_pointer (&route, nm_ip_route_unref);
		goto finish;
	}

	success = TRUE;

finish:
	g_free (dest);
	return route;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
	int family = AF_UNSPEC;

	switch (priv->mode) {
	case NM_IP_TUNNEL_MODE_IPIP:
	case NM_IP_TUNNEL_MODE_SIT:
	case NM_IP_TUNNEL_MODE_ISATAP:
	case NM_IP_TUNNEL_MODE_GRE:
	case NM_IP_TUNNEL_MODE_VTI:
		family = AF_INET;
		break;
	case NM_IP_TUNNEL_MODE_IP6IP6:
	case NM_IP_TUNNEL_MODE_IPIP6:
	case NM_IP_TUNNEL_MODE_IP6GRE:
	case NM_IP_TUNNEL_MODE_VTI6:
		family = AF_INET6;
		break;
	case NM_IP_TUNNEL_MODE_UNKNOWN:
		break;
	}

	if (family == AF_UNSPEC) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%d' is not a valid tunnel mode"),
		             (int) priv->mode);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE);
		return FALSE;
	}

	if (   priv->parent
	    && !nm_utils_iface_valid_name (priv->parent)
	    && !nm_utils_is_uuid (priv->parent)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is neither an UUID nor an interface name"),
		             priv->parent);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
		                NM_SETTING_IP_TUNNEL_PARENT);
		return FALSE;
	}

	if (priv->local && !nm_utils_ipaddr_valid (family, priv->local)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IPv%c address"),
		             priv->local,
		             family == AF_INET ? '4' : '6');
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL);
		return FALSE;
	}

	if (!priv->remote) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
		return FALSE;
	}

	if (!nm_utils_ipaddr_valid (family, priv->remote)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IPv%c address"),
		             priv->remote,
		             family == AF_INET ? '4' : '6');
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
		return FALSE;
	}

	if (   (priv->input_key && priv->input_key[0])
	    || (priv->output_key && priv->output_key[0])) {
		if (   priv->mode != NM_IP_TUNNEL_MODE_GRE
		    && priv->mode != NM_IP_TUNNEL_MODE_IP6GRE) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("tunnel keys can only be specified for GRE tunnels"));
			return FALSE;
		}
	}

	if (priv->input_key && priv->input_key[0]) {
		gint64 val;

		val = _nm_utils_ascii_str_to_int64 (priv->input_key, 10, 0, G_MAXUINT32, -1);
		if (val == -1) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid tunnel key"),
			             priv->input_key);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
			                NM_SETTING_IP_TUNNEL_INPUT_KEY);
		return FALSE;
		}
	}

	if (priv->output_key && priv->output_key[0]) {
		gint64 val;

		val = _nm_utils_ascii_str_to_int64 (priv->output_key, 10, 0, G_MAXUINT32, -1);
		if (val == -1) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid tunnel key"),
			             priv->output_key);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
			                NM_SETTING_IP_TUNNEL_OUTPUT_KEY);
		return FALSE;
		}
	}

	if (!priv->path_mtu_discovery && priv->ttl != 0) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("a fixed TTL is allowed only when path MTU discovery is enabled"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
		                NM_SETTING_IP_TUNNEL_TTL);
		return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 16
0
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
	int family = AF_UNSPEC;

	if (!priv->remote) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_MISSING_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_REMOTE);
		return FALSE;
	}

	if (nm_utils_ipaddr_valid (AF_INET, priv->remote))
		family = AF_INET;
	else if (nm_utils_ipaddr_valid (AF_INET6, priv->remote))
		family = AF_INET6;
	else {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IP address"),
		             priv->remote);
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_REMOTE);
		return FALSE;
	}

	if (priv->local) {
		if (!nm_utils_ipaddr_valid (family, priv->local)) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid IP%c address"),
			             priv->local, family == AF_INET ? '4' : '6');
			g_prefix_error (error, "%s.%s: ",
			                NM_SETTING_VXLAN_SETTING_NAME,
			                NM_SETTING_VXLAN_LOCAL);
			return FALSE;
		}
	}

	if (   priv->parent
	    && !nm_utils_iface_valid_name (priv->parent)
	    && !nm_utils_is_uuid (priv->parent)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is neither an UUID nor an interface name"),
		             priv->parent);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_PARENT);
		return FALSE;
	}

	if (   (priv->source_port_min || priv->source_port_max)
	    && (priv->source_port_min > priv->source_port_max)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("%d is greater than local port max %d"),
		             priv->source_port_min,
		             priv->source_port_max);
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_SOURCE_PORT_MIN);
		return FALSE;
	}

	return TRUE;
}