diff options
Diffstat (limited to 'src/dhcp')
| -rw-r--r-- | src/dhcp/meson.build | 22 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-client.c | 119 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-client.h | 49 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.c | 330 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.h | 15 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 59 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhcpcanon.c | 14 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhcpcd.c | 17 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-helper.c | 2 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-listener.c | 84 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 118 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-manager.h | 15 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-systemd.c | 115 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-utils.c | 8 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-utils.h | 2 | ||||
| -rw-r--r-- | src/dhcp/tests/leases/basic.leases | 31 | ||||
| -rw-r--r-- | src/dhcp/tests/leases/malformed1.leases | 15 | ||||
| -rw-r--r-- | src/dhcp/tests/leases/malformed2.leases | 15 | ||||
| -rw-r--r-- | src/dhcp/tests/leases/malformed3.leases | 15 | ||||
| -rw-r--r-- | src/dhcp/tests/meson.build | 19 | ||||
| -rw-r--r-- | src/dhcp/tests/test-dhcp-dhclient.c | 318 | ||||
| -rw-r--r-- | src/dhcp/tests/test-dhcp-utils.c | 21 |
22 files changed, 917 insertions, 486 deletions
diff --git a/src/dhcp/meson.build b/src/dhcp/meson.build deleted file mode 100644 index 289a16ca..00000000 --- a/src/dhcp/meson.build +++ /dev/null @@ -1,22 +0,0 @@ -name = 'nm-dhcp-helper' - -cflags = [ - '-DG_LOG_DOMAIN="@0@"'.format(name), - '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_GLIB', - '-DNMRUNDIR="@0@"'.format(nm_pkgrundir), -] - -executable( - name, - name + '.c', - dependencies: nm_core_dep, - c_args: cflags, - link_args: ldflags_linker_script_binary, - link_depends: linker_script_binary, - install: true, - install_dir: nm_libexecdir -) - -if enable_tests - subdir('tests') -endif diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 96c02653..ea3938d6 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -52,24 +52,23 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; NM_GOBJECT_PROPERTIES_DEFINE_BASE ( + PROP_MULTI_IDX, PROP_ADDR_FAMILY, - PROP_FLAGS, - PROP_HWADDR, PROP_IFACE, PROP_IFINDEX, - PROP_MULTI_IDX, - PROP_ROUTE_METRIC, + PROP_HWADDR, + PROP_UUID, PROP_ROUTE_TABLE, + PROP_ROUTE_METRIC, PROP_TIMEOUT, - PROP_UUID, ); typedef struct _NMDhcpClientPrivate { NMDedupMultiIndex *multi_idx; char * iface; - GBytes * hwaddr; + GByteArray * hwaddr; char * uuid; - GBytes * duid; + GByteArray * duid; GBytes * client_id; char * hostname; pid_t pid; @@ -139,7 +138,7 @@ nm_dhcp_client_get_uuid (NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->uuid; } -GBytes * +const GByteArray * nm_dhcp_client_get_duid (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); @@ -147,7 +146,7 @@ nm_dhcp_client_get_duid (NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->duid; } -GBytes * +const GByteArray * nm_dhcp_client_get_hw_addr (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); @@ -239,20 +238,26 @@ nm_dhcp_client_set_client_id_bin (NMDhcpClient *self, _set_client_id (self, b, TRUE); } -const char * -nm_dhcp_client_get_hostname (NMDhcpClient *self) +void +nm_dhcp_client_set_client_id_str (NMDhcpClient *self, + const char *dhcp_client_id) { - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + g_return_if_fail (NM_IS_DHCP_CLIENT (self)); + g_return_if_fail (!dhcp_client_id || dhcp_client_id[0]); - return NM_DHCP_CLIENT_GET_PRIVATE (self)->hostname; + _set_client_id (self, + dhcp_client_id + ? nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id) + : NULL, + TRUE); } -gboolean -nm_dhcp_client_get_info_only (NMDhcpClient *self) +const char * +nm_dhcp_client_get_hostname (NMDhcpClient *self) { - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); - return NM_DHCP_CLIENT_GET_PRIVATE (self)->info_only; + return NM_DHCP_CLIENT_GET_PRIVATE (self)->hostname; } gboolean @@ -340,7 +345,7 @@ nm_dhcp_client_stop_pid (pid_t pid, const char *iface) } static void -stop (NMDhcpClient *self, gboolean release, GBytes *duid) +stop (NMDhcpClient *self, gboolean release, const GByteArray *duid) { NMDhcpClientPrivate *priv; @@ -354,6 +359,7 @@ stop (NMDhcpClient *self, gboolean release, GBytes *duid) nm_dhcp_client_stop_pid (priv->pid, priv->iface); } priv->pid = -1; + priv->info_only = FALSE; } void @@ -486,9 +492,10 @@ nm_dhcp_client_watch_child (NMDhcpClient *self, pid_t pid) gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, - GBytes *client_id, + const char *dhcp_client_id, const char *dhcp_anycast_addr, const char *hostname, + gboolean use_fqdn, const char *last_ip4_address) { NMDhcpClientPrivate *priv; @@ -505,19 +512,19 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, else _LOGI ("activation: beginning transaction (timeout in %u seconds)", (guint) priv->timeout); - nm_dhcp_client_set_client_id (self, client_id); + nm_dhcp_client_set_client_id_str (self, dhcp_client_id); g_clear_pointer (&priv->hostname, g_free); priv->hostname = g_strdup (hostname); + priv->use_fqdn = use_fqdn; return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address); } -static GBytes * +static GByteArray * generate_duid_from_machine_id (void) { - const int DUID_SIZE = 18; - guint8 *duid_buffer; + GByteArray *duid; GChecksum *sum; guint8 buffer[32]; /* SHA256 digest size */ gsize sumlen = sizeof (buffer); @@ -525,7 +532,6 @@ generate_duid_from_machine_id (void) uuid_t uuid; gs_free char *machine_id_s = NULL; gs_free char *str = NULL; - GBytes *duid; machine_id_s = nm_utils_machine_id_read (); if (nm_utils_machine_id_parse (machine_id_s, uuid)) { @@ -548,31 +554,36 @@ generate_duid_from_machine_id (void) * u16: type (DUID-UUID = 4) * u8[16]: UUID bytes */ - duid_buffer = g_malloc (DUID_SIZE); - - G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2); - memcpy (&duid_buffer[0], &duid_type, 2); + duid = g_byte_array_sized_new (18); + g_byte_array_append (duid, (guint8 *) &duid_type, sizeof (duid_type)); /* Since SHA256 is 256 bits, but UUID is 128 bits, we just take the first * 128 bits of the SHA256 as the DUID-UUID. */ - memcpy (&duid_buffer[2], buffer, 16); + g_byte_array_append (duid, buffer, 16); - duid = g_bytes_new_take (duid_buffer, DUID_SIZE); nm_log_dbg (LOGD_DHCP, "dhcp: generated DUID %s", (str = nm_dhcp_utils_duid_to_string (duid))); return duid; } -static GBytes * +static GByteArray * get_duid (NMDhcpClient *self) { - static GBytes *duid = NULL; + static GByteArray *duid = NULL; + GByteArray *copy = NULL; - if (G_UNLIKELY (!duid)) + if (G_UNLIKELY (duid == NULL)) { duid = generate_duid_from_machine_id (); + g_assert (duid); + } + + if (G_LIKELY (duid)) { + copy = g_byte_array_sized_new (duid->len); + g_byte_array_append (copy, duid->data, duid->len); + } - return g_bytes_ref (duid); + return copy; } gboolean @@ -580,6 +591,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, const char *hostname, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes) { @@ -604,6 +616,8 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, g_clear_pointer (&priv->hostname, g_free); priv->hostname = g_strdup (hostname); + priv->info_only = info_only; + if (priv->timeout == NM_DHCP_TIMEOUT_INFINITY) _LOGI ("activation: beginning transaction (no timeout)"); else @@ -612,6 +626,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, return NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, dhcp_anycast_addr, ll_addr, + info_only, privacy, priv->duid, needed_prefixes); @@ -796,8 +811,8 @@ nm_dhcp_client_handle_event (gpointer unused, old_state = priv->state; new_state = reason_to_state (self, priv->iface, reason); - _LOGD ("DHCP state '%s' -> '%s' (reason: '%s')", - state_to_string (old_state), state_to_string (new_state), reason); + _LOGD ("DHCP reason '%s' -> state '%s'", + reason, state_to_string (new_state)); if (new_state == NM_DHCP_STATE_BOUND) { GVariantIter iter; @@ -908,16 +923,8 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE ((NMDhcpClient *) object); - guint flags; switch (prop_id) { - case PROP_FLAGS: - /* construct-only */ - flags = g_value_get_uint (value); - nm_assert ((flags & ~((guint) (NM_DHCP_CLIENT_FLAGS_INFO_ONLY | NM_DHCP_CLIENT_FLAGS_USE_FQDN))) == 0); - priv->info_only = NM_FLAGS_HAS (flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY); - priv->use_fqdn = NM_FLAGS_HAS (flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN); - break; case PROP_MULTI_IDX: /* construct-only */ priv->multi_idx = g_value_get_pointer (value); @@ -976,8 +983,6 @@ nm_dhcp_client_init (NMDhcpClient *self) priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DHCP_CLIENT, NMDhcpClientPrivate); self->_priv = priv; - c_list_init (&self->dhcp_client_lst); - priv->pid = -1; } @@ -992,8 +997,6 @@ dispose (GObject *object) * the DHCP client. */ - nm_assert (c_list_is_empty (&self->dhcp_client_lst)); - watch_cleanup (self); timeout_cleanup (self); @@ -1001,8 +1004,16 @@ dispose (GObject *object) g_clear_pointer (&priv->hostname, g_free); g_clear_pointer (&priv->uuid, g_free); g_clear_pointer (&priv->client_id, g_bytes_unref); - g_clear_pointer (&priv->hwaddr, g_bytes_unref); - g_clear_pointer (&priv->duid, g_bytes_unref); + + if (priv->hwaddr) { + g_byte_array_free (priv->hwaddr, TRUE); + priv->hwaddr = NULL; + } + + if (priv->duid) { + g_byte_array_free (priv->duid, TRUE); + priv->duid = NULL; + } G_OBJECT_CLASS (nm_dhcp_client_parent_class)->dispose (object); @@ -1043,7 +1054,7 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) obj_properties[PROP_HWADDR] = g_param_spec_boxed (NM_DHCP_CLIENT_HWADDR, "", "", - G_TYPE_BYTES, + G_TYPE_BYTE_ARRAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); @@ -1077,12 +1088,6 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FLAGS] = - g_param_spec_uint (NM_DHCP_CLIENT_FLAGS, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[SIGNAL_STATE_CHANGED] = diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 0d92d743..2c634168 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -34,16 +34,15 @@ #define NM_IS_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_CLIENT)) #define NM_DHCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) -#define NM_DHCP_CLIENT_ADDR_FAMILY "addr-family" -#define NM_DHCP_CLIENT_FLAGS "flags" -#define NM_DHCP_CLIENT_HWADDR "hwaddr" -#define NM_DHCP_CLIENT_IFINDEX "ifindex" -#define NM_DHCP_CLIENT_INTERFACE "iface" -#define NM_DHCP_CLIENT_MULTI_IDX "multi-idx" -#define NM_DHCP_CLIENT_ROUTE_METRIC "route-metric" +#define NM_DHCP_CLIENT_INTERFACE "iface" +#define NM_DHCP_CLIENT_ADDR_FAMILY "addr-family" +#define NM_DHCP_CLIENT_IFINDEX "ifindex" +#define NM_DHCP_CLIENT_HWADDR "hwaddr" +#define NM_DHCP_CLIENT_UUID "uuid" #define NM_DHCP_CLIENT_ROUTE_TABLE "route-table" -#define NM_DHCP_CLIENT_TIMEOUT "timeout" -#define NM_DHCP_CLIENT_UUID "uuid" +#define NM_DHCP_CLIENT_ROUTE_METRIC "route-metric" +#define NM_DHCP_CLIENT_TIMEOUT "timeout" +#define NM_DHCP_CLIENT_MULTI_IDX "multi-idx" #define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" #define NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED "prefix-delegated" @@ -65,14 +64,8 @@ struct _NMDhcpClientPrivate; typedef struct { GObject parent; struct _NMDhcpClientPrivate *_priv; - CList dhcp_client_lst; } NMDhcpClient; -typedef enum { - NM_DHCP_CLIENT_FLAGS_INFO_ONLY = (1LL << 0), - NM_DHCP_CLIENT_FLAGS_USE_FQDN = (1LL << 1), -} NMDhcpClientFlags; - typedef struct { GObjectClass parent; @@ -85,13 +78,14 @@ typedef struct { gboolean (*ip6_start) (NMDhcpClient *self, const char *anycast_addr, const struct in6_addr *ll_addr, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - GBytes *duid, + const GByteArray *duid, guint needed_prefixes); void (*stop) (NMDhcpClient *self, gboolean release, - GBytes *duid); + const GByteArray *duid); /** * get_duid: @@ -102,7 +96,7 @@ typedef struct { * representation of the DUID. If no DUID is found, %NULL should be * returned. */ - GBytes *(*get_duid) (NMDhcpClient *self); + GByteArray * (*get_duid) (NMDhcpClient *self); /* Signals */ void (*state_changed) (NMDhcpClient *self, @@ -125,9 +119,9 @@ int nm_dhcp_client_get_ifindex (NMDhcpClient *self); const char *nm_dhcp_client_get_uuid (NMDhcpClient *self); -GBytes *nm_dhcp_client_get_duid (NMDhcpClient *self); +const GByteArray *nm_dhcp_client_get_duid (NMDhcpClient *self); -GBytes *nm_dhcp_client_get_hw_addr (NMDhcpClient *self); +const GByteArray *nm_dhcp_client_get_hw_addr (NMDhcpClient *self); guint32 nm_dhcp_client_get_route_table (NMDhcpClient *self); @@ -139,20 +133,20 @@ GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self); const char *nm_dhcp_client_get_hostname (NMDhcpClient *self); -gboolean nm_dhcp_client_get_info_only (NMDhcpClient *self); - gboolean nm_dhcp_client_get_use_fqdn (NMDhcpClient *self); gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, - GBytes *client_id, + const char *dhcp_client_id, const char *dhcp_anycast_addr, const char *hostname, + gboolean use_fqdn, const char *last_ip4_address); gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, const char *hostname, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes); @@ -185,6 +179,8 @@ void nm_dhcp_client_set_client_id_bin (NMDhcpClient *self, guint8 type, const guint8 *client_id, gsize len); +void nm_dhcp_client_set_client_id_str (NMDhcpClient *self, + const char *dhcp_client_id); /***************************************************************************** * Client data @@ -194,6 +190,13 @@ typedef struct { GType (*get_type)(void); const char *name; const char *(*get_path) (void); + GSList *(*get_lease_ip_configs) (struct _NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + const char *uuid, + guint32 route_table, + guint32 route_metric); } NMDhcpClientFactory; extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon; diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index 52923310..4df90d76 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -125,7 +125,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname, gboolean * as long as all the characters are printable. */ for (i = 1; (p[0] == 0) && i < l; i++) { - if (!g_ascii_isprint (p[i]) || p[i] == '\\' || p[i] == '"') + if (!g_ascii_isprint (p[i])) break; } @@ -138,9 +138,8 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname, gboolean g_string_append_printf (str, "%02x", (guint8) p[i]); } } else { - /* Printable; just add to the line with type 0 */ + /* Printable; just add to the line minus the 'type' */ g_string_append_c (str, '"'); - g_string_append (str, "\\x00"); g_string_append_len (str, p + 1, l - 1); g_string_append_c (str, '"'); } @@ -178,60 +177,31 @@ read_client_id (const char *str) { gs_free char *s = NULL; char *p; - int i = 0, j = 0; nm_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG))); - str += NM_STRLEN (CLIENTID_TAG); - if (!g_ascii_isspace (*str)) - return NULL; + str += NM_STRLEN (CLIENTID_TAG); while (g_ascii_isspace (*str)) str++; if (*str == '"') { - /* Parse string literal with escape sequences */ s = g_strdup (str + 1); p = strrchr (s, '"'); if (p) *p = '\0'; else return NULL; + } else + s = g_strdup (str); - if (!s[0]) - return NULL; - - while (s[i]) { - if ( s[i] == '\\' - && s[i + 1] == 'x' - && g_ascii_isxdigit (s[i + 2]) - && g_ascii_isxdigit (s[i + 3])) { - s[j++] = (g_ascii_xdigit_value (s[i + 2]) << 4) - + g_ascii_xdigit_value (s[i + 3]); - i += 4; - continue; - } - if ( s[i] == '\\' - && s[i + 1] >= '0' && s[i + 1] <= '7' - && s[1 + 2] >= '0' && s[i + 2] <= '7' - && s[1 + 3] >= '0' && s[i + 3] <= '7') { - s[j++] = ((s[i + 1] - '0') << 6) - + ((s[i + 2] - '0') << 3) - + ( s[i + 3] - '0'); - i += 4; - continue; - } - s[j++] = s[i++]; - } - return g_bytes_new_take (g_steal_pointer (&s), j); - } - - /* Otherwise, try to read a hexadecimal sequence */ - s = g_strdup (str); g_strchomp (s); if (s[strlen (s) - 1] == ';') s[strlen (s) - 1] = '\0'; - return nm_utils_hexstr2bin (s); + if (!s[0]) + return NULL; + + return nm_dhcp_utils_client_id_string_to_bytes (s); } GBytes * @@ -309,7 +279,6 @@ nm_dhcp_dhclient_create_config (const char *interface, g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL); g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NULL); - nm_assert (!out_new_client_id || !*out_new_client_id); new_contents = g_string_new (_("# Created by NetworkManager\n")); fqdn_opts = g_ptr_array_sized_new (5); @@ -363,8 +332,6 @@ nm_dhcp_dhclient_create_config (const char *interface, continue; /* Otherwise capture and return the existing client id */ - if (out_new_client_id) - g_clear_pointer (out_new_client_id, g_bytes_unref); NM_SET_OUT (out_new_client_id, read_client_id (p)); } @@ -477,20 +444,14 @@ nm_dhcp_dhclient_create_config (const char *interface, /* Roughly follow what dhclient's quotify_buf() and pretty_escape() functions do */ char * -nm_dhcp_dhclient_escape_duid (GBytes *duid) +nm_dhcp_dhclient_escape_duid (const GByteArray *duid) { char *escaped; - const guint8 *s, *s0; - gsize len; + const guint8 *s = duid->data; char *d; - g_return_val_if_fail (duid, NULL); - - s0 = g_bytes_get_data (duid, &len); - s = s0; - - d = escaped = g_malloc ((len * 4) + 1); - while (s < (s0 + len)) { + d = escaped = g_malloc0 ((duid->len * 4) + 1); + while (s < (duid->data + duid->len)) { if (!g_ascii_isprint (*s)) { *d++ = '\\'; *d++ = '0' + ((*s >> 6) & 0x7); @@ -504,7 +465,6 @@ nm_dhcp_dhclient_escape_duid (GBytes *duid) } else *d++ = *s++; } - *d++ = '\0'; return escaped; } @@ -516,7 +476,7 @@ isoctal (const guint8 *p) && p[2] >= '0' && p[2] <= '7'); } -GBytes * +GByteArray * nm_dhcp_dhclient_unescape_duid (const char *duid) { GByteArray *unescaped; @@ -547,7 +507,7 @@ nm_dhcp_dhclient_unescape_duid (const char *duid) g_byte_array_append (unescaped, &p[i], 1); } - return g_byte_array_free_to_bytes (unescaped); + return unescaped; error: g_byte_array_free (unescaped, TRUE); @@ -556,10 +516,10 @@ error: #define DUID_PREFIX "default-duid \"" -GBytes * +GByteArray * nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error) { - GBytes *duid = NULL; + GByteArray *duid = NULL; char *contents; char **line, **split, *p, *e; @@ -643,3 +603,259 @@ nm_dhcp_dhclient_save_duid (const char *leasefile, g_string_free (s, TRUE); return success; } + +static void +add_lease_option (GHashTable *hash, char *line) +{ + char *spc; + size_t len; + + /* Find the space after "option" */ + spc = strchr (line, ' '); + if (!spc) + return; + + /* Find the option tag's data, which is after the second space */ + if (g_str_has_prefix (line, "option ")) { + while (g_ascii_isspace (*spc)) + spc++; + spc = strchr (spc + 1, ' '); + if (!spc) + return; + } + + /* Split the line at the space */ + *spc = '\0'; + spc++; + + /* Kill the ';' at the end of the line, if any */ + len = strlen (spc); + if (*(spc + len - 1) == ';') + *(spc + len - 1) = '\0'; + + /* Strip leading quote */ + while (g_ascii_isspace (*spc)) + spc++; + if (*spc == '"') + spc++; + + /* Strip trailing quote */ + len = strlen (spc); + if (len > 0 && spc[len - 1] == '"') + spc[len - 1] = '\0'; + + if (spc[0]) + g_hash_table_insert (hash, g_strdup (line), g_strdup (spc)); +} + +#define LEASE_INVALID G_MININT64 +static GTimeSpan +lease_validity_span (const char *str_expire, GDateTime *now) +{ + GDateTime *expire = NULL; + struct tm expire_tm; + GTimeSpan span; + + g_return_val_if_fail (now != NULL, LEASE_INVALID); + g_return_val_if_fail (str_expire != NULL, LEASE_INVALID); + + /* Skip initial number (day of week?) */ + if (!isdigit (*str_expire++)) + return LEASE_INVALID; + if (!isspace (*str_expire++)) + return LEASE_INVALID; + /* Read lease expiration (in UTC) */ + if (!strptime (str_expire, "%t%Y/%m/%d %H:%M:%S", &expire_tm)) + return LEASE_INVALID; + + expire = g_date_time_new_utc (expire_tm.tm_year + 1900, + expire_tm.tm_mon + 1, + expire_tm.tm_mday, + expire_tm.tm_hour, + expire_tm.tm_min, + expire_tm.tm_sec); + if (!expire) + return LEASE_INVALID; + + span = g_date_time_difference (expire, now); + g_date_time_unref (expire); + + /* GDateTime only supports a range of less then 10000 years, so span can + * not overflow or be equal to LEASE_INVALID */ + return span; +} + +/** + * nm_dhcp_dhclient_read_lease_ip_configs: + * @multi_idx: the multi index instance for the ip config object + * @addr_family: whether to read IPv4 or IPv6 leases + * @iface: the interface name to match leases with + * @ifindex: interface index of @iface + * @route_table: the route table for the default route. + * @route_metric: the route metric for the default route. + * @contents: the contents of a dhclient leasefile + * @now: the current UTC date/time; pass %NULL to automatically use current + * UTC time. Testcases may need a different value for 'now' + * + * Reads dhclient leases from @contents and parses them into either + * #NMIP4Config or #NMIP6Config objects depending on the value of @addr_family. + * + * Returns: a #GSList of #NMIP4Config objects (if @addr_family is %AF_INET) or a list of + * #NMIP6Config objects (if @addr_family is %AF_INET6) containing the lease data. + */ +GSList * +nm_dhcp_dhclient_read_lease_ip_configs (NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + guint32 route_table, + guint32 route_metric, + const char *contents, + GDateTime *now) +{ + GSList *parsed = NULL, *iter, *leases = NULL; + char **line, **split = NULL; + GHashTable *hash = NULL; + gint32 now_monotonic_ts; + + g_return_val_if_fail (contents != NULL, NULL); + nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + + split = g_strsplit_set (contents, "\n\r", -1); + if (!split) + return NULL; + + for (line = split; line && *line; line++) { + *line = g_strstrip (*line); + + if (*line[0] == '#') { + /* Comment */ + } else if (!strcmp (*line, "}")) { + /* Lease ends */ + parsed = g_slist_append (parsed, hash); + hash = NULL; + } else if (!strcmp (*line, "lease {")) { + /* Beginning of a new lease */ + if (hash) { + /* Ignore malformed lease that doesn't end before new one starts */ + g_hash_table_destroy (hash); + } + + hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); + } else if (hash && strlen (*line)) + add_lease_option (hash, *line); + } + g_strfreev (split); + + /* Check if the last lease in the file was properly ended */ + if (hash) { + /* Ignore malformed lease that doesn't end before new one starts */ + g_hash_table_destroy (hash); + hash = NULL; + } + + if (now) + g_date_time_ref (now); + else + now = g_date_time_new_now_utc (); + now_monotonic_ts = nm_utils_get_monotonic_timestamp_s (); + + for (iter = parsed; iter; iter = g_slist_next (iter)) { + NMIP4Config *ip4; + NMPlatformIP4Address address; + const char *value; + GTimeSpan expiry; + guint32 tmp, gw = 0; + + hash = iter->data; + + /* Make sure this lease is for the interface we want */ + value = g_hash_table_lookup (hash, "interface"); + if (!value || strcmp (value, iface)) + continue; + + value = g_hash_table_lookup (hash, "expire"); + if (!value) + continue; + expiry = lease_validity_span (value, now); + if (expiry == LEASE_INVALID) + continue; + + /* scale expiry to seconds (and CLAMP into the range of guint32) */ + expiry = CLAMP (expiry / G_TIME_SPAN_SECOND, 0, NM_PLATFORM_LIFETIME_PERMANENT-1); + if (expiry <= 0) { + /* the address is already expired. Don't even add it. */ + continue; + } + + memset (&address, 0, sizeof (address)); + + /* IP4 address */ + value = g_hash_table_lookup (hash, "fixed-address"); + if (!value) + continue; + if (!inet_pton (AF_INET, value, &address.address)) + continue; + address.peer_address = address.address; + + /* Gateway */ + value = g_hash_table_lookup (hash, "option routers"); + if (!value) + continue; + if (!inet_pton (AF_INET, value, &gw)) + continue; + + /* Netmask */ + value = g_hash_table_lookup (hash, "option subnet-mask"); + if (value && inet_pton (AF_INET, value, &tmp)) + address.plen = nm_utils_ip4_netmask_to_prefix (tmp); + + /* Get default netmask for the IP according to appropriate class. */ + if (!address.plen) + address.plen = _nm_utils_ip4_get_default_prefix (address.address); + + address.timestamp = now_monotonic_ts; + address.lifetime = address.preferred = expiry; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; + + ip4 = nm_ip4_config_new (multi_idx, ifindex); + nm_ip4_config_add_address (ip4, &address); + + { + const NMPlatformIP4Route r = { + .rt_source = NM_IP_CONFIG_SOURCE_DHCP, + .gateway = gw, + .table_coerced = nm_platform_route_table_coerce (route_table), + .metric = route_metric, + }; + + nm_ip4_config_add_route (ip4, &r, NULL); + } + + value = g_hash_table_lookup (hash, "option domain-name-servers"); + if (value) { + char **dns, **dns_iter; + + dns = g_strsplit_set (value, ",", -1); + for (dns_iter = dns; dns_iter && *dns_iter; dns_iter++) { + if (inet_pton (AF_INET, *dns_iter, &tmp)) + nm_ip4_config_add_nameserver (ip4, tmp); + } + if (dns) + g_strfreev (dns); + } + + value = g_hash_table_lookup (hash, "option domain-name"); + if (value && value[0]) + nm_ip4_config_add_domain (ip4, value); + + /* FIXME: static routes */ + + leases = g_slist_append (leases, ip4); + } + + g_date_time_unref (now); + g_slist_free_full (parsed, (GDestroyNotify) g_hash_table_destroy); + return leases; +} + diff --git a/src/dhcp/nm-dhcp-dhclient-utils.h b/src/dhcp/nm-dhcp-dhclient-utils.h index fab9196a..94de1963 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/dhcp/nm-dhcp-dhclient-utils.h @@ -33,16 +33,25 @@ char *nm_dhcp_dhclient_create_config (const char *interface, const char *orig_contents, GBytes **out_new_client_id); -char *nm_dhcp_dhclient_escape_duid (GBytes *duid); +char *nm_dhcp_dhclient_escape_duid (const GByteArray *duid); -GBytes *nm_dhcp_dhclient_unescape_duid (const char *duid); +GByteArray *nm_dhcp_dhclient_unescape_duid (const char *duid); -GBytes *nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error); +GByteArray *nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error); gboolean nm_dhcp_dhclient_save_duid (const char *leasefile, const char *escaped_duid, GError **error); +GSList *nm_dhcp_dhclient_read_lease_ip_configs (struct _NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + guint32 route_table, + guint32 route_metric, + const char *contents, + GDateTime *now); + GBytes *nm_dhcp_dhclient_get_client_id_from_config_file (const char *path); #endif /* __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ */ diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 738e9f91..74d920a8 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -158,6 +158,32 @@ get_dhclient_leasefile (int addr_family, return NULL; } +static GSList * +nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + const char *uuid, + guint32 route_table, + guint32 route_metric) +{ + gs_free char *contents = NULL; + gs_free char *leasefile = NULL; + + leasefile = get_dhclient_leasefile (addr_family, iface, uuid, NULL); + if (!leasefile) + return NULL; + + if ( g_file_test (leasefile, G_FILE_TEST_EXISTS) + && g_file_get_contents (leasefile, &contents, NULL, NULL) + && contents + && contents[0]) { + return nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, addr_family, iface, ifindex, + route_table, route_metric, contents, NULL); + } + return NULL; +} + static gboolean merge_dhclient_config (NMDhcpDhclient *self, int addr_family, @@ -312,7 +338,7 @@ create_dhclient_config (NMDhcpDhclient *self, static gboolean dhclient_start (NMDhcpClient *client, const char *mode_opt, - GBytes *duid, + const GByteArray *duid, gboolean release, pid_t *out_pid, int prefixes) @@ -413,19 +439,19 @@ dhclient_start (NMDhcpClient *client, while (prefixes--) g_ptr_array_add (argv, (gpointer) "-P"); } - g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ + g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); if (pid_file) { - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ g_ptr_array_add (argv, (gpointer) pid_file); } - g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */ + g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */ g_ptr_array_add (argv, (gpointer) priv->lease_file); if (priv->conf_file) { - g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */ + g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */ g_ptr_array_add (argv, (gpointer) priv->conf_file); } @@ -492,10 +518,8 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last priv->conf_file = create_dhclient_config (self, AF_INET, iface, uuid, client_id, dhcp_anycast_addr, hostname, timeout, use_fqdn, &new_client_id); if (priv->conf_file) { - if (new_client_id) { - nm_assert (!client_id); + if (new_client_id) nm_dhcp_client_set_client_id (client, new_client_id); - } success = dhclient_start (client, NULL, NULL, FALSE, NULL, 0); } else _LOGW ("error creating dhclient configuration file"); @@ -507,8 +531,9 @@ static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - GBytes *duid, + const GByteArray *duid, guint needed_prefixes) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); @@ -528,19 +553,16 @@ ip6_start (NMDhcpClient *client, return FALSE; } - return dhclient_start (client, - nm_dhcp_client_get_info_only (NM_DHCP_CLIENT (self)) - ? "-S" - : "-N", - duid, FALSE, NULL, needed_prefixes); + return dhclient_start (client, info_only ? "-S" : "-N", duid, FALSE, NULL, needed_prefixes); } static void -stop (NMDhcpClient *client, gboolean release, GBytes *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); + /* Chain up to parent */ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release, duid); if (priv->conf_file) @@ -581,12 +603,12 @@ state_changed (NMDhcpClient *client, nm_dhcp_client_set_client_id (client, client_id); } -static GBytes * +static GByteArray * get_duid (NMDhcpClient *client) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); - GBytes *duid = NULL; + GByteArray *duid = NULL; char *leasefile; GError *error = NULL; @@ -620,7 +642,7 @@ get_duid (NMDhcpClient *client) } /* return our DUID, otherwise let the parent class make a default DUID */ - return duid ?: NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client); + return duid ? duid : NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client); } /*****************************************************************************/ @@ -695,6 +717,7 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = { .name = "dhclient", .get_type = nm_dhcp_dhclient_get_type, .get_path = nm_dhcp_dhclient_get_path, + .get_lease_ip_configs = nm_dhcp_dhclient_get_lease_ip_configs, }; #endif /* WITH_DHCLIENT */ diff --git a/src/dhcp/nm-dhcp-dhcpcanon.c b/src/dhcp/nm-dhcp-dhcpcanon.c index 82b3db4f..d7ddd194 100644 --- a/src/dhcp/nm-dhcp-dhcpcanon.c +++ b/src/dhcp/nm-dhcp-dhcpcanon.c @@ -80,7 +80,7 @@ nm_dhcp_dhcpcanon_get_path (void) static gboolean dhcpcanon_start (NMDhcpClient *client, const char *mode_opt, - GBytes *duid, + const GByteArray *duid, gboolean release, pid_t *out_pid, int prefixes) @@ -118,16 +118,16 @@ dhcpcanon_start (NMDhcpClient *client, argv = g_ptr_array_new (); g_ptr_array_add (argv, (gpointer) dhcpcanon_path); - g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ + g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); if (pid_file) { - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ g_ptr_array_add (argv, (gpointer) pid_file); } if (priv->conf_file) { - g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */ + g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */ g_ptr_array_add (argv, (gpointer) priv->conf_file); } @@ -179,8 +179,9 @@ static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - GBytes *duid, + const GByteArray *duid, guint needed_prefixes) { NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client); @@ -189,7 +190,7 @@ ip6_start (NMDhcpClient *client, return FALSE; } static void -stop (NMDhcpClient *client, gboolean release, GBytes *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client); NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE (self); @@ -265,6 +266,7 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon = { .name = "dhcpcanon", .get_type = nm_dhcp_dhcpcanon_get_type, .get_path = nm_dhcp_dhcpcanon_get_path, + .get_lease_ip_configs = NULL, }; #endif /* WITH_DHCPCANON */ diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c index c4bcb084..66a31acf 100644 --- a/src/dhcp/nm-dhcp-dhcpcd.c +++ b/src/dhcp/nm-dhcp-dhcpcd.c @@ -114,18 +114,18 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last argv = g_ptr_array_new (); g_ptr_array_add (argv, (gpointer) dhcpcd_path); - g_ptr_array_add (argv, (gpointer) "-B"); /* Don't background on lease (disable fork()) */ + g_ptr_array_add (argv, (gpointer) "-B"); /* Don't background on lease (disable fork()) */ - g_ptr_array_add (argv, (gpointer) "-K"); /* Disable built-in carrier detection */ + g_ptr_array_add (argv, (gpointer) "-K"); /* Disable built-in carrier detection */ - g_ptr_array_add (argv, (gpointer) "-L"); /* Disable built-in IPv4LL */ + g_ptr_array_add (argv, (gpointer) "-L"); /* Disable built-in IPv4LL */ /* --noarp. Don't request or claim the address by ARP; this also disables IPv4LL. */ g_ptr_array_add (argv, (gpointer) "-A"); - g_ptr_array_add (argv, (gpointer) "-G"); /* Let NM handle routing */ + g_ptr_array_add (argv, (gpointer) "-G"); /* Let NM handle routing */ - g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ + g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); #ifdef DHCPCD_SUPPORTS_IPV6 @@ -177,8 +177,9 @@ static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - GBytes *duid, + const GByteArray *duid, guint needed_prefixes) { NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client); @@ -188,11 +189,12 @@ ip6_start (NMDhcpClient *client, } static void -stop (NMDhcpClient *client, gboolean release, GBytes *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client); NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (self); + /* Chain up to parent */ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release, duid); if (priv->pid_file) { @@ -251,6 +253,7 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd = { .name = "dhcpcd", .get_type = nm_dhcp_dhcpcd_get_type, .get_path = nm_dhcp_dhcpcd_get_path, + .get_lease_ip_configs = NULL, }; #endif /* WITH_DHCPCD */ diff --git a/src/dhcp/nm-dhcp-helper.c b/src/dhcp/nm-dhcp-helper.c index 8ea55061..f50c5cec 100644 --- a/src/dhcp/nm-dhcp-helper.c +++ b/src/dhcp/nm-dhcp-helper.c @@ -134,6 +134,8 @@ main (int argc, char *argv[]) guint try_count = 0; gint64 time_end; + nm_g_type_init (); + /* FIXME: g_dbus_connection_new_for_address_sync() tries to connect to the socket in * non-blocking mode, which can easily fail with EAGAIN, causing the creation of the * socket to fail with "Could not connect: Resource temporarily unavailable". diff --git a/src/dhcp/nm-dhcp-listener.c b/src/dhcp/nm-dhcp-listener.c index d7d38e54..1cce5a1c 100644 --- a/src/dhcp/nm-dhcp-listener.c +++ b/src/dhcp/nm-dhcp-listener.c @@ -33,7 +33,7 @@ #include "nm-dhcp-client.h" #include "nm-dhcp-manager.h" #include "nm-core-internal.h" -#include "nm-dbus-manager.h" +#include "nm-bus-manager.h" #include "NetworkManagerUtils.h" #define PRIV_SOCK_PATH NMRUNDIR "/private-dhcp" @@ -60,7 +60,7 @@ const NMDhcpClientFactory *const _nm_dhcp_manager_factories[4] = { /*****************************************************************************/ typedef struct { - NMDBusManager * dbus_mgr; + NMBusManager * dbus_mgr; gulong new_conn_id; gulong dis_conn_id; GHashTable * connections; @@ -192,52 +192,70 @@ _method_call (GDBusConnection *connection, { NMDhcpListener *self = NM_DHCP_LISTENER (user_data); - if ( !nm_streq (interface_name, NM_DHCP_HELPER_SERVER_INTERFACE_NAME) - || !nm_streq (method_name, NM_DHCP_HELPER_SERVER_METHOD_NOTIFY)) { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_METHOD, - "Unknown method %s", - method_name); - return; - } + if (!nm_streq0 (interface_name, NM_DHCP_HELPER_SERVER_INTERFACE_NAME)) + g_return_if_reached (); + if (!nm_streq0 (method_name, NM_DHCP_HELPER_SERVER_METHOD_NOTIFY)) + g_return_if_reached (); + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) + g_return_if_reached (); _method_call_handle (self, parameters); + g_dbus_method_invocation_return_value (invocation, NULL); } -static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO ( - NM_DHCP_HELPER_SERVER_INTERFACE_NAME, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_GDBUS_METHOD_INFO ( - NM_DHCP_HELPER_SERVER_METHOD_NOTIFY, - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("data", "a{sv}"), - ), - ), - ), -); - static guint _dbus_connection_register_object (NMDhcpListener *self, GDBusConnection *connection, GError **error) { - static const GDBusInterfaceVTable interface_vtable = { + static GDBusArgInfo arg_info_notify_in = { + .ref_count = -1, + .name = "data", + .signature = "a{sv}", + .annotations = NULL, + }; + static GDBusArgInfo *arg_infos_notify[] = { + &arg_info_notify_in, + NULL, + }; + static GDBusMethodInfo method_info_notify = { + .ref_count = -1, + .name = NM_DHCP_HELPER_SERVER_METHOD_NOTIFY, + .in_args = arg_infos_notify, + .out_args = NULL, + .annotations = NULL, + }; + static GDBusMethodInfo *method_infos[] = { + &method_info_notify, + NULL, + }; + static GDBusInterfaceInfo interface_info = { + .ref_count = -1, + .name = NM_DHCP_HELPER_SERVER_INTERFACE_NAME, + .methods = method_infos, + .signals = NULL, + .properties = NULL, + .annotations = NULL, + }; + + static GDBusInterfaceVTable interface_vtable = { .method_call = _method_call, + .get_property = NULL, + .set_property = NULL, }; return g_dbus_connection_register_object (connection, NM_DHCP_HELPER_SERVER_OBJECT_PATH, - interface_info, - NM_UNCONST_PTR (GDBusInterfaceVTable, &interface_vtable), + &interface_info, + &interface_vtable, self, NULL, error); } static void -new_connection_cb (NMDBusManager *mgr, +new_connection_cb (NMBusManager *mgr, GDBusConnection *connection, GDBusObjectManager *manager, NMDhcpListener *self) @@ -260,7 +278,7 @@ new_connection_cb (NMDBusManager *mgr, } static void -dis_connection_cb (NMDBusManager *mgr, +dis_connection_cb (NMBusManager *mgr, GDBusConnection *connection, NMDhcpListener *self) { @@ -282,18 +300,18 @@ nm_dhcp_listener_init (NMDhcpListener *self) NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self); /* Maps GDBusConnection :: signal-id */ - priv->connections = g_hash_table_new (nm_direct_hash, NULL); + priv->connections = g_hash_table_new (NULL, NULL); - priv->dbus_mgr = nm_dbus_manager_get (); + priv->dbus_mgr = nm_bus_manager_get (); /* Register the socket our DHCP clients will return lease info on */ - nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); + nm_bus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); priv->new_conn_id = g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, + NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, G_CALLBACK (new_connection_cb), self); priv->dis_conn_id = g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, + NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, G_CALLBACK (dis_connection_cb), self); } diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index bf22872d..f5c7c84b 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -43,8 +43,8 @@ typedef struct { const NMDhcpClientFactory *client_factory; - char *default_hostname; - CList dhcp_client_lst_head; + GHashTable * clients; + char * default_hostname; } NMDhcpManagerPrivate; struct _NMDhcpManager { @@ -98,17 +98,21 @@ static NMDhcpClient * get_client_for_ifindex (NMDhcpManager *manager, int addr_family, int ifindex) { NMDhcpManagerPrivate *priv; - NMDhcpClient *client; + GHashTableIter iter; + gpointer value; g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); g_return_val_if_fail (ifindex > 0, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); - c_list_for_each_entry (client, &priv->dhcp_client_lst_head, dhcp_client_lst) { - if ( nm_dhcp_client_get_ifindex (client) == ifindex - && nm_dhcp_client_get_addr_family (client) == addr_family) - return client; + g_hash_table_iter_init (&iter, priv->clients); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + NMDhcpClient *candidate = NM_DHCP_CLIENT (value); + + if ( nm_dhcp_client_get_ifindex (candidate) == ifindex + && nm_dhcp_client_get_addr_family (candidate) == addr_family) + return candidate; } return NULL; @@ -125,19 +129,13 @@ static void remove_client (NMDhcpManager *self, NMDhcpClient *client) { g_signal_handlers_disconnect_by_func (client, client_state_changed, self); - c_list_unlink (&client->dhcp_client_lst); /* Stopping the client is left up to the controlling device * explicitly since we may want to quit NetworkManager but not terminate * the DHCP client. */ -} -static void -remove_client_unref (NMDhcpManager *self, NMDhcpClient *client) -{ - remove_client (self, client); - g_object_unref (client); + g_hash_table_remove (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client); } static void @@ -149,7 +147,7 @@ client_state_changed (NMDhcpClient *client, NMDhcpManager *self) { if (state >= NM_DHCP_STATE_TIMEOUT) - remove_client_unref (self, client); + remove_client (self, client); } static NMDhcpClient * @@ -158,12 +156,12 @@ client_start (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - GBytes *hwaddr, + const GByteArray *hwaddr, const char *uuid, guint32 route_table, guint32 route_metric, const struct in6_addr *ipv6_ll_addr, - GBytes *dhcp_client_id, + const char *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, const char *hostname, @@ -181,21 +179,23 @@ client_start (NMDhcpManager *self, g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (uuid != NULL, NULL); - g_return_val_if_fail (!dhcp_client_id || g_bytes_get_size (dhcp_client_id) >= 2, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + /* Ensure we have a usable DHCP client */ if (!priv->client_factory) return NULL; /* Kill any old client instance */ client = get_client_for_ifindex (self, addr_family, ifindex); if (client) { + g_object_ref (client); remove_client (self, client); nm_dhcp_client_stop (client, FALSE); g_object_unref (client); } + /* And make a new one */ client = g_object_new (priv->client_factory->get_type (), NM_DHCP_CLIENT_MULTI_IDX, multi_idx, NM_DHCP_CLIENT_ADDR_FAMILY, addr_family, @@ -206,26 +206,21 @@ client_start (NMDhcpManager *self, NM_DHCP_CLIENT_ROUTE_TABLE, (guint) route_table, NM_DHCP_CLIENT_ROUTE_METRIC, (guint) route_metric, NM_DHCP_CLIENT_TIMEOUT, (guint) timeout, - NM_DHCP_CLIENT_FLAGS, (guint) (0 - | (hostname_use_fqdn ? NM_DHCP_CLIENT_FLAGS_USE_FQDN : 0) - | (info_only ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY : 0) - ), NULL); - nm_assert (client && c_list_is_empty (&client->dhcp_client_lst)); - c_list_link_tail (&priv->dhcp_client_lst_head, &client->dhcp_client_lst); + g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client)); g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); if (addr_family == AF_INET) - success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address); + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, hostname_use_fqdn, last_ip4_address); else - success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, privacy, needed_prefixes); + success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy, needed_prefixes); if (!success) { - remove_client_unref (self, client); - return NULL; + remove_client (self, client); + client = NULL; } - return g_object_ref (client); + return client; } /* Caller owns a reference to the NMDhcpClient on return */ @@ -234,14 +229,14 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - GBytes *hwaddr, + const GByteArray *hwaddr, const char *uuid, guint32 route_table, guint32 route_metric, gboolean send_hostname, const char *dhcp_hostname, const char *dhcp_fqdn, - GBytes *dhcp_client_id, + const char *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, const char *last_ip_address) @@ -290,7 +285,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - GBytes *hwaddr, + const GByteArray *hwaddr, const struct in6_addr *ll_addr, const char *uuid, guint32 route_table, @@ -333,6 +328,31 @@ nm_dhcp_manager_set_default_hostname (NMDhcpManager *manager, const char *hostna priv->default_hostname = g_strdup (hostname); } +GSList * +nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, + NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + const char *uuid, + guint32 route_table, + guint32 route_metric) +{ + NMDhcpManagerPrivate *priv; + + g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (ifindex >= -1, NULL); + g_return_val_if_fail (uuid != NULL, NULL); + g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NULL); + + priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + if ( priv->client_factory + && priv->client_factory->get_lease_ip_configs) + return priv->client_factory->get_lease_ip_configs (multi_idx, addr_family, iface, ifindex, uuid, route_table, route_metric); + return NULL; +} + const char * nm_dhcp_manager_get_config (NMDhcpManager *self) { @@ -358,8 +378,6 @@ nm_dhcp_manager_init (NMDhcpManager *self) int i; const NMDhcpClientFactory *client_factory = NULL; - c_list_init (&priv->dhcp_client_lst_head); - for (i = 0; i < G_N_ELEMENTS (_nm_dhcp_manager_factories); i++) { const NMDhcpClientFactory *f = _nm_dhcp_manager_factories[i]; @@ -411,21 +429,38 @@ nm_dhcp_manager_init (NMDhcpManager *self) nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", client_factory->name); priv->client_factory = client_factory; + priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, + (GDestroyNotify) g_object_unref); } static void dispose (GObject *object) { - NMDhcpManager *self = NM_DHCP_MANAGER (object); - NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - NMDhcpClient *client, *client_safe; - - c_list_for_each_entry_safe (client, client_safe, &priv->dhcp_client_lst_head, dhcp_client_lst) - remove_client_unref (self, client); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE ((NMDhcpManager *) object); + GList *values, *iter; + + if (priv->clients) { + values = g_hash_table_get_values (priv->clients); + for (iter = values; iter; iter = g_list_next (iter)) + remove_client (NM_DHCP_MANAGER (object), NM_DHCP_CLIENT (iter->data)); + g_list_free (values); + } G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE ((NMDhcpManager *) object); + + g_free (priv->default_hostname); + + if (priv->clients) + g_hash_table_destroy (priv->clients); - nm_clear_g_free (&priv->default_hostname); + G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object); } static void @@ -433,5 +468,6 @@ nm_dhcp_manager_class_init (NMDhcpManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); + object_class->finalize = finalize; object_class->dispose = dispose; } diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index f8a7e31d..078117ff 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -49,14 +49,14 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager, struct _NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - GBytes *hwaddr, + const GByteArray *hwaddr, const char *uuid, guint32 route_table, guint32 route_metric, gboolean send_hostname, const char *dhcp_hostname, const char *dhcp_fqdn, - GBytes *dhcp_client_id, + const char *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, const char *last_ip_address); @@ -65,7 +65,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, struct _NMDedupMultiIndex *multi_idx, const char *iface, int ifindex, - GBytes *hwaddr, + const GByteArray *hwaddr, const struct in6_addr *ll_addr, const char *uuid, guint32 route_table, @@ -78,6 +78,15 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes); +GSList * nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, + struct _NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + const char *uuid, + guint32 route_table, + guint32 route_metric); + /* For testing only */ extern const char* nm_dhcp_helper_path; diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 4f37f069..f79b7cb1 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -29,7 +29,6 @@ #include <net/if_arp.h> #include "nm-utils/nm-dedup-multi.h" -#include "nm-utils/unaligned.h" #include "nm-utils.h" #include "nm-dhcp-utils.h" @@ -61,7 +60,8 @@ typedef struct { guint request_count; - bool privacy:1; + gboolean privacy; + gboolean info_only; } NMDhcpSystemdPrivate; struct _NMDhcpSystemd { @@ -451,6 +451,36 @@ get_leasefile_path (int addr_family, const char *iface, const char *uuid) iface); } +static GSList * +nm_dhcp_systemd_get_lease_ip_configs (NMDedupMultiIndex *multi_idx, + int addr_family, + const char *iface, + int ifindex, + const char *uuid, + guint32 route_table, + guint32 route_metric) +{ + GSList *leases = NULL; + gs_free char *path = NULL; + sd_dhcp_lease *lease = NULL; + NMIP4Config *ip4_config; + int r; + + if (addr_family != AF_INET) + return NULL; + + path = get_leasefile_path (addr_family, iface, uuid); + r = dhcp_lease_load (&lease, path); + if (r == 0 && lease) { + ip4_config = lease_to_ip4_config (multi_idx, iface, ifindex, lease, NULL, route_table, route_metric, FALSE, NULL); + if (ip4_config) + leases = g_slist_append (leases, ip4_config); + sd_dhcp_lease_unref (lease); + } + + return leases; +} + /*****************************************************************************/ static void @@ -554,16 +584,14 @@ dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data) } static guint16 -get_arp_type (GBytes *hwaddr) +get_arp_type (const GByteArray *hwaddr) { - switch (g_bytes_get_size (hwaddr)) { - case ETH_ALEN: + if (hwaddr->len == ETH_ALEN) return ARPHRD_ETHER; - case INFINIBAND_ALEN: + else if (hwaddr->len == INFINIBAND_ALEN) return ARPHRD_INFINIBAND; - default: + else return ARPHRD_NONE; - } } static gboolean @@ -572,7 +600,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (client); - GBytes *hwaddr; + const GByteArray *hwaddr; sd_dhcp_lease *lease = NULL; GBytes *override_client_id; const uint8_t *client_id = NULL; @@ -581,6 +609,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last const char *hostname; int r, i; gboolean success = FALSE; + guint16 arp_type; g_assert (priv->client4 == NULL); g_assert (priv->client6 == NULL); @@ -604,14 +633,16 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last hwaddr = nm_dhcp_client_get_hw_addr (client); if (hwaddr) { - const uint8_t *data; - gsize len; + arp_type= get_arp_type (hwaddr); + if (arp_type == ARPHRD_NONE) { + _LOGW ("failed to determine ARP type"); + goto error; + } - data = g_bytes_get_data (hwaddr, &len); r = sd_dhcp_client_set_mac (priv->client4, - data, - len, - get_arp_type (hwaddr)); + hwaddr->data, + hwaddr->len, + arp_type); if (r < 0) { _LOGW ("failed to set MAC address (%d)", r); goto error; @@ -630,6 +661,12 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last goto error; } + r = sd_dhcp_client_set_request_broadcast (priv->client4, true); + if (r < 0) { + _LOGW ("failed to enable broadcast mode (%d)", r); + goto error; + } + dhcp_lease_load (&lease, priv->lease_file); if (last_ip4_address) @@ -817,7 +854,7 @@ bound6_handle (NMDhcpSystemd *self) lease, options, TRUE, - nm_dhcp_client_get_info_only (NM_DHCP_CLIENT (self)), + priv->info_only, &error); if (ip6_config) { @@ -863,29 +900,24 @@ static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, + gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - GBytes *duid, + const GByteArray *duid, guint needed_prefixes) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (client); - GBytes *hwaddr; - const char *hostname; + const GByteArray *hwaddr; int r, i; - const guint8 *duid_arr; - gsize duid_len; g_assert (priv->client4 == NULL); g_assert (priv->client6 == NULL); g_return_val_if_fail (duid != NULL, FALSE); - duid_arr = g_bytes_get_data (duid, &duid_len); - if (!duid_arr || duid_len < 2) - g_return_val_if_reached (FALSE); - g_free (priv->lease_file); priv->lease_file = get_leasefile_path (AF_INET6, iface, nm_dhcp_client_get_uuid (client)); + priv->info_only = info_only; r = sd_dhcp6_client_new (&priv->client6); if (r < 0) { @@ -900,13 +932,16 @@ ip6_start (NMDhcpClient *client, _LOGT ("dhcp-client6: set %p", priv->client6); - if (nm_dhcp_client_get_info_only (client)) - sd_dhcp6_client_set_information_request (priv->client6, 1); + if (info_only) + sd_dhcp6_client_set_information_request (priv->client6, 1); + /* NM stores the entire DUID which includes the uint16 "type", while systemd + * wants the type passed separately from the following data. + */ r = sd_dhcp6_client_set_duid (priv->client6, - unaligned_read_be16 (&duid_arr[0]), - &duid_arr[2], - duid_len - 2); + ntohs (((const guint16 *) duid->data)[0]), + duid->data + 2, + duid->len - 2); if (r < 0) { _LOGW ("failed to set DUID (%d)", r); return FALSE; @@ -920,13 +955,9 @@ ip6_start (NMDhcpClient *client, hwaddr = nm_dhcp_client_get_hw_addr (client); if (hwaddr) { - const uint8_t *data; - gsize len; - - data = g_bytes_get_data (hwaddr, &len); r = sd_dhcp6_client_set_mac (priv->client6, - data, - len, + hwaddr->data, + hwaddr->len, get_arp_type (hwaddr)); if (r < 0) { _LOGW ("failed to set MAC address (%d)", r); @@ -958,13 +989,6 @@ ip6_start (NMDhcpClient *client, goto error; } - hostname = nm_dhcp_client_get_hostname (client); - r = sd_dhcp6_client_set_fqdn (priv->client6, hostname); - if (r < 0) { - _LOGW ("failed to set DHCP hostname to '%s' (%d)", hostname, r); - goto error; - } - r = sd_dhcp6_client_start (priv->client6); if (r < 0) { _LOGW ("failed to start client (%d)", r); @@ -982,14 +1006,12 @@ error: } static void -stop (NMDhcpClient *client, gboolean release, GBytes *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); int r = 0; - NM_DHCP_CLIENT_CLASS (nm_dhcp_systemd_parent_class)->stop (client, release, duid); - _LOGT ("dhcp-client%d: stop %p", priv->client4 ? '4' : '6', priv->client4 ? (gpointer) priv->client4 : (gpointer) priv->client6); @@ -1052,4 +1074,5 @@ const NMDhcpClientFactory _nm_dhcp_client_factory_internal = { .name = "internal", .get_type = nm_dhcp_systemd_get_type, .get_path = NULL, + .get_lease_ip_configs = nm_dhcp_systemd_get_lease_ip_configs, }; diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c index 9185a135..50ca2abe 100644 --- a/src/dhcp/nm-dhcp-utils.c +++ b/src/dhcp/nm-dhcp-utils.c @@ -721,15 +721,11 @@ error: } char * -nm_dhcp_utils_duid_to_string (GBytes *duid) +nm_dhcp_utils_duid_to_string (const GByteArray *duid) { - gconstpointer data; - gsize len; - g_return_val_if_fail (duid != NULL, NULL); - data = g_bytes_get_data (duid, &len); - return _nm_utils_bin2str (data, len, FALSE); + return _nm_utils_bin2str (duid->data, duid->len, FALSE); } /** diff --git a/src/dhcp/nm-dhcp-utils.h b/src/dhcp/nm-dhcp-utils.h index 5c127bd1..32140f48 100644 --- a/src/dhcp/nm-dhcp-utils.h +++ b/src/dhcp/nm-dhcp-utils.h @@ -39,7 +39,7 @@ NMIP6Config *nm_dhcp_utils_ip6_config_from_options (struct _NMDedupMultiIndex *m NMPlatformIP6Address nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options); -char *nm_dhcp_utils_duid_to_string (GBytes *duid); +char * nm_dhcp_utils_duid_to_string (const GByteArray *duid); GBytes * nm_dhcp_utils_client_id_string_to_bytes (const char *client_id); diff --git a/src/dhcp/tests/leases/basic.leases b/src/dhcp/tests/leases/basic.leases new file mode 100644 index 00000000..703d9247 --- /dev/null +++ b/src/dhcp/tests/leases/basic.leases @@ -0,0 +1,31 @@ +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} +lease { + interface "wlan0"; + fixed-address 10.77.52.141; + option subnet-mask 255.0.0.0; + option dhcp-lease-time 1200; + option routers 10.77.52.254; + option dhcp-message-type 5; + option dhcp-server-identifier 10.77.52.254; + option domain-name-servers 8.8.8.8,8.8.4.4; + option dhcp-renewal-time 600; + option dhcp-rebinding-time 1050; + option domain-name "morriesguest.local"; + renew 5 2013/11/01 20:01:08; + rebind 5 2013/11/01 20:05:00; + expire 5 2013/11/01 20:06:15; +} + diff --git a/src/dhcp/tests/leases/malformed1.leases b/src/dhcp/tests/leases/malformed1.leases new file mode 100644 index 00000000..401d982a --- /dev/null +++ b/src/dhcp/tests/leases/malformed1.leases @@ -0,0 +1,15 @@ +# missing fixed-address option +lease { + interface "wlan0"; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} + diff --git a/src/dhcp/tests/leases/malformed2.leases b/src/dhcp/tests/leases/malformed2.leases new file mode 100644 index 00000000..adf5f6de --- /dev/null +++ b/src/dhcp/tests/leases/malformed2.leases @@ -0,0 +1,15 @@ +# missing routers option +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} + diff --git a/src/dhcp/tests/leases/malformed3.leases b/src/dhcp/tests/leases/malformed3.leases new file mode 100644 index 00000000..a2afc8b6 --- /dev/null +++ b/src/dhcp/tests/leases/malformed3.leases @@ -0,0 +1,15 @@ +# missing expire time +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; +} + diff --git a/src/dhcp/tests/meson.build b/src/dhcp/tests/meson.build deleted file mode 100644 index 32badae8..00000000 --- a/src/dhcp/tests/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -test_units = [ - 'test-dhcp-dhclient', - 'test-dhcp-utils' -] - -foreach test_unit: test_units - exe = executable( - test_unit, - test_unit + '.c', - dependencies: test_nm_dep, - c_args: '-DTESTDIR="@0@"'.format(meson.current_source_dir()) - ) - - test( - 'dhcp/' + test_unit, - test_script, - args: test_args + [exe.full_path()] - ) -endforeach diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 25af51a1..f2e1f321 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -36,6 +36,12 @@ #include "nm-test-utils-core.h" +#define DEBUG 1 + +static const int IFINDEX = 5; +static const guint32 ROUTE_TABLE = RT_TABLE_MAIN; +static const guint32 ROUTE_METRIC = 100; + static void test_config (const char *orig, const char *expected, @@ -148,7 +154,7 @@ test_override_client_id (void) static const char *quote_client_id_expected = \ "# Created by NetworkManager\n" "\n" - "send dhcp-client-identifier \"\\x00abcd\"; # added by NetworkManager\n" + "send dhcp-client-identifier \"1234\"; # added by NetworkManager\n" "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" @@ -166,65 +172,7 @@ test_quote_client_id (void) { test_config (NULL, quote_client_id_expected, AF_INET, NULL, 0, FALSE, - "abcd", - NULL, - "eth0", - NULL); -} - -/*****************************************************************************/ - -static const char *quote_client_id_expected_2 = \ - "# Created by NetworkManager\n" - "\n" - "send dhcp-client-identifier 00:61:5c:62:63; # added by NetworkManager\n" - "\n" - "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" - "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" - "option wpad code 252 = string;\n" - "\n" - "also request rfc3442-classless-static-routes;\n" - "also request ms-classless-static-routes;\n" - "also request static-routes;\n" - "also request wpad;\n" - "also request ntp-servers;\n" - "\n"; - -static void -test_quote_client_id_2 (void) -{ - test_config (NULL, quote_client_id_expected_2, - AF_INET, NULL, 0, FALSE, - "a\\bc", - NULL, - "eth0", - NULL); -} - -/*****************************************************************************/ - -static const char *hex_zero_client_id_expected = \ - "# Created by NetworkManager\n" - "\n" - "send dhcp-client-identifier 00:11:22:33; # added by NetworkManager\n" - "\n" - "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" - "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" - "option wpad code 252 = string;\n" - "\n" - "also request rfc3442-classless-static-routes;\n" - "also request ms-classless-static-routes;\n" - "also request static-routes;\n" - "also request wpad;\n" - "also request ntp-servers;\n" - "\n"; - -static void -test_hex_zero_client_id (void) -{ - test_config (NULL, hex_zero_client_id_expected, - AF_INET, NULL, 0, FALSE, - "00:11:22:33", + "1234", NULL, "eth0", NULL); @@ -235,7 +183,7 @@ test_hex_zero_client_id (void) static const char *ascii_client_id_expected = \ "# Created by NetworkManager\n" "\n" - "send dhcp-client-identifier \"\\x00qb:cd:ef:12:34:56\"; # added by NetworkManager\n" + "send dhcp-client-identifier \"qb:cd:ef:12:34:56\"; # added by NetworkManager\n" "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" @@ -291,13 +239,13 @@ test_hex_single_client_id (void) /*****************************************************************************/ static const char *existing_hex_client_id_orig = \ - "send dhcp-client-identifier 10:30:04:20:7A:08;\n"; + "send dhcp-client-identifier 00:30:04:20:7A:08;\n"; static const char *existing_hex_client_id_expected = \ "# Created by NetworkManager\n" "# Merged from /path/to/dhclient.conf\n" "\n" - "send dhcp-client-identifier 10:30:04:20:7A:08;\n" + "send dhcp-client-identifier 00:30:04:20:7A:08;\n" "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" @@ -314,7 +262,7 @@ static void test_existing_hex_client_id (void) { gs_unref_bytes GBytes *new_client_id = NULL; - const guint8 bytes[] = { 0x10, 0x30, 0x04, 0x20, 0x7A, 0x08 }; + const guint8 bytes[] = { 0x00, 0x30, 0x04,0x20, 0x7A, 0x08 }; new_client_id = g_bytes_new (bytes, sizeof (bytes)); test_config (existing_hex_client_id_orig, existing_hex_client_id_expected, @@ -327,52 +275,16 @@ test_existing_hex_client_id (void) /*****************************************************************************/ -static const char *existing_escaped_client_id_orig = \ - "send dhcp-client-identifier \"\\044test\\xfe\";\n"; - -static const char *existing_escaped_client_id_expected = \ - "# Created by NetworkManager\n" - "# Merged from /path/to/dhclient.conf\n" - "\n" - "send dhcp-client-identifier \"\\044test\\xfe\";\n" - "\n" - "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" - "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" - "option wpad code 252 = string;\n" - "\n" - "also request rfc3442-classless-static-routes;\n" - "also request ms-classless-static-routes;\n" - "also request static-routes;\n" - "also request wpad;\n" - "also request ntp-servers;\n" - "\n"; - -static void -test_existing_escaped_client_id (void) -{ - gs_unref_bytes GBytes *new_client_id = NULL; - - new_client_id = g_bytes_new ("$test\xfe", 6); - test_config (existing_escaped_client_id_orig, existing_escaped_client_id_expected, - AF_INET, NULL, 0, FALSE, - NULL, - new_client_id, - "eth0", - NULL); -} - -/*****************************************************************************/ - #define EACID "qb:cd:ef:12:34:56" static const char *existing_ascii_client_id_orig = \ - "send dhcp-client-identifier \"\\x00" EACID "\";\n"; + "send dhcp-client-identifier \"" EACID "\";\n"; static const char *existing_ascii_client_id_expected = \ "# Created by NetworkManager\n" "# Merged from /path/to/dhclient.conf\n" "\n" - "send dhcp-client-identifier \"\\x00" EACID "\";\n" + "send dhcp-client-identifier \"" EACID "\";\n" "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" @@ -673,26 +585,23 @@ test_existing_multiline_alsoreq (void) static void test_one_duid (const char *escaped, const guint8 *unescaped, guint len) { - GBytes *t; + GByteArray *t; char *w; - gsize t_len; - gconstpointer t_arr; t = nm_dhcp_dhclient_unescape_duid (escaped); g_assert (t); - t_arr = g_bytes_get_data (t, &t_len); - g_assert (t_arr); - g_assert_cmpint (t_len, ==, len); - g_assert_cmpint (memcmp (t_arr, unescaped, len), ==, 0); - g_bytes_unref (t); + g_assert_cmpint (t->len, ==, len); + g_assert_cmpint (memcmp (t->data, unescaped, len), ==, 0); + g_byte_array_free (t, TRUE); - t = g_bytes_new_static (unescaped, len); + t = g_byte_array_sized_new (len); + g_byte_array_append (t, unescaped, len); w = nm_dhcp_dhclient_escape_duid (t); g_assert (w); g_assert_cmpint (strlen (escaped), ==, strlen (w)); g_assert_cmpstr (escaped, ==, w); - g_bytes_unref (t); + g_byte_array_free (t, TRUE); g_free (w); } @@ -731,23 +640,22 @@ test_read_duid_from_leasefile (void) { const guint8 expected[] = { 0x00, 0x01, 0x00, 0x01, 0x18, 0x79, 0xa6, 0x13, 0x60, 0x67, 0x20, 0xec, 0x4c, 0x70 }; - gs_unref_bytes GBytes *duid = NULL; + GByteArray *duid; GError *error = NULL; - gconstpointer duid_arr; - gsize duid_len; duid = nm_dhcp_dhclient_read_duid (TESTDIR "/test-dhclient-duid.leases", &error); g_assert_no_error (error); g_assert (duid); - duid_arr = g_bytes_get_data (duid, &duid_len); - g_assert_cmpint (duid_len, ==, sizeof (expected)); - g_assert_cmpint (memcmp (duid_arr, expected, duid_len), ==, 0); + g_assert_cmpint (duid->len, ==, sizeof (expected)); + g_assert_cmpint (memcmp (duid->data, expected, duid->len), ==, 0); + + g_byte_array_free (duid, TRUE); } static void test_read_commented_duid_from_leasefile (void) { - GBytes *duid; + GByteArray *duid; GError *error = NULL; duid = nm_dhcp_dhclient_read_duid (TESTDIR "/test-dhclient-commented-duid.leases", &error); @@ -846,12 +754,12 @@ test_write_existing_commented_duid (void) static const char *interface1_orig = \ "interface \"eth0\" {\n" - "\talso request my-option;\n" - "\tinitial-delay 5;\n" + " also request my-option;\n" + " initial-delay 5;\n" "}\n" "interface \"eth1\" {\n" - "\talso request another-option;\n" - "\tinitial-delay 0;\n" + " also request another-option;\n" + " initial-delay 0;\n" "}\n" "\n" "also request yet-another-option;\n"; @@ -890,12 +798,12 @@ test_interface1 (void) static const char *interface2_orig = \ "interface eth0 {\n" - "\talso request my-option;\n" - "\tinitial-delay 5;\n" + " also request my-option;\n" + " initial-delay 5;\n" " }\n" "interface eth1 {\n" - "\tinitial-delay 0;\n" - "\trequest another-option;\n" + " initial-delay 0;\n" + " request another-option;\n" " } \n" "\n" "also request yet-another-option;\n"; @@ -936,12 +844,12 @@ test_config_req_intf (void) { static const char *const orig = \ "request subnet-mask, broadcast-address, routers,\n" - "\trfc3442-classless-static-routes,\n" - "\tinterface-mtu, host-name, domain-name, domain-search,\n" - "\tdomain-name-servers, nis-domain, nis-servers,\n" - "\tnds-context, nds-servers, nds-tree-name,\n" - "\tnetbios-name-servers, netbios-dd-server,\n" - "\tnetbios-node-type, netbios-scope, ntp-servers;\n" + " rfc3442-classless-static-routes,\n" + " interface-mtu, host-name, domain-name, domain-search,\n" + " domain-name-servers, nis-domain, nis-servers,\n" + " nds-context, nds-servers, nds-tree-name,\n" + " netbios-name-servers, netbios-dd-server,\n" + " netbios-node-type, netbios-scope, ntp-servers;\n" ""; static const char *const expected = \ "# Created by NetworkManager\n" @@ -987,6 +895,133 @@ test_config_req_intf (void) /*****************************************************************************/ +static void +test_read_lease_ip4_config_basic (void) +{ + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); + GError *error = NULL; + char *contents = NULL; + gboolean success; + const char *path = TESTDIR "/leases/basic.leases"; + GSList *leases; + GDateTime *now; + NMIP4Config *config; + const NMPlatformIP4Address *addr; + guint32 expected_addr; + + success = g_file_get_contents (path, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Date from before the least expiration */ + now = g_date_time_new_utc (2013, 11, 1, 19, 55, 32); + leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); + g_assert_cmpint (g_slist_length (leases), ==, 2); + + /* IP4Config #1 */ + config = g_slist_nth_data (leases, 0); + g_assert (NM_IS_IP4_CONFIG (config)); + + /* Address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); + expected_addr = nmtst_inet4_from_string ("192.168.1.180"); + addr = _nmtst_ip4_config_get_address (config, 0); + g_assert_cmpint (addr->address, ==, expected_addr); + g_assert_cmpint (addr->peer_address, ==, expected_addr); + g_assert_cmpint (addr->plen, ==, 24); + + /* Gateway */ + expected_addr = nmtst_inet4_from_string ("192.168.1.1"); + g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr); + + /* DNS */ + g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 1); + expected_addr = nmtst_inet4_from_string ("192.168.1.1"); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); + + g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 0); + + /* IP4Config #2 */ + config = g_slist_nth_data (leases, 1); + g_assert (NM_IS_IP4_CONFIG (config)); + + /* Address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); + expected_addr = nmtst_inet4_from_string ("10.77.52.141"); + addr = _nmtst_ip4_config_get_address (config, 0); + g_assert_cmpint (addr->address, ==, expected_addr); + g_assert_cmpint (addr->peer_address, ==, expected_addr); + g_assert_cmpint (addr->plen, ==, 8); + + /* Gateway */ + expected_addr = nmtst_inet4_from_string ("10.77.52.254"); + g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr); + + /* DNS */ + g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 2); + expected_addr = nmtst_inet4_from_string ("8.8.8.8"); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); + expected_addr = nmtst_inet4_from_string ("8.8.4.4"); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 1), ==, expected_addr); + + /* Domains */ + g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 1); + g_assert_cmpstr (nm_ip4_config_get_domain (config, 0), ==, "morriesguest.local"); + + g_slist_free_full (leases, g_object_unref); + g_date_time_unref (now); + g_free (contents); +} + +static void +test_read_lease_ip4_config_expired (void) +{ + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); + GError *error = NULL; + char *contents = NULL; + gboolean success; + const char *path = TESTDIR "/leases/basic.leases"; + GSList *leases; + GDateTime *now; + + success = g_file_get_contents (path, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Date from *after* the lease expiration */ + now = g_date_time_new_utc (2013, 12, 1, 19, 55, 32); + leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); + g_assert (leases == NULL); + + g_date_time_unref (now); + g_free (contents); +} + +static void +test_read_lease_ip4_config_expect_failure (gconstpointer user_data) +{ + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); + GError *error = NULL; + char *contents = NULL; + gboolean success; + GSList *leases; + GDateTime *now; + + success = g_file_get_contents ((const char *) user_data, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Date from before the least expiration */ + now = g_date_time_new_utc (2013, 11, 1, 1, 1, 1); + leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now); + g_assert (leases == NULL); + + g_date_time_unref (now); + g_free (contents); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -996,13 +1031,10 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/orig_missing", test_orig_missing); g_test_add_func ("/dhcp/dhclient/override_client_id", test_override_client_id); - g_test_add_func ("/dhcp/dhclient/quote_client_id/1", test_quote_client_id); - g_test_add_func ("/dhcp/dhclient/quote_client_id/2", test_quote_client_id_2); - g_test_add_func ("/dhcp/dhclient/hex_zero_client_id", test_hex_zero_client_id); + g_test_add_func ("/dhcp/dhclient/quote_client_id", test_quote_client_id); g_test_add_func ("/dhcp/dhclient/ascii_client_id", test_ascii_client_id); g_test_add_func ("/dhcp/dhclient/hex_single_client_id", test_hex_single_client_id); g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id); - g_test_add_func ("/dhcp/dhclient/existing-client-id", test_existing_escaped_client_id); g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id); g_test_add_func ("/dhcp/dhclient/fqdn", test_fqdn); g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override); @@ -1024,6 +1056,18 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/write_existing_duid", test_write_existing_duid); g_test_add_func ("/dhcp/dhclient/write_existing_commented_duid", test_write_existing_commented_duid); + g_test_add_func ("/dhcp/dhclient/leases/ip4-config/basic", test_read_lease_ip4_config_basic); + g_test_add_func ("/dhcp/dhclient/leases/ip4-config/expired", test_read_lease_ip4_config_expired); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-address", + TESTDIR "/leases/malformed1.leases", + test_read_lease_ip4_config_expect_failure); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-gateway", + TESTDIR "/leases/malformed2.leases", + test_read_lease_ip4_config_expect_failure); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-expire", + TESTDIR "/leases/malformed3.leases", + test_read_lease_ip4_config_expect_failure); + return g_test_run (); } diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c index 617a3c6c..72f31191 100644 --- a/src/dhcp/tests/test-dhcp-utils.c +++ b/src/dhcp/tests/test-dhcp-utils.c @@ -349,7 +349,8 @@ test_dhclient_invalid_classless_routes_1 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*ignoring invalid classless static routes*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring invalid classless static routes*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -379,7 +380,8 @@ test_dhcpcd_invalid_classless_routes_1 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*ignoring invalid classless static routes*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring invalid classless static routes*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -411,7 +413,8 @@ test_dhclient_invalid_classless_routes_2 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*ignoring invalid classless static routes*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring invalid classless static routes*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -443,7 +446,8 @@ test_dhcpcd_invalid_classless_routes_2 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*ignoring invalid classless static routes*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring invalid classless static routes*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -475,7 +479,8 @@ test_dhclient_invalid_classless_routes_3 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*ignoring invalid classless static routes*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring invalid classless static routes*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -502,7 +507,8 @@ test_dhcpcd_invalid_classless_routes_3 (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*DHCP provided invalid classless static route*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*DHCP provided invalid classless static route*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); @@ -609,7 +615,8 @@ test_invalid_escaped_domain_searches (void) options = fill_table (generic_options, NULL); options = fill_table (data, options); - NMTST_EXPECT_NM_WARN ("*invalid domain search*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid domain search*"); ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_test_assert_expected_messages (); |