void nm_dhcp_client_new_options (NMDHCPClient *self, GHashTable *options, const char *reason) { NMDHCPClientPrivate *priv; guint32 old_state; guint32 new_state; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_DHCP_CLIENT (self)); g_return_if_fail (options != NULL); g_return_if_fail (reason != NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); old_state = priv->state; new_state = string_to_state (reason); /* Clear old and save new DHCP options */ g_hash_table_remove_all (priv->options); g_hash_table_foreach (options, copy_option, priv->options); if (old_state == new_state) { /* dhclient will stay in the same state (or, really, provide the same * reason) for operations like RENEW and REBIND. We need to ensure * that triggers various DHCP lease change code, so we need to pass * along same-state transitions for these states. */ if ( new_state != DHC_BOUND4 && new_state != DHC_RENEW4 && new_state != DHC_REBIND4 && new_state != DHC_BOUND6 && new_state != DHC_RENEW6 && new_state != DHC_REBIND6) return; } /* Handle changed device state */ if (state_is_bound (new_state)) { /* Cancel the timeout if the DHCP client is now bound */ timeout_cleanup (self); } if (priv->ipv6) { nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 state changed %s -> %s", priv->iface, state_to_string (old_state), state_to_string (new_state)); } else { nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 state changed %s -> %s", priv->iface, state_to_string (old_state), state_to_string (new_state)); } dhcp_client_set_state (self, new_state, TRUE, FALSE); }
gboolean nm_dhcp_client_foreach_option (NMDHCPClient *self, GHFunc func, gpointer user_data) { NMDHCPClientPrivate *priv; GHashTableIter iter; gpointer iterkey, itervalue; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); g_return_val_if_fail (func != NULL, FALSE); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); if (!state_is_bound (priv->state)) { if (priv->ipv6) { nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); } else { nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface); } } g_hash_table_iter_init (&iter, priv->options); while (g_hash_table_iter_next (&iter, &iterkey, &itervalue)) { const char *key = iterkey, *value = itervalue; const char **p; static const char *filter_options[] = { "interface", "pid", "reason", "dhcp_message_type", NULL }; gboolean ignore = FALSE; /* Filter out stuff that's not actually new DHCP options */ for (p = filter_options; *p; p++) { if (!strcmp (*p, key) || !strncmp (key, OLD_TAG, strlen (OLD_TAG))) { ignore = TRUE; break; } } if (!ignore) { const char *tmp_key = key; /* Remove the "new_" prefix that dhclient passes back */ if (!strncmp (key, NEW_TAG, strlen (NEW_TAG))) tmp_key = key + strlen (NEW_TAG); func ((gpointer) tmp_key, (gpointer) value, user_data); } } return TRUE; }
void nm_dhcp_client_new_options (NMDHCPClient *self, GHashTable *options, const char *reason) { NMDHCPClientPrivate *priv; guint32 old_state; guint32 new_state; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_DHCP_CLIENT (self)); g_return_if_fail (options != NULL); g_return_if_fail (reason != NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); old_state = priv->state; new_state = string_to_state (reason); /* Clear old and save new DHCP options */ g_hash_table_remove_all (priv->options); g_hash_table_foreach (options, copy_option, priv->options); if (old_state == new_state) return; /* Handle changed device state */ if (state_is_bound (new_state)) { /* Cancel the timeout if the DHCP client is now bound */ timeout_cleanup (self); } if (priv->ipv6) { nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 state changed %s -> %s", priv->iface, state_to_string (old_state), state_to_string (new_state)); } else { nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 state changed %s -> %s", priv->iface, state_to_string (old_state), state_to_string (new_state)); } dhcp_client_set_state (self, new_state, TRUE, FALSE); }
NMIP6Config * nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) { NMDHCPClientPrivate *priv; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); if (test && !state_is_bound (priv->state)) { nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); return NULL; } if (!g_hash_table_size (priv->options)) { /* We never got a response from the DHCP client */ return NULL; } return ip6_options_to_config (self); }