diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml index 120367278..57ce29529 100644 --- a/introspection/nm-ip4-config.xml +++ b/introspection/nm-ip4-config.xml @@ -8,6 +8,9 @@ The nameservers in use. + + The Windows Internet Name Service servers associated with the connection. + A list of domains this address belongs to. diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index 6b1f7d237..ed296015c 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -112,8 +112,6 @@ dump_ip4_config (NMIP4Config *cfg) g_free (tmp); } - g_print ("IP4 hostname: %s\n", nm_ip4_config_get_hostname (cfg)); - array = nm_ip4_config_get_nameservers (cfg); if (array) { g_print ("IP4 DNS:\n"); @@ -130,6 +128,16 @@ dump_ip4_config (NMIP4Config *cfg) for (i = 0; i < ptr_array->len; i++) g_print ("\t%s\n", (const char *) g_ptr_array_index (ptr_array, i)); } + + array = nm_ip4_config_get_wins_servers (cfg); + if (array) { + g_print ("IP4 WINS:\n"); + for (i = 0; i < array->len; i++) { + tmp = ip4_address_as_string (g_array_index (array, guint32, i)); + g_print ("\t%s\n", tmp); + g_free (tmp); + } + } } static void diff --git a/libnm-glib/libnm_glib.ver b/libnm-glib/libnm_glib.ver index 8dd6c72ea..6336c86df 100644 --- a/libnm-glib/libnm_glib.ver +++ b/libnm-glib/libnm_glib.ver @@ -94,6 +94,7 @@ global: nm_ip4_config_get_domains; nm_ip4_config_get_hostname; nm_ip4_config_get_nameservers; + nm_ip4_config_get_wins_servers; nm_ip4_config_get_routes; nm_ip4_config_get_type; nm_ip4_config_new; diff --git a/libnm-glib/nm-ip4-config.c b/libnm-glib/nm-ip4-config.c index 3af0f8d71..9ab1607b8 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -42,6 +42,7 @@ typedef struct { GArray *nameservers; GPtrArray *domains; GSList *routes; + GArray *wins; } NMIP4ConfigPrivate; enum { @@ -51,6 +52,7 @@ enum { PROP_NAMESERVERS, PROP_DOMAINS, PROP_ROUTES, + PROP_WINS_SERVERS, LAST_PROP }; @@ -83,6 +85,9 @@ demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointe if (!strcmp (pspec->name, NM_IP4_CONFIG_NAMESERVERS)) _nm_object_queue_notify (object, NM_IP4_CONFIG_NAMESERVERS); + else if (!strcmp (pspec->name, NM_IP4_CONFIG_WINS_SERVERS)) + _nm_object_queue_notify (object, NM_IP4_CONFIG_WINS_SERVERS); + return TRUE; } @@ -116,11 +121,12 @@ register_for_property_changed (NMIP4Config *config) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); const NMPropertiesChangedInfo property_changed_info[] = { - { NM_IP4_CONFIG_ADDRESSES, demarshal_ip4_address_array, &priv->addresses }, - { NM_IP4_CONFIG_HOSTNAME, _nm_object_demarshal_generic, &priv->hostname }, - { NM_IP4_CONFIG_NAMESERVERS, demarshal_ip4_array, &priv->nameservers }, - { NM_IP4_CONFIG_DOMAINS, demarshal_domains, &priv->domains }, - { NM_IP4_CONFIG_ROUTES, demarshal_ip4_routes_array, &priv->routes }, + { NM_IP4_CONFIG_ADDRESSES, demarshal_ip4_address_array, &priv->addresses }, + { NM_IP4_CONFIG_HOSTNAME, _nm_object_demarshal_generic, &priv->hostname }, + { NM_IP4_CONFIG_NAMESERVERS, demarshal_ip4_array, &priv->nameservers }, + { NM_IP4_CONFIG_DOMAINS, demarshal_domains, &priv->domains }, + { NM_IP4_CONFIG_ROUTES, demarshal_ip4_routes_array, &priv->routes }, + { NM_IP4_CONFIG_WINS_SERVERS, demarshal_ip4_array, &priv->wins }, { NULL }, }; @@ -172,6 +178,9 @@ finalize (GObject *object) if (priv->nameservers) g_array_free (priv->nameservers, TRUE); + if (priv->wins) + g_array_free (priv->wins, TRUE); + if (priv->domains) { g_ptr_array_foreach (priv->domains, (GFunc) g_free, NULL); g_ptr_array_free (priv->domains, TRUE); @@ -207,6 +216,9 @@ get_property (GObject *object, case PROP_ROUTES: nm_utils_ip4_routes_to_gvalue (priv->routes, value); break; + case PROP_WINS_SERVERS: + g_value_set_boxed (value, nm_ip4_config_get_wins_servers (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -289,6 +301,19 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) "Routes", "Routes", G_PARAM_READABLE)); + + /** + * NMIP4Config:wins-servers: + * + * The #GArray containing WINS servers (%guint32es) of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_WINS_SERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, + "WINS Servers", + "WINS Servers", + NM_TYPE_UINT_ARRAY, + G_PARAM_READABLE)); } /** @@ -404,6 +429,7 @@ nm_ip4_config_get_nameservers (NMIP4Config *config) return priv->nameservers; } + /** * nm_ip4_config_get_domains: * @config: a #NMIP4Config @@ -443,6 +469,42 @@ nm_ip4_config_get_domains (NMIP4Config *config) return handle_ptr_array_return (priv->domains); } +/** + * nm_ip4_config_get_wins_servers: + * @config: a #NMIP4Config + * + * Gets the Windows Internet Name Service servers (WINS). + * + * Returns: the #GArray containing %guint32s. This is the internal copy used by the + * configuration and must not be modified. + **/ +const GArray * +nm_ip4_config_get_wins_servers (NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv; + GArray *array = NULL; + GValue value = {0,}; + + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->nameservers) { + if (_nm_object_get_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Nameservers", + &value)) { + array = (GArray *) g_value_get_boxed (&value); + if (array && array->len) { + priv->nameservers = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len); + g_array_append_vals (priv->nameservers, array->data, array->len); + } + g_value_unset (&value); + } + } + + return priv->nameservers; +} + /** * nm_ip4_config_get_routes: * @config: a #NMIP4Config diff --git a/libnm-glib/nm-ip4-config.h b/libnm-glib/nm-ip4-config.h index c8dbe1984..cc9f36455 100644 --- a/libnm-glib/nm-ip4-config.h +++ b/libnm-glib/nm-ip4-config.h @@ -51,16 +51,18 @@ typedef struct { #define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_ROUTES "routes" +#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" GType nm_ip4_config_get_type (void); GObject *nm_ip4_config_new (DBusGConnection *connection, const char *object_path); -const GSList * nm_ip4_config_get_addresses (NMIP4Config *config); -const char * nm_ip4_config_get_hostname (NMIP4Config *config); -const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config); -const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config); -const GSList * nm_ip4_config_get_routes (NMIP4Config *config); +const GSList * nm_ip4_config_get_addresses (NMIP4Config *config); +const char * nm_ip4_config_get_hostname (NMIP4Config *config); +const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config); +const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config); +const GSList * nm_ip4_config_get_routes (NMIP4Config *config); +const GArray * nm_ip4_config_get_wins_servers (NMIP4Config *config); G_END_DECLS diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 6de7ac289..9caeacada 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -840,6 +840,21 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, g_strfreev (searches); } + str = g_hash_table_lookup (device->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_info (" wins '%s'", *s); + } else + nm_warning ("Ignoring invalid WINS server '%s'", *s); + } + g_strfreev (searches); + } + str = g_hash_table_lookup (device->options, "new_static_routes"); if (str) { char **searches = g_strsplit (str, " ", 0); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 4caeb1508..b9c2df7e4 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -54,6 +54,8 @@ typedef struct { GPtrArray *domains; GPtrArray *searches; + GArray *wins; + GSList *routes; gboolean never_default; @@ -66,6 +68,7 @@ enum { PROP_NAMESERVERS, PROP_DOMAINS, PROP_ROUTES, + PROP_WINS_SERVERS, LAST_PROP }; @@ -179,10 +182,21 @@ void nm_ip4_config_set_ptp_address (NMIP4Config *config, guint32 ptp_addr) void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver) { - g_return_if_fail (NM_IS_IP4_CONFIG (config)); + NMIP4ConfigPrivate *priv; + int i; - if (nameserver != 0) - g_array_append_val (NM_IP4_CONFIG_GET_PRIVATE (config)->nameservers, nameserver); + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + g_return_if_fail (nameserver > 0); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + for (i = 0; i < priv->nameservers->len; i++) { + guint32 s = g_array_index (priv->nameservers, guint32, i); + + /* No dupes */ + g_return_if_fail (nameserver != s); + } + + g_array_append_val (priv->nameservers, nameserver); } guint32 nm_ip4_config_get_nameserver (NMIP4Config *config, guint i) @@ -210,6 +224,50 @@ void nm_ip4_config_reset_nameservers (NMIP4Config *config) g_array_remove_range (priv->nameservers, 0, priv->nameservers->len); } +void nm_ip4_config_add_wins (NMIP4Config *config, guint32 wins) +{ + NMIP4ConfigPrivate *priv; + int i; + + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + g_return_if_fail (wins > 0); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + for (i = 0; i < priv->wins->len; i++) { + guint32 s = g_array_index (priv->wins, guint32, i); + + /* No dupes */ + g_return_if_fail (wins != s); + } + + g_array_append_val (priv->wins, wins); +} + +guint32 nm_ip4_config_get_wins (NMIP4Config *config, guint i) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); + + return g_array_index (NM_IP4_CONFIG_GET_PRIVATE (config)->wins, guint32, i); +} + +guint32 nm_ip4_config_get_num_wins (NMIP4Config *config) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); + + return NM_IP4_CONFIG_GET_PRIVATE (config)->wins->len; +} + +void nm_ip4_config_reset_wins (NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv; + + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (priv->wins->len) + g_array_remove_range (priv->wins, 0, priv->wins->len); +} + void nm_ip4_config_take_route (NMIP4Config *config, NMIP4Route *route) { @@ -589,6 +647,11 @@ nm_ip4_config_diff (NMIP4Config *a, NMIP4Config *b) || !addr_array_compare (b_priv->nameservers, a_priv->nameservers)) flags |= NM_IP4_COMPARE_FLAG_NAMESERVERS; + if ( (a_priv->wins->len != b_priv->wins->len) + || !addr_array_compare (a_priv->wins, b_priv->wins) + || !addr_array_compare (b_priv->wins, a_priv->wins)) + flags |= NM_IP4_COMPARE_FLAG_WINS_SERVERS; + if ( !route_slist_compare (a_priv->routes, b_priv->routes) || !route_slist_compare (b_priv->routes, a_priv->routes)) flags |= NM_IP4_COMPARE_FLAG_ROUTES; @@ -618,6 +681,7 @@ nm_ip4_config_init (NMIP4Config *config) NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); priv->nameservers = g_array_new (FALSE, TRUE, sizeof (guint32)); + priv->wins = g_array_new (FALSE, TRUE, sizeof (guint32)); priv->domains = g_ptr_array_new (); priv->searches = g_ptr_array_new (); } @@ -629,6 +693,7 @@ finalize (GObject *object) nm_utils_slist_free (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); nm_utils_slist_free (priv->routes, (GDestroyNotify) nm_ip4_route_unref); + g_array_free (priv->wins, TRUE); g_array_free (priv->nameservers, TRUE); g_ptr_array_free (priv->domains, TRUE); g_ptr_array_free (priv->searches, TRUE); @@ -653,6 +718,9 @@ get_property (GObject *object, guint prop_id, case PROP_ROUTES: nm_utils_ip4_routes_to_gvalue (priv->routes, value); break; + case PROP_WINS_SERVERS: + g_value_set_boxed (value, priv->wins); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -692,7 +760,6 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) "Domains", DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_ROUTES, g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, @@ -700,6 +767,13 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) "Routes", DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_WINS_SERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, + "WinsServers", + "WINS server list", + DBUS_TYPE_G_UINT_ARRAY, + G_PARAM_READABLE)); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class), &dbus_glib_nm_ip4_config_object_info); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 2e9de5095..1c435adb6 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -45,6 +45,7 @@ typedef struct { #define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_ROUTES "routes" +#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" GType nm_ip4_config_get_type (void); @@ -67,6 +68,11 @@ guint32 nm_ip4_config_get_nameserver (NMIP4Config *config, guint i); guint32 nm_ip4_config_get_num_nameservers (NMIP4Config *config); void nm_ip4_config_reset_nameservers (NMIP4Config *config); +void nm_ip4_config_add_wins (NMIP4Config *config, guint32 wins); +guint32 nm_ip4_config_get_wins (NMIP4Config *config, guint i); +guint32 nm_ip4_config_get_num_wins (NMIP4Config *config); +void nm_ip4_config_reset_wins (NMIP4Config *config); + void nm_ip4_config_take_route (NMIP4Config *config, NMIP4Route *route); void nm_ip4_config_add_route (NMIP4Config *config, NMIP4Route *route); void nm_ip4_config_replace_route (NMIP4Config *config, guint32 i, NMIP4Route *new_route); @@ -114,6 +120,7 @@ typedef enum { NM_IP4_COMPARE_FLAG_SEARCHES = 0x00000020, NM_IP4_COMPARE_FLAG_MTU = 0x00000040, NM_IP4_COMPARE_FLAG_MSS = 0x00000080, + NM_IP4_COMPARE_FLAG_WINS_SERVERS= 0x00000100, NM_IP4_COMPARE_FLAG_ALL = 0xFFFFFFFF /* match everything */ } NMIP4ConfigCompareFlags; diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 0a9c951ce..19dc36d50 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -508,6 +508,14 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, 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_warning ("No interface"); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 693ef44db..66a252cde 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -455,7 +455,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, GArray *nbns = (GArray *) g_value_get_boxed (val); for (i = 0; i < nbns->len; i++) - nm_ip4_config_add_nameserver (config, g_array_index (nbns, guint, i)); + nm_ip4_config_add_wins (config, g_array_index (nbns, guint, i)); } val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_MSS);