static gboolean ip_addresses_with_prefix_from_strv (GBinding *binding, const GValue *source_value, GValue *target_value, gpointer user_data) { int family = GPOINTER_TO_INT (user_data); char **strings; GPtrArray *addrs; NMIPAddress *addr; char *addrstr; guint32 prefix; int i; strings = g_value_get_boxed (source_value); /* Fetch the original property value, so as to preserve their extra attributes */ g_object_get (g_binding_get_source (binding), g_binding_get_source_property (binding), &addrs, NULL); for (i = 0; strings[i]; i++) { if (i >= addrs->len) { if (family == AF_INET) addr = nm_ip_address_new (AF_INET, "0.0.0.0", 32, NULL); else addr = nm_ip_address_new (AF_INET6, "::", 128, NULL); g_ptr_array_add (addrs, addr); } else addr = addrs->pdata[i]; if (!parse_addr_prefix (strings[i], family, &addrstr, &prefix)) { g_ptr_array_unref (addrs); return FALSE; } nm_ip_address_set_address (addr, addrstr); nm_ip_address_set_prefix (addr, prefix); g_free (addrstr); } g_ptr_array_set_size (addrs, i); g_value_take_boxed (target_value, addrs); return TRUE; }
/* * 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; }
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; }
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; }
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; }