static void test_discover_message(sd_event *e) { sd_dhcp_client *client; int res, r; if (verbose) printf("* %s\n", __FUNCTION__); r = sd_dhcp_client_new(&client, false); assert_se(r >= 0); assert_se(client); r = sd_dhcp_client_attach_event(client, e, 0); assert_se(r >= 0); assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0); assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0); callback_recv = test_discover_message_verify; res = sd_dhcp_client_start(client); assert_se(IN_SET(res, 0, -EINPROGRESS)); sd_event_run(e, (uint64_t) -1); sd_dhcp_client_stop(client); sd_dhcp_client_unref(client); test_fd[1] = safe_close(test_fd[1]); callback_recv = NULL; }
int sd_dhcp_client_set_mac(sd_dhcp_client *client, const struct ether_addr *addr) { bool need_restart = false; assert_return(client, -EINVAL); assert_return(addr, -EINVAL); if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0) return 0; if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { log_dhcp_client(client, "Changing MAC address on running DHCP " "client, restarting"); need_restart = true; client = client_stop(client, DHCP_EVENT_STOP); } if (!client) return 0; memcpy(&client->client_id.mac_addr, addr, ETH_ALEN); client->client_id.type = 0x01; if (need_restart && client->state != DHCP_STATE_STOPPED) sd_dhcp_client_start(client); return 0; }
static void test_addr_acq(sd_event *e) { usec_t time_now = now(CLOCK_MONOTONIC); sd_dhcp_client *client; int res, r; if (verbose) printf("* %s\n", __FUNCTION__); r = sd_dhcp_client_new(&client); assert_se(r >= 0); assert_se(client); r = sd_dhcp_client_attach_event(client, e, 0); assert_se(r >= 0); assert_se(sd_dhcp_client_set_index(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0); assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0); callback_recv = test_addr_acq_recv_discover; assert_se(sd_event_add_time(e, &test_hangcheck, CLOCK_MONOTONIC, time_now + 2 * USEC_PER_SEC, 0, test_dhcp_hangcheck, NULL) >= 0); res = sd_dhcp_client_start(client); assert_se(res == 0 || res == -EINPROGRESS); sd_event_loop(e); test_hangcheck = sd_event_source_unref(test_hangcheck); sd_dhcp_client_set_callback(client, NULL, NULL); sd_dhcp_client_stop(client); sd_dhcp_client_unref(client); test_fd[1] = safe_close(test_fd[1]); callback_recv = NULL; xid = 0; }
static void test_addr_acq(sd_event *e) { usec_t time_now = now(clock_boottime_or_monotonic()); sd_dhcp_client *client; int res, r; if (verbose) printf("* %s\n", __FUNCTION__); r = sd_dhcp_client_new(&client, false); assert_se(r >= 0); assert_se(client); r = sd_dhcp_client_attach_event(client, e, 0); assert_se(r >= 0); assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0); assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0); callback_recv = test_addr_acq_recv_discover; assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(), time_now + 2 * USEC_PER_SEC, 0, test_dhcp_hangcheck, NULL) >= 0); res = sd_dhcp_client_start(client); assert_se(IN_SET(res, 0, -EINPROGRESS)); assert_se(sd_event_loop(e) >= 0); test_hangcheck = sd_event_source_unref(test_hangcheck); assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0); assert_se(sd_dhcp_client_stop(client) >= 0); sd_dhcp_client_unref(client); test_fd[1] = safe_close(test_fd[1]); callback_recv = NULL; xid = 0; }
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; }