Пример #1
0
/*
 * Parse IPv4 routes from strings to NMIP4Route stucture.
 * ip_str is the IPv4 route in the form of address/prefix
 * next_hop_str is the next_hop address
 * metric_str is the route metric
 */
NMIP4Route *
nmc_parse_and_build_ip4_route (const char *ip_str, const char *next_hop_str, const char *metric_str, GError **error)
{
	NMIP4Route *route = NULL;
	guint32 ip4_addr, next_hop_addr;
	char *tmp;
	char *plen;
	long int prefix, metric;

	g_return_val_if_fail (ip_str != NULL, NULL);
	g_return_val_if_fail (next_hop_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';

	if (inet_pton (AF_INET, tmp, &ip4_addr) < 1) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid IPv4 route '%s'"), tmp);
		goto finish;
	}

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

	if (inet_pton (AF_INET, next_hop_str, &next_hop_addr) < 1) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid next hop address '%s'"), next_hop_str);
		goto finish;
	}

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

	route = nm_ip4_route_new ();
	nm_ip4_route_set_dest (route, ip4_addr);
	nm_ip4_route_set_prefix (route, (guint32) prefix);
	nm_ip4_route_set_next_hop (route, next_hop_addr);
	nm_ip4_route_set_metric (route, (guint32) metric);

finish:
	g_free (tmp);
	return route;
}
static void
process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
{
	const char *str;
	char **searches, **s;

	str = g_hash_table_lookup (options, "new_static_routes");
	if (!str)
		return;

	searches = g_strsplit (str, " ", 0);
	if ((g_strv_length (searches) % 2)) {
		nm_log_info (LOGD_DHCP, "  static routes provided, but invalid");
		goto out;
	}

	for (s = searches; *s; s += 2) {
		NMIP4Route *route;
		struct in_addr rt_addr;
		struct in_addr rt_route;

		if (inet_pton (AF_INET, *s, &rt_addr) <= 0) {
			nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route address: '%s'", *s);
			continue;
		}
		if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) {
			nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route gateway: '%s'", *(s + 1));
			continue;
		}

		// FIXME: ensure the IP addresse and route are sane

		route = nm_ip4_route_new ();
		nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
		nm_ip4_route_set_prefix (route, 32); /* 255.255.255.255 */
		nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);

		nm_ip4_config_take_route (ip4_config, route);
		nm_log_info (LOGD_DHCP, "  static route %s gw %s", *s, *(s + 1));
	}

out:
	g_strfreev (searches);
}
static gboolean
ip4_process_dhcpcd_rfc3442_routes (const char *str,
                                   NMIP4Config *ip4_config,
                                   guint32 *gwaddr)
{
	char **routes, **r;
	gboolean have_routes = FALSE;

	routes = g_strsplit (str, " ", 0);
	if (g_strv_length (routes) == 0)
		goto out;

	if ((g_strv_length (routes) % 2) != 0) {
		nm_log_warn (LOGD_DHCP4, "  classless static routes provided, but invalid");
		goto out;
	}

	for (r = routes; *r; r += 2) {
		char *slash;
		NMIP4Route *route;
		int rt_cidr = 32;
		struct in_addr rt_addr;
		struct in_addr rt_route;

		slash = strchr(*r, '/');
		if (slash) {
			*slash = '\0';
			errno = 0;
			rt_cidr = strtol (slash + 1, NULL, 10);
			if ((errno == EINVAL) || (errno == ERANGE)) {
				nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1);
				continue;
			}
		}
		if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
			nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r);
			continue;
		}
		if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
			nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
			continue;
		}

		have_routes = TRUE;
		if (rt_cidr == 0 && rt_addr.s_addr == 0) {
			/* FIXME: how to handle multiple routers? */
			*gwaddr = rt_route.s_addr;
		} else {
			route = nm_ip4_route_new ();
			nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
			nm_ip4_route_set_prefix (route, rt_cidr);
			nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);

			nm_ip4_config_take_route (ip4_config, route);
			nm_log_info (LOGD_DHCP4, "  classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
		}
	}

out:
	g_strfreev (routes);
	return have_routes;
}
Пример #4
0
void
ip4_routes_dialog_update_setting (GtkWidget *dialog, NMSettingIP4Config *s_ip4)
{
	GtkBuilder *builder;
	GtkWidget *widget;
	GtkTreeModel *model;
	GtkTreeIter tree_iter;
	gboolean iter_valid;

	g_return_if_fail (dialog != NULL);
	g_return_if_fail (s_ip4 != NULL);

	builder = g_object_get_data (G_OBJECT (dialog), "builder");
	g_return_if_fail (builder != NULL);
	g_return_if_fail (GTK_IS_BUILDER (builder));

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_routes"));
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
	iter_valid = gtk_tree_model_get_iter_first (model, &tree_iter);

	nm_setting_ip4_config_clear_routes (s_ip4);

	while (iter_valid) {
		guint32 addr = 0, prefix = 0, next_hop = 0, metric = 0;
		NMIP4Route *route;

		/* Address */
		if (!get_one_addr (model, &tree_iter, COL_ADDRESS, TRUE, &addr)) {
			g_warning ("%s: IPv4 address missing or invalid!", __func__);
			goto next;
		}

		/* Prefix */
		if (!get_one_prefix (model, &tree_iter, COL_PREFIX, TRUE, &prefix)) {
			g_warning ("%s: IPv4 prefix/netmask missing or invalid!", __func__);
			goto next;
		}

		/* Next hop (optional) */
		if (!get_one_addr (model, &tree_iter, COL_NEXT_HOP, FALSE, &next_hop)) {
			g_warning ("%s: IPv4 next hop invalid!", __func__);
			goto next;
		}

		/* Metric (optional) */
		if (!get_one_int (model, &tree_iter, COL_METRIC, G_MAXUINT32, FALSE, &metric)) {
			g_warning ("%s: IPv4 metric invalid!", __func__);
			goto next;
		}

		route = nm_ip4_route_new ();
		nm_ip4_route_set_dest (route, addr);
		nm_ip4_route_set_prefix (route, prefix);
		nm_ip4_route_set_next_hop (route, next_hop);
		nm_ip4_route_set_metric (route, metric);
		nm_setting_ip4_config_add_route (s_ip4, route);
		nm_ip4_route_unref (route);

	next:
		iter_valid = gtk_tree_model_iter_next (model, &tree_iter);
	}

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_ignore_auto_routes"));
	g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES,
	              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
	              NULL);

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_never_default"));
	g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT,
	              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
	              NULL);
}