diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-01-05 13:38:10 +0200 |
---|---|---|
committer | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-01-05 13:17:26 +0100 |
commit | 3fd016f68a3d021d89fa7a1be1fa712e27e4913b (patch) | |
tree | 81f085800797c124b2aa9146041f5bd4061e4cdf /gdhcp | |
parent | 195007a210055b96f42f29348cbce02915dea242 (diff) | |
download | connman-3fd016f68a3d021d89fa7a1be1fa712e27e4913b.tar.gz connman-3fd016f68a3d021d89fa7a1be1fa712e27e4913b.tar.bz2 connman-3fd016f68a3d021d89fa7a1be1fa712e27e4913b.zip |
dhcpv6: Request message implemented.
Diffstat (limited to 'gdhcp')
-rw-r--r-- | gdhcp/client.c | 36 | ||||
-rw-r--r-- | gdhcp/gdhcp.h | 8 |
2 files changed, 43 insertions, 1 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c index 425f1cbf..a8fedb1f 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -71,6 +71,7 @@ typedef enum _dhcp_client_state { IPV4LL_DEFEND, INFORMATION_REQ, SOLICITATION, + REQUEST, } ClientState; struct _GDHCPClient { @@ -117,6 +118,8 @@ struct _GDHCPClient { gpointer solicitation_data; GDHCPClientEventFunc advertise_cb; gpointer advertise_data; + GDHCPClientEventFunc request_cb; + gpointer request_data; char *last_address; unsigned char *duid; int duid_len; @@ -779,6 +782,11 @@ static int send_solicitation(GDHCPClient *dhcp_client) return send_dhcpv6_msg(dhcp_client, DHCPV6_SOLICIT, "solicit"); } +static int send_dhcpv6_request(GDHCPClient *dhcp_client) +{ + return send_dhcpv6_msg(dhcp_client, DHCPV6_REQUEST, "request"); +} + static int send_information_req(GDHCPClient *dhcp_client) { return send_dhcpv6_msg(dhcp_client, DHCPV6_INFORMATION_REQ, @@ -1957,6 +1965,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, } break; case INFORMATION_REQ: + case REQUEST: if (dhcp_client->type != G_DHCP_IPV6) return TRUE; @@ -1967,7 +1976,10 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, option_len = 0; server_id = dhcpv6_get_option(packet6, pkt_len, G_DHCPV6_SERVERID, &option_len, &count); - if (server_id == NULL || count != 1 || option_len == 0) { + if (server_id == NULL || count != 1 || option_len == 0 || + (dhcp_client->server_duid_len > 0 && + memcmp(dhcp_client->server_duid, server_id, + dhcp_client->server_duid_len) != 0)) { /* RFC 3315, 15.10 */ debug(dhcp_client, "server duid error, discarding msg %p/%d/%d", @@ -1990,6 +2002,11 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, dhcp_client->information_req_data); return TRUE; } + if (dhcp_client->request_cb != NULL) { + dhcp_client->request_cb(dhcp_client, + dhcp_client->request_data); + return TRUE; + } break; default: break; @@ -2103,6 +2120,16 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) return re; } send_solicitation(dhcp_client); + + } else if (dhcp_client->request_cb) { + dhcp_client->state = REQUEST; + re = switch_listening_mode(dhcp_client, L3); + if (re != 0) { + switch_listening_mode(dhcp_client, L_NONE); + dhcp_client->state = 0; + return re; + } + send_dhcpv6_request(dhcp_client); } return 0; @@ -2235,6 +2262,12 @@ void g_dhcp_client_register_event(GDHCPClient *dhcp_client, dhcp_client->advertise_cb = func; dhcp_client->advertise_data = data; return; + case G_DHCP_CLIENT_EVENT_REQUEST: + if (dhcp_client->type == G_DHCP_IPV4) + return; + dhcp_client->request_cb = func; + dhcp_client->request_data = data; + return; } } @@ -2272,6 +2305,7 @@ char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client) case IPV4LL_ANNOUNCE: case INFORMATION_REQ: case SOLICITATION: + case REQUEST: break; } return NULL; diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index 56848549..22a28a54 100644 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -55,6 +55,7 @@ typedef enum { G_DHCP_CLIENT_EVENT_INFORMATION_REQ, G_DHCP_CLIENT_EVENT_SOLICITATION, G_DHCP_CLIENT_EVENT_ADVERTISE, + G_DHCP_CLIENT_EVENT_REQUEST, } GDHCPClientEvent; typedef enum { @@ -82,6 +83,13 @@ typedef enum { #define G_DHCPV6_DNS_SERVERS 23 #define G_DHCPV6_SNTP_SERVERS 31 +#define G_DHCPV6_ERROR_SUCCESS 0 +#define G_DHCPV6_ERROR_FAILURE 1 +#define G_DHCPV6_ERROR_NO_ADDR 2 +#define G_DHCPV6_ERROR_BINDING 3 +#define G_DHCPV6_ERROR_LINK 4 +#define G_DHCPV6_ERROR_MCAST 5 + typedef enum { G_DHCPV6_DUID_LLT = 1, G_DHCPV6_DUID_EN = 2, |