diff options
author | Patrik Flykt <patrik.flykt@linux.intel.com> | 2013-12-09 23:43:31 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-12-12 11:43:34 -0500 |
commit | 751246ee37cf0cd72baf378f1b9c1ac04f8b8c9b (patch) | |
tree | ee5131c370f84c57359904272f003b4bf03ba091 /src/libsystemd-dhcp/dhcp-client.c | |
parent | 51debc1e396a14d7c1204d8661c4eb1056c47670 (diff) |
dhcp: Add notification callback
Define a notification callback and events for stopping and client
lease expiry. Add functions to fetch IP parameters from a lease.
Diffstat (limited to 'src/libsystemd-dhcp/dhcp-client.c')
-rw-r--r-- | src/libsystemd-dhcp/dhcp-client.c | 112 |
1 files changed, 111 insertions, 1 deletions
diff --git a/src/libsystemd-dhcp/dhcp-client.c b/src/libsystemd-dhcp/dhcp-client.c index d03435b929..03a846df39 100644 --- a/src/libsystemd-dhcp/dhcp-client.c +++ b/src/libsystemd-dhcp/dhcp-client.c @@ -63,6 +63,8 @@ struct sd_dhcp_client { sd_event_source *timeout_t1; sd_event_source *timeout_t2; sd_event_source *timeout_expire; + sd_dhcp_client_cb_t cb; + void *userdata; DHCPLease *lease; }; @@ -75,6 +77,17 @@ static const uint8_t default_req_opts[] = { DHCP_OPTION_NTP_SERVER, }; +int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb, + void *userdata) +{ + assert_return(client, -EINVAL); + + client->cb = cb; + client->userdata = userdata; + + return 0; +} + int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { size_t i; @@ -143,8 +156,99 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, return 0; } +int sd_dhcp_client_get_address(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->address; + + break; + } + + 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; +} + +int sd_dhcp_client_prefixlen(const struct in_addr *addr) +{ + int len = 0; + uint32_t mask; + + assert_return(addr, -EADDRNOTAVAIL); + + mask = be32toh(addr->s_addr); + while (mask) { + len++; + mask = mask << 1; + } + + return len; +} + +int sd_dhcp_client_get_router(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->router; + + break; + } + + return 0; +} + static int client_notify(sd_dhcp_client *client, int event) { + if (client->cb) + client->cb(client, event, client->userdata); + return 0; } @@ -169,6 +273,8 @@ static int client_stop(sd_dhcp_client *client, int error) client->attempt = 1; + client_notify(client, error); + switch (client->state) { case DHCP_STATE_INIT: @@ -463,6 +569,10 @@ error: static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) { + sd_dhcp_client *client = userdata; + + client_stop(client, DHCP_EVENT_EXPIRED); + return 0; } @@ -848,7 +958,7 @@ error: int sd_dhcp_client_stop(sd_dhcp_client *client) { - return client_stop(client, 0); + return client_stop(client, DHCP_EVENT_STOP); } sd_dhcp_client *sd_dhcp_client_new(sd_event *event) |