static void bound4_handle (NMDhcpSystemd *self) { NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); sd_dhcp_lease *lease; NMIP4Config *ip4_config; GHashTable *options; GError *error = NULL; int r; r = sd_dhcp_client_get_lease (priv->client4, &lease); if (r < 0 || !lease) { _LOGW ("no lease!"); nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); return; } _LOGD ("lease available"); options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); ip4_config = lease_to_ip4_config (iface, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)), lease, options, nm_dhcp_client_get_priority (NM_DHCP_CLIENT (self)), TRUE, &error); if (ip4_config) { const uint8_t *client_id = NULL; size_t client_id_len = 0; uint8_t type = 0; add_requests_to_options (options, dhcp4_requests); dhcp_lease_save (lease, priv->lease_file); sd_dhcp_client_get_client_id(priv->client4, &type, &client_id, &client_id_len); if (client_id) _save_client_id (self, type, client_id, client_id_len); nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_BOUND, G_OBJECT (ip4_config), options); } else { _LOGW ("%s", error->message); nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); g_clear_error (&error); } g_hash_table_destroy (options); g_clear_object (&ip4_config); }
static gboolean ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (client); const GByteArray *hwaddr; sd_dhcp_lease *lease = NULL; GBytes *override_client_id; const uint8_t *client_id = NULL; size_t client_id_len = 0; struct in_addr last_addr = { 0 }; const char *hostname, *fqdn; int r, i; gboolean success = FALSE; guint16 arp_type; g_assert (priv->client4 == NULL); g_assert (priv->client6 == NULL); g_free (priv->lease_file); priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), FALSE); r = sd_dhcp_client_new (&priv->client4); if (r < 0) { _LOGW ("failed to create client (%d)", r); return FALSE; } _LOGT ("dhcp-client4: set %p", priv->client4); r = sd_dhcp_client_attach_event (priv->client4, NULL, 0); if (r < 0) { _LOGW ("failed to attach event (%d)", r); goto error; } hwaddr = nm_dhcp_client_get_hw_addr (client); if (hwaddr) { arp_type= get_arp_type (hwaddr); if (arp_type == ARPHRD_NONE) { _LOGW ("failed to determine ARP type"); goto error; } r = sd_dhcp_client_set_mac (priv->client4, hwaddr->data, hwaddr->len, arp_type); if (r < 0) { _LOGW ("failed to set MAC address (%d)", r); goto error; } } r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client)); if (r < 0) { _LOGW ("failed to set ifindex (%d)", r); goto error; } r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client); if (r < 0) { _LOGW ("failed to set callback (%d)", r); 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) inet_pton (AF_INET, last_ip4_address, &last_addr); else if (lease) sd_dhcp_lease_get_address (lease, &last_addr); if (last_addr.s_addr) { r = sd_dhcp_client_set_request_address (priv->client4, &last_addr); if (r < 0) { _LOGW ("failed to set last IPv4 address (%d)", r); goto error; } } override_client_id = nm_dhcp_client_get_client_id (client); if (override_client_id) { client_id = g_bytes_get_data (override_client_id, &client_id_len); g_assert (client_id && client_id_len); sd_dhcp_client_set_client_id (priv->client4, client_id[0], client_id + 1, client_id_len - 1); } else if (lease) { r = sd_dhcp_lease_get_client_id (lease, (const void **) &client_id, &client_id_len); if (r == 0 && client_id_len) { sd_dhcp_client_set_client_id (priv->client4, client_id[0], client_id + 1, client_id_len - 1); _save_client_id (NM_DHCP_SYSTEMD (client), client_id[0], client_id + 1, client_id_len - 1); } } /* Add requested options */ for (i = 0; dhcp4_requests[i].name; i++) { if (dhcp4_requests[i].include) sd_dhcp_client_set_request_option (priv->client4, dhcp4_requests[i].num); } hostname = nm_dhcp_client_get_hostname (client); if (hostname) { char *prefix, *dot; prefix = strdup (hostname); dot = strchr (prefix, '.'); /* get rid of the domain */ if (dot) *dot = '\0'; r = sd_dhcp_client_set_hostname (priv->client4, prefix); free (prefix); if (r < 0) { _LOGW ("failed to set DHCP hostname (%d)", r); goto error; } } fqdn = nm_dhcp_client_get_fqdn (client); if (fqdn) { r = sd_dhcp_client_set_hostname (priv->client4, fqdn); if (r < 0) { _LOGW ("failed to set DHCP FQDN (%d)", r); goto error; } } r = sd_dhcp_client_start (priv->client4); if (r < 0) { _LOGW ("failed to start client (%d)", r); goto error; } nm_dhcp_client_start_timeout (client); success = TRUE; error: sd_dhcp_lease_unref (lease); if (!success) priv->client4 = sd_dhcp_client_unref (priv->client4); return success; }
static gboolean ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client); const char *iface = nm_dhcp_client_get_iface (client); const GByteArray *hwaddr; sd_dhcp_lease *lease = NULL; GBytes *override_client_id; const uint8_t *client_id = NULL; size_t client_id_len = 0; struct in_addr last_addr = { 0 }; const char *hostname; int r, i; gboolean success = FALSE; g_assert (priv->client4 == NULL); g_assert (priv->client6 == NULL); g_free (priv->lease_file); priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), FALSE); r = sd_dhcp_client_new (&priv->client4); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to create DHCPv4 client (%d)", iface, r); return FALSE; } r = sd_dhcp_client_attach_event (priv->client4, NULL, 0); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to attach DHCP event (%d)", iface, r); goto error; } hwaddr = nm_dhcp_client_get_hw_addr (client); if (hwaddr) { r = sd_dhcp_client_set_mac (priv->client4, hwaddr->data, hwaddr->len, get_arp_type (hwaddr)); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP MAC address (%d)", iface, r); goto error; } } r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client)); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP ifindex (%d)", iface, r); goto error; } r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP callback (%d)", iface, r); goto error; } r = sd_dhcp_client_set_request_broadcast (priv->client4, true); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP broadcast (%d)", iface, r); goto error; } dhcp_lease_load (&lease, priv->lease_file); if (last_ip4_address) inet_pton (AF_INET, last_ip4_address, &last_addr); else if (lease) sd_dhcp_lease_get_address (lease, &last_addr); if (last_addr.s_addr) { r = sd_dhcp_client_set_request_address (priv->client4, &last_addr); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set last IPv4 address (%d)", iface, r); goto error; } } override_client_id = nm_dhcp_client_get_client_id (client); if (override_client_id) { client_id = g_bytes_get_data (override_client_id, &client_id_len); g_assert (client_id && client_id_len); sd_dhcp_client_set_client_id (priv->client4, client_id[0], client_id + 1, client_id_len - 1); } else if (lease) { r = sd_dhcp_lease_get_client_id (lease, (const void **) &client_id, &client_id_len); if (r == 0 && client_id_len) { sd_dhcp_client_set_client_id (priv->client4, client_id[0], client_id + 1, client_id_len - 1); _save_client_id (NM_DHCP_SYSTEMD (client), client_id[0], client_id + 1, client_id_len - 1); } } /* Add requested options */ for (i = 0; dhcp4_requests[i].name; i++) { if (dhcp4_requests[i].include) sd_dhcp_client_set_request_option (priv->client4, dhcp4_requests[i].num); } hostname = nm_dhcp_client_get_hostname (client); if (hostname) { r = sd_dhcp_client_set_hostname (priv->client4, hostname); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP hostname (%d)", iface, r); goto error; } } r = sd_dhcp_client_start (priv->client4); if (r < 0) { nm_log_warn (LOGD_DHCP4, "(%s): failed to start DHCP (%d)", iface, r); goto error; } success = TRUE; error: sd_dhcp_lease_unref (lease); if (!success) priv->client4 = sd_dhcp_client_unref (priv->client4); return success; }