Define a notification callback and events for stopping and client lease expiry. Add functions to fetch IP parameters from a lease. --- src/dhcp/client.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/dhcp/client.h | 9 +++++ 2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/src/dhcp/client.c b/src/dhcp/client.c index 50008a9..0144c70 100644 --- a/src/dhcp/client.c +++ b/src/dhcp/client.c @@ -63,6 +63,8 @@ struct DHCPClient { sd_event_source *timeout_expire; sd_event_source *timeout_t1; sd_event_source *timeout_t2; + dhcp_client_cb_t cb; + void *userdata; DHCPLease *lease; }; @@ -75,6 +77,19 @@ static uint8_t default_req_opts[] = { DHCP_OPTION_NTP_SERVER, }; + +int dhcp_client_set_callback(DHCPClient *client, dhcp_client_cb_t cb, + void *userdata) +{ + if (!client) + return -EINVAL; + + client->cb = cb; + client->userdata = userdata; + + return 0; +} + int dhcp_client_set_request_option(DHCPClient *client, uint8_t option) { int i; @@ -157,8 +172,83 @@ int dhcp_client_set_mac(DHCPClient *client, struct ether_addr *addr) return 0; } +int dhcp_client_get_address(DHCPClient *client, struct in_addr *addr) +{ + if (!addr || !client) + return -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.s_addr; + + break; + } + + return 0; +} + +int dhcp_client_get_netmask(DHCPClient *client, struct in_addr *addr) +{ + if (!addr || !client) + return -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.s_addr; + + break; + } + + return 0; +} + +int dhcp_client_get_router(DHCPClient *client, struct in_addr *addr) +{ + if (!addr || !client) + return -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.s_addr; + + break; + } + + return 0; +} + static int client_notify(DHCPClient *client, int event) { + if (client->cb) + client->cb(client, event, client->userdata); + return 0; } @@ -195,6 +285,8 @@ static int client_stop(DHCPClient *client, int error) client->attempt = 1; + client_notify(client, error); + switch (client->state) { case DHCP_STATE_INIT: @@ -487,6 +579,10 @@ error: static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) { + DHCPClient *client = userdata; + + client_stop(client, DHCP_EVENT_EXPIRED); + return 0; } @@ -895,7 +991,7 @@ error: int dhcp_client_stop(DHCPClient *client) { - return client_stop(client, 0); + return client_stop(client, DHCP_EVENT_STOP); } DHCPClient *dhcp_client_new(sd_event *event) diff --git a/src/dhcp/client.h b/src/dhcp/client.h index 5ce7fb4..adb4443 100644 --- a/src/dhcp/client.h +++ b/src/dhcp/client.h @@ -26,19 +26,28 @@ #include "sd-event.h" +#define DHCP_EVENT_STOP 0 #define DHCP_EVENT_NAK 1 #define DHCP_EVENT_IP_ACQUIRE 2 #define DHCP_EVENT_IP_CHANGE 3 +#define DHCP_EVENT_EXPIRED 4 struct DHCPClient; typedef struct DHCPClient DHCPClient; +typedef void (*dhcp_client_cb_t)(DHCPClient *client, int event, void *userdata); +int dhcp_client_set_callback(DHCPClient *client, dhcp_client_cb_t cb, + void *userdata); int dhcp_client_set_request_option(DHCPClient *client, uint8_t option); int dhcp_client_set_request_address(DHCPClient *client, struct in_addr *last_address); int dhcp_client_set_index(DHCPClient *client, int interface_index); int dhcp_client_set_mac(DHCPClient *client, struct ether_addr *addr); +int dhcp_client_get_address(DHCPClient *client, struct in_addr *addr); +int dhcp_client_get_netmask(DHCPClient *client, struct in_addr *addr); +int dhcp_client_get_router(DHCPClient *client, struct in_addr *addr); + int dhcp_client_start(DHCPClient *client); int dhcp_client_stop(DHCPClient *client); DHCPClient *dhcp_client_new(sd_event *event); -- 1.7.10.4 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel