X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-network%2Fsd-dhcp-client.c;h=6b19666c3bc46707a44ce6aecb105be3d9635ef0;hb=ffc90a11962274ac597b7838f31a4aff0362aa46;hp=1603c41227ea72148cdbfe21ff23f0e4833c824f;hpb=574cc928887851269c5919123dbdf8e1b2713b23;p=elogind.git diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 1603c4122..6b19666c3 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -56,6 +56,7 @@ struct sd_dhcp_client { uint8_t type; struct ether_addr mac_addr; } _packed_ client_id; + char *hostname; uint32_t xid; usec_t start_time; uint16_t secs; @@ -178,6 +179,27 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, return 0; } +int sd_dhcp_client_set_hostname(sd_dhcp_client *client, + const char *hostname) { + char *new_hostname = NULL; + + assert_return(client, -EINVAL); + + if (streq_ptr(client->hostname, hostname)) + return 0; + + if (hostname) { + new_hostname = strdup(hostname); + if (!new_hostname) + return -ENOMEM; + } + + free(client->hostname); + client->hostname = new_hostname; + + return 0; +} + int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) { assert_return(client, -EINVAL); assert_return(ret, -EINVAL); @@ -386,6 +408,17 @@ static int client_send_discover(sd_dhcp_client *client) { return r; } + /* it is unclear from RFC 2131 if client should send hostname in + DHCPDISCOVER but dhclient does and so we do as well + */ + if (client->hostname) { + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_HOST_NAME, + strlen(client->hostname), client->hostname); + if (r < 0) + return r; + } + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, DHCP_OPTION_END, 0, NULL); if (r < 0) @@ -477,6 +510,14 @@ static int client_send_request(sd_dhcp_client *client) { return -EINVAL; } + if (client->hostname) { + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_HOST_NAME, + strlen(client->hostname), client->hostname); + if (r < 0) + return r; + } + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, DHCP_OPTION_END, 0, NULL); if (r < 0) @@ -710,7 +751,7 @@ static int client_start(sd_dhcp_client *client) { client->xid = random_u32(); - r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid); + r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr); if (r < 0) { client_stop(client, r); return r; @@ -754,7 +795,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) client->state = DHCP_STATE_REBINDING; client->attempt = 1; - r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid); + r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr); if (r < 0) { client_stop(client, r); return 0; @@ -776,7 +817,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, r = dhcp_network_bind_udp_socket(client->lease->address, DHCP_PORT_CLIENT); if (r < 0) { - client_stop(client, r); + log_dhcp_client(client, "could not bind UDP socket"); return 0; } @@ -879,7 +920,8 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, client->lease->subnet_mask != lease->subnet_mask || client->lease->router != lease->router) { r = DHCP_EVENT_IP_CHANGE; - } + } else + r = DHCP_EVENT_RENEW; client->lease = sd_dhcp_lease_unref(client->lease); } @@ -1363,6 +1405,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { sd_dhcp_lease_unref(client->lease); free(client->req_opts); + free(client->hostname); free(client); }