static int dhcp4_set_hostname(Link *link) { _cleanup_free_ char *hostname = NULL; const char *hn; int r; assert(link); if (!link->network->dhcp_send_hostname) hn = NULL; else if (link->network->dhcp_hostname) hn = link->network->dhcp_hostname; else { r = gethostname_strict(&hostname); if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */ return r; hn = hostname; } r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r == -EINVAL && hostname) /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */ log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); else if (r < 0) return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); return 0; }
static int dhcp4_set_hostname(Link *link) { _cleanup_free_ char *hostname = NULL; const char *hn; int r; assert(link); if (!link->network->dhcp_send_hostname) hn = NULL; else if (link->network->dhcp_hostname) hn = link->network->dhcp_hostname; else { r = gethostname_strict(&hostname); if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */ return r; hn = hostname; } return sd_dhcp_client_set_hostname(link->dhcp_client, hn); }
static void test_request_basic(sd_event *e) { int r; sd_dhcp_client *client; if (verbose) printf("* %s\n", __FUNCTION__); /* Initialize client without Anonymize settings. */ 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_request_option(NULL, 0) == -EINVAL); assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL); assert_se(sd_dhcp_client_set_ifindex(NULL, 0) == -EINVAL); assert_se(sd_dhcp_client_set_ifindex(client, 15) == 0); assert_se(sd_dhcp_client_set_ifindex(client, -42) == -EINVAL); assert_se(sd_dhcp_client_set_ifindex(client, -1) == -EINVAL); assert_se(sd_dhcp_client_set_ifindex(client, 0) == -EINVAL); assert_se(sd_dhcp_client_set_ifindex(client, 1) == 0); assert_se(sd_dhcp_client_set_hostname(client, "host") == 1); assert_se(sd_dhcp_client_set_hostname(client, "host.domain") == 1); assert_se(sd_dhcp_client_set_hostname(client, NULL) == 1); assert_se(sd_dhcp_client_set_hostname(client, "~host") == -EINVAL); assert_se(sd_dhcp_client_set_hostname(client, "~host.domain") == -EINVAL); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_ROUTER) == -EEXIST); /* This PRL option is not set when using Anonymize, but in this test * Anonymize settings are not being used. */ assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_HOST_NAME) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_DOMAIN_NAME) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_DOMAIN_NAME_SERVER) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PAD) == -EINVAL); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_END) == -EINVAL); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_MESSAGE_TYPE) == -EINVAL); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_OVERLOAD) == -EINVAL); assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST) == -EINVAL); /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the * default PRL when using Anonymize, so it is changed to other option * that is not set by default, to check that it was set successfully. * Options not set by default (using or not anonymize) are option 17 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */ assert_se(sd_dhcp_client_set_request_option(client, 17) == 0); assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, 42) == 0); assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST); sd_dhcp_client_unref(client); }
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; }
int dhcp4_configure(Link *link) { int r; assert(link); assert(link->network); assert(link->network->dhcp & ADDRESS_FAMILY_IPV4); r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) return r; r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) return r; r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) return r; r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); if (r < 0) return r; r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) return r; r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) return r; if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) return r; } if (link->network->dhcp_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU); if (r < 0) return r; } if (link->network->dhcp_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) return r; } if (link->network->dhcp_sendhost) { _cleanup_free_ char *hostname = NULL; const char *hn = NULL; if (!link->network->hostname) { hostname = gethostname_malloc(); if (!hostname) return -ENOMEM; hn = hostname; } else hn = link->network->hostname; if (!is_localhost(hn)) { r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r < 0) return r; } } if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) return r; } switch (link->network->dhcp_client_identifier) { case DHCP_CLIENT_ID_DUID: /* Library defaults to this. */ break; case DHCP_CLIENT_ID_MAC: r = sd_dhcp_client_set_client_id(link->dhcp_client, ARPHRD_ETHER, (const uint8_t *) &link->mac, sizeof (link->mac)); if (r < 0) return r; break; default: assert_not_reached("Unknown client identifier type."); } return 0; }
int dhcp4_configure(Link *link) { int r; assert(link); assert(link->network); assert(link->network->dhcp & ADDRESS_FAMILY_IPV4); if (!link->dhcp_client) { r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) return r; } r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) return r; r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) return r; r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); if (r < 0) return r; r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) return r; r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) return r; if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) return r; } if (link->network->dhcp_use_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU); if (r < 0) return r; } if (link->network->dhcp_use_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) return r; } /* Always acquire the timezone and NTP */ r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE); if (r < 0) return r; if (link->network->dhcp_send_hostname) { _cleanup_free_ char *hostname = NULL; const char *hn = NULL; if (!link->network->dhcp_hostname) { hostname = gethostname_malloc(); if (!hostname) return -ENOMEM; hn = hostname; } else hn = link->network->dhcp_hostname; if (!is_localhost(hn)) { r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r < 0) return r; } } if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) return r; } switch (link->network->dhcp_client_identifier) { case DHCP_CLIENT_ID_DUID: /* If configured, apply user specified DUID and/or IAID */ r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, link->network->iaid_value, link->manager->dhcp_duid_len, &link->manager->dhcp_duid); if (r < 0) return r; break; case DHCP_CLIENT_ID_MAC: r = sd_dhcp_client_set_client_id(link->dhcp_client, ARPHRD_ETHER, (const uint8_t *) &link->mac, sizeof (link->mac)); if (r < 0) return r; break; default: assert_not_reached("Unknown client identifier type."); } return 0; }
int dhcp4_configure(Link *link) { int r; assert(link); assert(link->network); assert(IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)); r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) return r; r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) return r; r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) return r; r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); if (r < 0) return r; r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) return r; r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) return r; if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) return r; } if (link->network->dhcp_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU); if (r < 0) return r; } if (link->network->dhcp_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) return r; } if (link->network->dhcp_sendhost) { _cleanup_free_ char *hostname = NULL; hostname = gethostname_malloc(); if (!hostname) return -ENOMEM; if (!is_localhost(hostname)) { r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname); if (r < 0) return r; } } if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) return r; } return 0; }
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; }