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