diff --git a/ChangeLog b/ChangeLog index 40ac959397..5796718881 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2008-07-17 Dan Williams + + * introspection/Makefile.am + introspection/nm-device.xml + introspection/nm-dhcp4-config.xml + - Add bits for the DHCP4Config property of the device, and the DHCP4Config + itself + * src/nm-device-interface.c + src/nm-device-interface.h + - Add the DHCP4Config property + + * src/nm-device.c + - Keep track of DHCP4 options via a new DHCP4Config property and notify + D-Bus clients when it changes + + * src/nm-dhcp4-config.c + src/nm-dhcp4-config.h + - Simple object to store DHCP4 options, export them over D-Bus, and + notify when they change + + * src/dhcp-manager/nm-dhcp-manager.c + src/dhcp-manager/nm-dhcp-manager.h + - (nm_dhcp_manager_set_dhcp4_config, copy_dhcp4_config_option): copy and + filter server-returned DHCP options into an NMDHCP4Config object + 2008-07-16 Dan Williams * introspection/nm-device.xml diff --git a/introspection/Makefile.am b/introspection/Makefile.am index da4927ea6e..2ac5804f13 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -15,5 +15,6 @@ EXTRA_DIST = \ nm-vpn-plugin.xml \ nm-vpn-connection.xml \ nm-ppp-manager.xml \ - nm-active-connection.xml + nm-active-connection.xml \ + nm-dhcp4-config.xml diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 392a77f950..eb545a3c68 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -37,6 +37,11 @@ Object path of the Ip4Config object describing the configuration of the device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state. + + + Object path of the Dhcp4Config object describing the DHCP options returned by the DHCP server. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state. + + Whether or not this device is managed by NetworkManager. diff --git a/introspection/nm-dhcp4-config.xml b/introspection/nm-dhcp4-config.xml new file mode 100644 index 0000000000..c0821ada97 --- /dev/null +++ b/introspection/nm-dhcp4-config.xml @@ -0,0 +1,20 @@ + + + + + + Options and configuration returned by the IPv4 DHCP server. + + + Configuration options returned by a DHCP server, if any. + + + + + + A dictionary mapping property names to variant boxed values + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index bdce5d6aef..91dd0d0e35 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,7 +68,9 @@ NetworkManager_SOURCES = \ wpa.c \ wpa.h \ nm-netlink.c \ - nm-netlink.h + nm-netlink.h \ + nm-dhcp4-config.c \ + nm-dhcp4-config.h nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $< @@ -100,6 +102,9 @@ nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml nm-active-connection-glue.h: $(top_srcdir)/introspection/nm-active-connection.xml dbus-binding-tool --prefix=nm_active_connection --mode=glib-server --output=$@ $< +nm-dhcp4-config-glue.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml + dbus-binding-tool --prefix=nm_dhcp4_config --mode=glib-server --output=$@ $< + BUILT_SOURCES = \ nm-access-point-glue.h \ nm-manager-glue.h \ @@ -110,7 +115,8 @@ BUILT_SOURCES = \ nm-cdma-device-glue.h \ nm-gsm-device-glue.h \ nm-ip4-config-glue.h \ - nm-active-connection-glue.h + nm-active-connection-glue.h \ + nm-dhcp4-config-glue.h NetworkManager_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 2a00788e4a..4846bf1044 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -881,3 +881,67 @@ error: return NULL; } + +#define NEW_TAG "new_" +#define OLD_TAG "old_" + +static void +copy_dhcp4_config_option (gpointer key, + gpointer value, + gpointer user_data) +{ + NMDHCP4Config *config = NM_DHCP4_CONFIG (user_data); + char *tmp_key = NULL; + const char **p; + static const char *filter_options[] = { + "interface", "pid", "reason", NULL + }; + + /* Filter out stuff that's not actually new DHCP options */ + for (p = filter_options; *p; p++) { + if (!strcmp (*p, (const char *) key)) + return; + if (!strncmp ((const char *) key, OLD_TAG, strlen (OLD_TAG))) + return; + } + + /* Remove the "new_" prefix that dhclient passes back */ + if (!strncmp ((const char *) key, NEW_TAG, strlen (NEW_TAG))) + tmp_key = g_strdup ((const char *) (key + strlen (NEW_TAG))); + else + tmp_key = g_strdup ((const char *) key); + + nm_dhcp4_config_add_option (config, tmp_key, (const char *) value); + g_free (tmp_key); +} + +gboolean +nm_dhcp_manager_set_dhcp4_config (NMDHCPManager *self, + const char *iface, + NMDHCP4Config *config) +{ + NMDHCPManagerPrivate *priv; + NMDHCPDevice *device; + + g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), FALSE); + g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (config != NULL, FALSE); + + priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + + device = (NMDHCPDevice *) g_hash_table_lookup (priv->devices, iface); + if (!device) { + nm_warning ("Device '%s' transaction not started.", iface); + return FALSE; + } + + if (!state_is_bound (device->state)) { + nm_warning ("%s: dhclient didn't bind to a lease.", device->iface); + return FALSE; + } + + nm_dhcp4_config_reset (config); + g_hash_table_foreach (device->options, copy_dhcp4_config_option, config); + return TRUE; +} + diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index 68f8f0a541..1471479887 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -27,6 +27,7 @@ #include #include "nm-ip4-config.h" +#include "nm-dhcp4-config.h" #define NM_DHCP_MANAGER_RUN_DIR LOCALSTATEDIR "/run" @@ -94,6 +95,10 @@ void nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager, NMIP4Config * nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, const char *iface); NMDHCPState nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, const char *iface); +gboolean nm_dhcp_manager_set_dhcp4_config (NMDHCPManager *manager, + const char *iface, + NMDHCP4Config *config); + gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *message); gboolean nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4); diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index 49b4c97fbf..0ae1b974a5 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -3,7 +3,6 @@ #include "nm-marshal.h" #include "nm-setting-connection.h" #include "nm-device-interface.h" -#include "nm-ip4-config.h" #include "nm-utils.h" #include "nm-device-interface-glue.h" @@ -97,6 +96,14 @@ nm_device_interface_init (gpointer g_iface) G_TYPE_OBJECT, G_PARAM_READWRITE)); + g_object_interface_install_property + (g_iface, + g_param_spec_object (NM_DEVICE_INTERFACE_DHCP4_CONFIG, + "DHCP4 Config", + "DHCP4 Config", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); + g_object_interface_install_property (g_iface, g_param_spec_uint (NM_DEVICE_INTERFACE_STATE, diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index c6572180fb..ac9972fa63 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -27,6 +27,7 @@ typedef enum #define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" #define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" #define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_INTERFACE_STATE "state" #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ #define NM_DEVICE_INTERFACE_MANAGED "managed" @@ -40,6 +41,7 @@ typedef enum { NM_DEVICE_INTERFACE_PROP_CAPABILITIES, NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS, NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, + NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG, NM_DEVICE_INTERFACE_PROP_STATE, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_PROP_MANAGED, diff --git a/src/nm-device.c b/src/nm-device.c index dd1f48a2f4..049bf6b0bd 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -48,6 +48,7 @@ #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" #include "nm-dnsmasq-manager.h" +#include "nm-dhcp4-config.h" #define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config" @@ -90,6 +91,7 @@ struct _NMDevicePrivate NMDHCPManager * dhcp_manager; gulong dhcp_state_sigid; gulong dhcp_timeout_sigid; + NMDHCP4Config * dhcp4_config; /* dnsmasq stuff for shared connections */ NMDnsMasqManager * dnsmasq_manager; @@ -995,22 +997,28 @@ real_act_stage4_get_ip4_config (NMDevice *self, NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMConnection *connection; NMSettingIP4Config *s_ip4; + const char *iface; g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + iface = nm_device_get_iface (self); + connection = nm_act_request_get_connection (nm_device_get_act_request (self)); g_assert (connection); s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); if (nm_device_get_use_dhcp (self)) { - *config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, - nm_device_get_iface (self)); - if (*config) + *config = nm_dhcp_manager_get_ip4_config (priv->dhcp_manager, iface); + if (*config) { nm_utils_merge_ip4_config (*config, s_ip4); - else + + nm_dhcp_manager_set_dhcp4_config (priv->dhcp_manager, iface, priv->dhcp4_config); + /* Notify of new DHCP4 config */ + g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); + } else *reason = NM_DEVICE_STATE_REASON_DHCP_ERROR; } else { g_assert (s_ip4); @@ -1027,7 +1035,7 @@ real_act_stage4_get_ip4_config (NMDevice *self, } else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { *config = nm_device_new_ip4_shared_config (self, reason); if (*config) - priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self)); + priv->dnsmasq_manager = nm_dnsmasq_manager_new (iface); } } @@ -1115,6 +1123,9 @@ real_act_stage4_ip_config_timeout (NMDevice *self, g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* Notify of invalid DHCP4 config object */ + g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); + /* DHCP failed; connection must fail */ *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; @@ -1334,6 +1345,8 @@ nm_device_deactivate_quickly (NMDevice *self) if (nm_device_get_use_dhcp (self)) { nm_dhcp_manager_cancel_transaction (priv->dhcp_manager, nm_device_get_iface (self)); nm_device_set_use_dhcp (self, FALSE); + /* Notify of invalid DHCP4 config */ + g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); } else if (priv->dnsmasq_manager) { if (priv->dnsmasq_state_id) { g_signal_handler_disconnect (priv->dnsmasq_manager, priv->dnsmasq_state_id); @@ -1542,6 +1555,7 @@ nm_device_can_interrupt_activation (NMDevice *self) static void handle_dhcp_lease_change (NMDevice *device) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); NMIP4Config *config; NMSettingIP4Config *s_ip4; NMConnection *connection; @@ -1575,6 +1589,8 @@ handle_dhcp_lease_change (NMDevice *device) nm_warning ("Failed to update IP4 config in response to DHCP event."); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); } + + nm_dhcp_manager_set_dhcp4_config (priv->dhcp_manager, nm_device_get_iface (device), priv->dhcp4_config); } static void @@ -1584,6 +1600,7 @@ dhcp_state_changed (NMDHCPManager *dhcp_manager, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); NMDeviceState dev_state; if (strcmp (nm_device_get_iface (device), iface) != 0) @@ -1605,12 +1622,16 @@ dhcp_state_changed (NMDHCPManager *dhcp_manager, handle_dhcp_lease_change (device); break; case DHC_TIMEOUT: /* timed out contacting DHCP server */ + nm_dhcp4_config_reset (priv->dhcp4_config); + if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) nm_device_activate_schedule_stage4_ip_config_timeout (device); break; case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ case DHC_ABEND: /* dhclient exited abnormally */ case DHC_END: /* dhclient exited normally */ + nm_dhcp4_config_reset (priv->dhcp4_config); + if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); } else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { @@ -1658,6 +1679,11 @@ nm_device_set_use_dhcp (NMDevice *self, priv = NM_DEVICE_GET_PRIVATE (self); if (use_dhcp) { + /* New exported DHCP4 config */ + if (priv->dhcp4_config) + g_object_unref (priv->dhcp4_config); + priv->dhcp4_config = nm_dhcp4_config_new (); + if (!priv->dhcp_manager) { priv->dhcp_manager = nm_dhcp_manager_get (); priv->dhcp_state_sigid = g_signal_connect (priv->dhcp_manager, @@ -1669,13 +1695,21 @@ nm_device_set_use_dhcp (NMDevice *self, G_CALLBACK (dhcp_timeout), self); } - } else if (priv->dhcp_manager) { - g_signal_handler_disconnect (priv->dhcp_manager, priv->dhcp_state_sigid); - priv->dhcp_state_sigid = 0; - g_signal_handler_disconnect (priv->dhcp_manager, priv->dhcp_timeout_sigid); - priv->dhcp_timeout_sigid = 0; - g_object_unref (priv->dhcp_manager); - priv->dhcp_manager = NULL; + } else { + if (priv->dhcp4_config) { + g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG); + g_object_unref (priv->dhcp4_config); + priv->dhcp4_config = NULL; + } + + if (priv->dhcp_manager) { + g_signal_handler_disconnect (priv->dhcp_manager, priv->dhcp_state_sigid); + priv->dhcp_state_sigid = 0; + g_signal_handler_disconnect (priv->dhcp_manager, priv->dhcp_timeout_sigid); + priv->dhcp_timeout_sigid = 0; + g_object_unref (priv->dhcp_manager); + priv->dhcp_manager = NULL; + } } } @@ -1995,9 +2029,12 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; + state = nm_device_get_state (self); + switch (prop_id) { case NM_DEVICE_INTERFACE_PROP_UDI: g_value_set_string (value, priv->udi); @@ -2015,13 +2052,18 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->ip4_address); break; case NM_DEVICE_INTERFACE_PROP_IP4_CONFIG: - state = nm_device_get_state (NM_DEVICE (object)); - if ( (state == NM_DEVICE_STATE_ACTIVATED) - || (state == NM_DEVICE_STATE_IP_CONFIG)) + if ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG)) g_value_set_object (value, priv->ip4_config); else g_value_set_object (value, NULL); break; + case NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG: + if ( ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG)) + && nm_device_get_use_dhcp (self)) + g_value_set_object (value, priv->dhcp4_config); + else + g_value_set_object (value, NULL); + break; case NM_DEVICE_INTERFACE_PROP_STATE: g_value_set_uint (value, priv->state); break; @@ -2086,6 +2128,10 @@ nm_device_class_init (NMDeviceClass *klass) NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, NM_DEVICE_INTERFACE_IP4_CONFIG); + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG, + NM_DEVICE_INTERFACE_DHCP4_CONFIG); + g_object_class_override_property (object_class, NM_DEVICE_INTERFACE_PROP_STATE, NM_DEVICE_INTERFACE_STATE); diff --git a/src/nm-dhcp4-config.c b/src/nm-dhcp4-config.c new file mode 100644 index 0000000000..334a1b0e57 --- /dev/null +++ b/src/nm-dhcp4-config.c @@ -0,0 +1,186 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + + +#include +#include + +#include "NetworkManager.h" +#include "nm-dbus-manager.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp4-config-glue.h" +#include "nm-dbus-glib-types.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" + + +G_DEFINE_TYPE (NMDHCP4Config, nm_dhcp4_config, G_TYPE_OBJECT) + +#define NM_DHCP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigPrivate)) + +typedef struct { + char *dbus_path; + GHashTable *options; +} NMDHCP4ConfigPrivate; + + +enum { + PROP_0, + PROP_OPTIONS, + + LAST_PROP +}; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +NMDHCP4Config * +nm_dhcp4_config_new (void) +{ + return NM_DHCP4_CONFIG (g_object_new (NM_TYPE_DHCP4_CONFIG, NULL)); +} + +void +nm_dhcp4_config_add_option (NMDHCP4Config *self, + const char *key, + const char *option) +{ + GValue *svalue; + + g_return_if_fail (NM_IS_DHCP4_CONFIG (self)); + g_return_if_fail (key != NULL); + g_return_if_fail (option != NULL); + + svalue = g_slice_new0 (GValue); + g_value_init (svalue, G_TYPE_STRING); + g_value_set_string (svalue, option); + g_hash_table_insert (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options, g_strdup (key), svalue); + g_object_notify (G_OBJECT (self), NM_DHCP4_CONFIG_OPTIONS); +} + +void +nm_dhcp4_config_reset (NMDHCP4Config *self) +{ + g_return_if_fail (NM_IS_DHCP4_CONFIG (self)); + + g_hash_table_remove_all (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options); + g_object_notify (G_OBJECT (self), NM_DHCP4_CONFIG_OPTIONS); +} + +const char * +nm_dhcp4_config_get_option (NMDHCP4Config *self, const char *key) +{ + GValue *value; + + g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL); + g_return_val_if_fail (key != NULL, NULL); + + value = g_hash_table_lookup (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options, key); + return value ? g_value_get_string (value) : NULL; +} + +static void +nm_gvalue_destroy (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +static void +nm_dhcp4_config_init (NMDHCP4Config *self) +{ + NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self); + static guint32 counter = 0; + DBusGConnection *connection; + NMDBusManager *dbus_mgr; + + dbus_mgr = nm_dbus_manager_get (); + connection = nm_dbus_manager_get_connection (dbus_mgr); + priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/DHCP4Config/%d", counter++); + dbus_g_connection_register_g_object (connection, priv->dbus_path, G_OBJECT (self)); + g_object_unref (dbus_mgr); + + priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy); +} + +static void +finalize (GObject *object) +{ + NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); + + g_free (priv->dbus_path); + g_hash_table_destroy (priv->options); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_OPTIONS: + g_value_set_boxed (value, priv->options); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMDHCP4ConfigPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + /* properties */ + g_object_class_install_property + (object_class, PROP_OPTIONS, + g_param_spec_boxed (NM_DHCP4_CONFIG_OPTIONS, + "Options", + "DHCP configuration options returned by the server", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDHCP4ConfigClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class), + &dbus_glib_nm_dhcp4_config_object_info); +} diff --git a/src/nm-dhcp4-config.h b/src/nm-dhcp4-config.h new file mode 100644 index 0000000000..db0e49d880 --- /dev/null +++ b/src/nm-dhcp4-config.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef NM_DHCP4_CONFIG_H +#define NM_DHCP4_CONFIG_H + +#include +#include + +#include "nm-dhcp4-config.h" + +#define NM_TYPE_DHCP4_CONFIG (nm_dhcp4_config_get_type ()) +#define NM_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP4_CONFIG, NMDHCP4Config)) +#define NM_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigClass)) +#define NM_IS_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP4_CONFIG)) +#define NM_IS_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DHCP4_CONFIG)) +#define NM_DHCP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigClass)) + +typedef struct { + GObject parent; +} NMDHCP4Config; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*properties_changed) (NMDHCP4Config *config, GHashTable *properties); +} NMDHCP4ConfigClass; + +#define NM_DHCP4_CONFIG_OPTIONS "options" + +GType nm_dhcp4_config_get_type (void); + +NMDHCP4Config *nm_dhcp4_config_new (void); + +void nm_dhcp4_config_add_option (NMDHCP4Config *config, + const char *key, + const char *option); + +void nm_dhcp4_config_reset (NMDHCP4Config *config); + +const char *nm_dhcp4_config_get_option (NMDHCP4Config *config, const char *option); + +#endif /* NM_DHCP4_CONFIG_H */