INFORMATION_REQ,
SOLICITATION,
REQUEST,
+ RENEW,
+ REBIND,
+ RELEASE,
} ClientState;
struct _GDHCPClient {
gpointer advertise_data;
GDHCPClientEventFunc request_cb;
gpointer request_data;
+ GDHCPClientEventFunc renew_cb;
+ gpointer renew_data;
+ GDHCPClientEventFunc rebind_cb;
+ gpointer rebind_data;
+ GDHCPClientEventFunc release_cb;
+ gpointer release_data;
char *last_address;
unsigned char *duid;
int duid_len;
uint32_t T1, T2;
struct in6_addr ia_na;
struct in6_addr ia_ta;
+ time_t last_renew;
+ time_t last_rebind;
+ time_t expire;
};
static inline void debug(GDHCPClient *client, const char *format, ...)
}
int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client,
- uint32_t *T1, uint32_t *T2)
+ uint32_t *T1, uint32_t *T2,
+ time_t *last_renew, time_t *last_rebind,
+ time_t *expire)
{
if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
return -EINVAL;
if (T2 != NULL)
*T2 = dhcp_client->T2;
+ if (last_renew != NULL)
+ *last_renew = dhcp_client->last_renew;
+
+ if (last_rebind != NULL)
+ *last_rebind = dhcp_client->last_rebind;
+
+ if (expire != NULL)
+ *expire = dhcp_client->expire;
+
return 0;
}
return send_dhcpv6_msg(dhcp_client, DHCPV6_REQUEST, "request");
}
+static int send_dhcpv6_renew(GDHCPClient *dhcp_client)
+{
+ return send_dhcpv6_msg(dhcp_client, DHCPV6_RENEW, "renew");
+}
+
+static int send_dhcpv6_rebind(GDHCPClient *dhcp_client)
+{
+ return send_dhcpv6_msg(dhcp_client, DHCPV6_REBIND, "rebind");
+}
+
+static int send_dhcpv6_release(GDHCPClient *dhcp_client)
+{
+ return send_dhcpv6_msg(dhcp_client, DHCPV6_RELEASE, "release");
+}
+
static int send_information_req(GDHCPClient *dhcp_client)
{
return send_dhcpv6_msg(dhcp_client, DHCPV6_INFORMATION_REQ,
dhcp_client->require_list = NULL;
dhcp_client->duid = NULL;
dhcp_client->duid_len = 0;
+ dhcp_client->last_renew = dhcp_client->last_rebind = time(0);
+ dhcp_client->expire = 0;
*error = G_DHCP_CLIENT_ERROR_NONE;
else
memcpy(&dhcp_client->ia_ta, &addr,
sizeof(struct in6_addr));
+
+ g_dhcpv6_client_set_expire(dhcp_client, valid);
}
return list;
break;
case INFORMATION_REQ:
case REQUEST:
+ case RENEW:
+ case REBIND:
+ case RELEASE:
if (dhcp_client->type != G_DHCP_IPV6)
return TRUE;
dhcp_client->request_data);
return TRUE;
}
+ if (dhcp_client->renew_cb != NULL) {
+ dhcp_client->renew_cb(dhcp_client,
+ dhcp_client->renew_data);
+ return TRUE;
+ }
+ if (dhcp_client->rebind_cb != NULL) {
+ dhcp_client->rebind_cb(dhcp_client,
+ dhcp_client->rebind_data);
+ return TRUE;
+ }
+ if (dhcp_client->release_cb != NULL) {
+ dhcp_client->release_cb(dhcp_client,
+ dhcp_client->release_data);
+ return TRUE;
+ }
break;
default:
break;
return re;
}
send_dhcpv6_request(dhcp_client);
+
+ } else if (dhcp_client->renew_cb) {
+ dhcp_client->state = RENEW;
+ 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_renew(dhcp_client);
+
+ } else if (dhcp_client->rebind_cb) {
+ dhcp_client->state = REBIND;
+ 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_rebind(dhcp_client);
+
+ } else if (dhcp_client->release_cb) {
+ dhcp_client->state = RENEW;
+ 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_release(dhcp_client);
}
return 0;
dhcp_client->request_cb = func;
dhcp_client->request_data = data;
return;
+ case G_DHCP_CLIENT_EVENT_RENEW:
+ if (dhcp_client->type == G_DHCP_IPV4)
+ return;
+ dhcp_client->renew_cb = func;
+ dhcp_client->renew_data = data;
+ return;
+ case G_DHCP_CLIENT_EVENT_REBIND:
+ if (dhcp_client->type == G_DHCP_IPV4)
+ return;
+ dhcp_client->rebind_cb = func;
+ dhcp_client->rebind_data = data;
+ return;
+ case G_DHCP_CLIENT_EVENT_RELEASE:
+ if (dhcp_client->type == G_DHCP_IPV4)
+ return;
+ dhcp_client->release_cb = func;
+ dhcp_client->release_data = data;
+ return;
}
}
case INFORMATION_REQ:
case SOLICITATION:
case REQUEST:
+ case RENEW:
+ case REBIND:
+ case RELEASE:
break;
}
return NULL;
}
}
+void g_dhcpv6_client_reset_renew(GDHCPClient *dhcp_client)
+{
+ if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
+ return;
+
+ dhcp_client->last_renew = time(0);
+}
+
+void g_dhcpv6_client_reset_rebind(GDHCPClient *dhcp_client)
+{
+ if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
+ return;
+
+ dhcp_client->last_rebind = time(0);
+}
+
+void g_dhcpv6_client_set_expire(GDHCPClient *dhcp_client, uint32_t timeout)
+{
+ if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
+ return;
+
+ dhcp_client->expire = time(0) + timeout;
+}
+
uint16_t g_dhcpv6_client_get_status(GDHCPClient *dhcp_client)
{
if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)