예제 #1
0
/*
 * Parse IPv6 route from strings to NMIP6Route stucture.
 * ip_str is the IPv6 route in the form address/prefix
 * next_hop_str is the next hop
 * metric_str is the route metric
 */
NMIP6Route *
nmc_parse_and_build_ip6_route (const char *ip_str, const char *next_hop_str, const char *metric_str, GError **error)
{
	NMIP6Route *route = NULL;
	struct in6_addr ip_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 (error == NULL || *error == NULL, NULL);

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

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

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

	if (inet_pton (AF_INET6, 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, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
			             _("invalid metric '%s'"), metric_str);
			goto finish;
		}
	}

	route = nm_ip6_route_new ();
	nm_ip6_route_set_dest (route, &ip_addr);
	nm_ip6_route_set_prefix (route, (guint32) prefix);
	nm_ip6_route_set_next_hop (route, &next_hop_addr);
	nm_ip6_route_set_metric (route, (guint32) metric);

finish:
	g_free (tmp);
	return route;
}
예제 #2
0
/*
 * Parse IPv6 address from string to NMIP6Address stucture.
 * ip_str is the IPv6 address in the form address/prefix
 * gw_str is the gateway address (it is optional)
 */
NMIP6Address *
nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error)
{
	NMIP6Address *addr = NULL;
	struct in6_addr ip_addr, gw_addr;
	char *tmp;
	char *plen;
	long int prefix;

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

	if (inet_pton (AF_INET6, tmp, &ip_addr) < 1) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid IPv6 address '%s'"), tmp);
		goto finish;
	}

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

	if (inet_pton (AF_INET6, gw_str ? gw_str : "::", &gw_addr) < 1) {
		g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
		             _("invalid gateway '%s'"), gw_str);
		goto finish;
	}

	addr = nm_ip6_address_new ();
	nm_ip6_address_set_address (addr, &ip_addr);
	nm_ip6_address_set_prefix (addr, (guint32) prefix);
	nm_ip6_address_set_gateway (addr, &gw_addr);

finish:
	g_free (tmp);
	return addr;
}
예제 #3
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;
}
예제 #4
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;
}