static void static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) { NMModem *self = NM_MODEM (user_data); NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); GValueArray *ret_array = NULL; GError *error = NULL; NMIP4Config *config = NULL; priv->call = NULL; if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_VALUE_ARRAY, &ret_array, G_TYPE_INVALID)) { NMIP4Address *addr; int i; config = nm_ip4_config_new (); addr = nm_ip4_address_new (); nm_ip4_address_set_address (addr, g_value_get_uint (g_value_array_get_nth (ret_array, 0))); nm_ip4_address_set_prefix (addr, 32); nm_ip4_config_take_address (config, addr); for (i = 0; i < ret_array->n_values; i++) { GValue *value = g_value_array_get_nth (ret_array, i); nm_ip4_config_add_nameserver (config, g_value_get_uint (value)); } g_value_array_free (ret_array); } g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, NULL, config, error); g_clear_error (&error); }
/* * Parse IPv4 address from string to NMIP4Address stucture. * ip_str is the IPv4 address in the form address/prefix * gw_str is the gateway address (it is optional) */ NMIP4Address * nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error) { NMIP4Address *addr = NULL; guint32 ip4_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_INET, tmp, &ip4_addr) < 1) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid IPv4 address '%s'"), tmp); goto finish; } prefix = 32; if (plen) { if (!nmc_string_to_int (plen, TRUE, 1, 32, &prefix)) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid prefix '%s'; <1-32> allowed"), plen); goto finish; } } if (inet_pton (AF_INET, gw_str ? gw_str : "0.0.0.0", &gw_addr) < 1) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid gateway '%s'"), gw_str); goto finish; } addr = nm_ip4_address_new (); nm_ip4_address_set_address (addr, ip4_addr); nm_ip4_address_set_prefix (addr, (guint32) prefix); nm_ip4_address_set_gateway (addr, gw_addr); finish: g_free (tmp); return addr; }
/* Given a table of DHCP options from the client, convert into an IP4Config */ static NMIP4Config * ip4_options_to_config (NMDHCPClient *self) { NMDHCPClientPrivate *priv; NMIP4Config *ip4_config = NULL; struct in_addr tmp_addr; NMIP4Address *addr = NULL; char *str = NULL; guint32 gwaddr = 0, prefix = 0; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->options != NULL, NULL); ip4_config = nm_ip4_config_new (); if (!ip4_config) { nm_log_warn (LOGD_DHCP4, "(%s): couldn't allocate memory for an IP4Config!", priv->iface); return NULL; } addr = nm_ip4_address_new (); if (!addr) { nm_log_warn (LOGD_DHCP4, "(%s): couldn't allocate memory for an IP4 Address!", priv->iface); goto error; } str = g_hash_table_lookup (priv->options, "new_ip_address"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { nm_ip4_address_set_address (addr, tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " address %s", str); } else goto error; str = g_hash_table_lookup (priv->options, "new_subnet_mask"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " prefix %d (%s)", prefix, str); } else { /* Get default netmask for the IP according to appropriate class. */ prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); nm_log_info (LOGD_DHCP4, " prefix %d (default)", prefix); } nm_ip4_address_set_prefix (addr, prefix); /* Routes: if the server returns classless static routes, we MUST ignore * the 'static_routes' option. */ if (!ip4_process_classless_routes (priv->options, ip4_config, &gwaddr)) process_classful_routes (priv->options, ip4_config); if (gwaddr) { char buf[INET_ADDRSTRLEN + 1]; inet_ntop (AF_INET, &gwaddr, buf, sizeof (buf)); nm_log_info (LOGD_DHCP4, " gateway %s", buf); nm_ip4_address_set_gateway (addr, gwaddr); } else { /* If the gateway wasn't provided as a classless static route with a * subnet length of 0, try to find it using the old-style 'routers' option. */ str = g_hash_table_lookup (priv->options, "new_routers"); if (str) { char **routers = g_strsplit (str, " ", 0); char **s; for (s = routers; *s; s++) { /* FIXME: how to handle multiple routers? */ if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { nm_ip4_address_set_gateway (addr, tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " gateway %s", *s); break; } else nm_log_warn (LOGD_DHCP4, "ignoring invalid gateway '%s'", *s); } g_strfreev (routers); } } nm_ip4_config_take_address (ip4_config, addr); addr = NULL; str = g_hash_table_lookup (priv->options, "new_host_name"); if (str) nm_log_info (LOGD_DHCP4, " hostname '%s'", str); str = g_hash_table_lookup (priv->options, "new_domain_name_servers"); if (str) { char **searches = g_strsplit (str, " ", 0); char **s; for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { nm_ip4_config_add_nameserver (ip4_config, tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " nameserver '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid nameserver '%s'", *s); } g_strfreev (searches); } str = g_hash_table_lookup (priv->options, "new_domain_name"); if (str) { char **domains = g_strsplit (str, " ", 0); char **s; for (s = domains; *s; s++) { nm_log_info (LOGD_DHCP4, " domain name '%s'", *s); nm_ip4_config_add_domain (ip4_config, *s); } g_strfreev (domains); } str = g_hash_table_lookup (priv->options, "new_domain_search"); if (str) process_domain_search (str, ip4_add_domain_search, ip4_config); str = g_hash_table_lookup (priv->options, "new_netbios_name_servers"); if (str) { char **searches = g_strsplit (str, " ", 0); char **s; for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { nm_ip4_config_add_wins (ip4_config, tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " wins '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid WINS server '%s'", *s); } g_strfreev (searches); } str = g_hash_table_lookup (priv->options, "new_interface_mtu"); if (str) { int int_mtu; errno = 0; int_mtu = strtol (str, NULL, 10); if ((errno == EINVAL) || (errno == ERANGE)) goto error; if (int_mtu > 576) nm_ip4_config_set_mtu (ip4_config, int_mtu); } str = g_hash_table_lookup (priv->options, "new_nis_domain"); if (str) { nm_log_info (LOGD_DHCP4, " NIS domain '%s'", str); nm_ip4_config_set_nis_domain (ip4_config, str); } str = g_hash_table_lookup (priv->options, "new_nis_servers"); if (str) { char **searches = g_strsplit (str, " ", 0); char **s; for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { nm_ip4_config_add_nis_server (ip4_config, tmp_addr.s_addr); nm_log_info (LOGD_DHCP4, " nis '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid NIS server '%s'", *s); } g_strfreev (searches); } return ip4_config; error: if (addr) nm_ip4_address_unref (addr); g_object_unref (ip4_config); return NULL; }
static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config_hash, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); NMConnection *connection; NMSettingPPP *s_ppp; NMIP4Config *config; NMIP4Address *addr; GValue *val; int i; nm_log_info (LOGD_PPP, "PPP manager(IP Config Get) reply received."); remove_timeout_handler (manager); config = nm_ip4_config_new (); addr = nm_ip4_address_new (); nm_ip4_address_set_prefix (addr, 32); val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_GATEWAY); if (val) { nm_ip4_address_set_gateway (addr, g_value_get_uint (val)); nm_ip4_config_set_ptp_address (config, g_value_get_uint (val)); } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_ADDRESS); if (val) nm_ip4_address_set_address (addr, g_value_get_uint (val)); val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_PREFIX); if (val) nm_ip4_address_set_prefix (addr, g_value_get_uint (val)); if (nm_ip4_address_get_address (addr) && nm_ip4_address_get_prefix (addr)) { nm_ip4_config_take_address (config, addr); } else { nm_log_err (LOGD_PPP, "invalid IPv4 address received!"); nm_ip4_address_unref (addr); goto out; } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_DNS); if (val) { GArray *dns = (GArray *) g_value_get_boxed (val); for (i = 0; i < dns->len; i++) nm_ip4_config_add_nameserver (config, g_array_index (dns, guint, i)); } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_WINS); if (val) { GArray *wins = (GArray *) g_value_get_boxed (val); for (i = 0; i < wins->len; i++) nm_ip4_config_add_wins (config, g_array_index (wins, guint, i)); } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_INTERFACE); if (!val || !G_VALUE_HOLDS_STRING (val)) { nm_log_err (LOGD_PPP, "no interface received!"); goto out; } priv->ip_iface = g_value_dup_string (val); /* Got successful IP4 config; obviously the secrets worked */ connection = nm_act_request_get_connection (priv->act_req); g_assert (connection); g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); /* Merge in custom MTU */ s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); if (s_ppp) { guint32 mtu = nm_setting_ppp_get_mtu (s_ppp); if (mtu) nm_ip4_config_set_mtu (config, mtu); } /* Push the IP4 config up to the device */ g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); monitor_stats (manager); out: g_object_unref (config); return TRUE; }