From a020ed21da6721e896c7eb4b84fc805e127031eb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 19 Dec 2008 17:01:06 -0500 Subject: [PATCH] Re-add WINS support to the IPv4 config Don't do anything with WINS servers (dispatcher scripts installed with samba could certainly update samba's idea of WINS servers), but at least provide them so that the VPNs that can get upstream WINS servers can at least make other stuff aware of them. --- introspection/nm-ip4-config.xml | 3 ++ libnm-glib/libnm-glib-test.c | 12 ++++- libnm-glib/libnm_glib.ver | 1 + libnm-glib/nm-ip4-config.c | 72 +++++++++++++++++++++++-- libnm-glib/nm-ip4-config.h | 12 +++-- src/dhcp-manager/nm-dhcp-manager.c | 15 ++++++ src/nm-ip4-config.c | 82 +++++++++++++++++++++++++++-- src/nm-ip4-config.h | 7 +++ src/ppp-manager/nm-ppp-manager.c | 8 +++ src/vpn-manager/nm-vpn-connection.c | 2 +- 10 files changed, 197 insertions(+), 17 deletions(-) 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);