From 0d94cc8824ede1a2024580eaed73fcd7d88dcdab 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 | 10 ++++ libnm-glib/libnm_glib.ver | 1 + libnm-glib/nm-ip4-config.c | 62 ++++++++++++++++++++++ libnm-glib/nm-ip4-config.h | 2 + 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, 187 insertions(+), 5 deletions(-) diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml index 1203672785..57ce29529d 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 bf9c76cb62..ed296015cf 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -128,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 8dd6c72eab..6336c86df5 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 d4c791faf7..9c4e5497be 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -41,6 +41,7 @@ typedef struct { GArray *nameservers; GPtrArray *domains; GSList *routes; + GArray *wins; } NMIP4ConfigPrivate; enum { @@ -50,6 +51,7 @@ enum { PROP_NAMESERVERS, PROP_DOMAINS, PROP_ROUTES, + PROP_WINS_SERVERS, LAST_PROP }; @@ -82,6 +84,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; } @@ -119,6 +124,7 @@ register_for_property_changed (NMIP4Config *config) { 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 }, }; @@ -169,6 +175,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); @@ -204,6 +213,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; @@ -286,6 +298,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)); } /** @@ -389,6 +414,7 @@ nm_ip4_config_get_nameservers (NMIP4Config *config) return priv->nameservers; } + /** * nm_ip4_config_get_domains: * @config: a #NMIP4Config @@ -428,6 +454,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 7807d98dbf..6849c44ba1 100644 --- a/libnm-glib/nm-ip4-config.h +++ b/libnm-glib/nm-ip4-config.h @@ -51,6 +51,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); @@ -61,6 +62,7 @@ const char * nm_ip4_config_get_hostname (NMIP4Config *config); /* DEPRECA 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 e5535a346b..f29fad33db 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -841,6 +841,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 4caeb1508d..b9c2df7e4b 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 2e9de5095b..1c435adb60 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 0a9c951ce2..19dc36d50a 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 693ef44db6..66a252cdec 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);