X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-dhcp-client.c;h=c5d8371a9831a36cf6cb077420ccf3c5cc29870d;hb=1346b1f0388f4100bb3c2a2bb23bc881769c020c;hp=1df89dc65111d2ece72766bb9e2cce203b8aef96;hpb=b087416f97a2662d290dde1cd68c3134317d0b1f;p=elogind.git diff --git a/src/libsystemd/sd-dhcp-client.c b/src/libsystemd/sd-dhcp-client.c index 1df89dc65..c5d8371a9 100644 --- a/src/libsystemd/sd-dhcp-client.c +++ b/src/libsystemd/sd-dhcp-client.c @@ -42,6 +42,8 @@ struct DHCPLease { be32_t subnet_mask; be32_t router; struct in_addr **dns; + uint16_t mtu; + char *hostname; }; typedef struct DHCPLease DHCPLease; @@ -186,10 +188,10 @@ int sd_dhcp_client_get_address(sd_dhcp_client *client, struct in_addr *addr) return 0; } -int sd_dhcp_client_get_netmask(sd_dhcp_client *client, struct in_addr *addr) +int sd_dhcp_client_get_mtu(sd_dhcp_client *client, uint16_t *mtu) { assert_return(client, -EINVAL); - assert_return(addr, -EINVAL); + assert_return(mtu, -EINVAL); switch (client->state) { case DHCP_STATE_INIT: @@ -202,7 +204,10 @@ int sd_dhcp_client_get_netmask(sd_dhcp_client *client, struct in_addr *addr) case DHCP_STATE_BOUND: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: - addr->s_addr = client->lease->subnet_mask; + if (client->lease->mtu) + *mtu = client->lease->mtu; + else + return -ENOENT; break; } @@ -237,6 +242,33 @@ int sd_dhcp_client_get_dns(sd_dhcp_client *client, struct in_addr ***addr) return 0; } +int sd_dhcp_client_get_hostname(sd_dhcp_client *client, const char **hostname) +{ + assert_return(client, -EINVAL); + assert_return(hostname, -EINVAL); + + switch (client->state) { + case DHCP_STATE_INIT: + case DHCP_STATE_SELECTING: + case DHCP_STATE_INIT_REBOOT: + case DHCP_STATE_REBOOTING: + case DHCP_STATE_REQUESTING: + return -EADDRNOTAVAIL; + + case DHCP_STATE_BOUND: + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + if (client->lease->hostname) + *hostname = client->lease->hostname; + else + return -ENOENT; + + break; + } + + return 0; +} + int sd_dhcp_client_prefixlen(const struct in_addr *addr) { int len = 0; @@ -277,6 +309,30 @@ int sd_dhcp_client_get_router(sd_dhcp_client *client, struct in_addr *addr) return 0; } +int sd_dhcp_client_get_netmask(sd_dhcp_client *client, struct in_addr *addr) +{ + assert_return(client, -EINVAL); + assert_return(addr, -EINVAL); + + switch (client->state) { + case DHCP_STATE_INIT: + case DHCP_STATE_SELECTING: + case DHCP_STATE_INIT_REBOOT: + case DHCP_STATE_REBOOTING: + case DHCP_STATE_REQUESTING: + return -EADDRNOTAVAIL; + + case DHCP_STATE_BOUND: + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + addr->s_addr = client->lease->subnet_mask; + + break; + } + + return 0; +} + static int client_notify(sd_dhcp_client *client, int event) { if (client->cb) @@ -788,6 +844,27 @@ static int client_parse_offer(uint8_t code, uint8_t len, const uint8_t *option, break; + case DHCP_OPTION_INTERFACE_MTU: + if (len >= 2) { + be16_t mtu; + + memcpy(&mtu, option, 2); + lease->mtu = be16toh(mtu); + + if (lease->mtu < 68) + lease->mtu = 0; + } + + break; + + case DHCP_OPTION_HOST_NAME: + if (len >= 1) { + free(lease->hostname); + lease->hostname = strndup((const char *)option, len); + } + + break; + case DHCP_OPTION_RENEWAL_T1_TIME: if (len == 4) { memcpy(&val, option, 4);