/****************************************************************************
 * apps/netutils/dhcp6c/dhcp6c.c
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.  The
 * ASF licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <nuttx/config.h>
#include <nuttx/compiler.h>

#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <limits.h>
#include <resolv.h>
#include <string.h>
#include <unistd.h>
#include <debug.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <malloc.h>
#include <pthread.h>
#include <sys/time.h>
#include <nuttx/clock.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <arpa/inet.h>

#include "netutils/netlib.h"
#include "netutils/dhcp6c.h"

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#define DHCPV6_ALL_RELAYS {{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02}}}
#define DHCPV6_CLIENT_PORT 546
#define DHCPV6_SERVER_PORT 547
#define DHCPV6_DUID_LLADDR 3
#define DHCPV6_REQ_DELAY 1

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#define dhcpv6_for_each_option(_o, start, end, otype, olen, odata)\
    for ((_o) = (FAR uint8_t *)(start); (_o) + 4 <= (FAR uint8_t *)(end) &&\
        ((otype) = (_o)[0] << 8 | (_o)[1]) && ((odata) = (FAR void *)&(_o)[4]) &&\
        ((olen) = (_o)[2] << 8 | (_o)[3]) + (odata) <= (FAR uint8_t *)(end); \
        (_o) += 4 + ((_o)[2] << 8 | (_o)[3]))

/****************************************************************************
 * Private Types
 ****************************************************************************/

enum dhcpv6_opt_e
{
  DHCPV6_OPT_CLIENTID = 1,
  DHCPV6_OPT_SERVERID = 2,
  DHCPV6_OPT_IA_NA = 3,
  DHCPV6_OPT_IA_ADDR = 5,
  DHCPV6_OPT_ORO = 6,
  DHCPV6_OPT_PREF = 7,
  DHCPV6_OPT_ELAPSED = 8,
  DHCPV6_OPT_RELAY_MSG = 9,
  DHCPV6_OPT_AUTH = 11,
  DHCPV6_OPT_STATUS = 13,
  DHCPV6_OPT_RAPID_COMMIT = 14,
  DHCPV6_OPT_RECONF_MESSAGE = 19,
  DHCPV6_OPT_RECONF_ACCEPT = 20,
  DHCPV6_OPT_DNS_SERVERS = 23,
  DHCPV6_OPT_DNS_DOMAIN = 24,
  DHCPV6_OPT_IA_PD = 25,
  DHCPV6_OPT_IA_PREFIX = 26,
  DHCPV6_OPT_INFO_REFRESH = 32,
  DHCPV6_OPT_FQDN = 39,
  DHCPV6_OPT_NTP_SERVER = 56,
  DHCPV6_OPT_SIP_SERVER_D = 21,
  DHCPV6_OPT_SIP_SERVER_A = 22,
};

enum dhcpv6_opt_npt_e
{
  NTP_SRV_ADDR = 1,
  NTP_MC_ADDR = 2,
  NTP_SRV_FQDN = 3
};

enum dhcpv6_msg_e
{
  DHCPV6_MSG_UNKNOWN = 0,
  DHCPV6_MSG_SOLICIT = 1,
  DHCPV6_MSG_ADVERT = 2,
  DHCPV6_MSG_REQUEST = 3,
  DHCPV6_MSG_RENEW = 5,
  DHCPV6_MSG_REBIND = 6,
  DHCPV6_MSG_REPLY = 7,
  DHCPV6_MSG_RELEASE = 8,
  DHCPV6_MSG_DECLINE = 9,
  DHCPV6_MSG_RECONF = 10,
  DHCPV6_MSG_INFO_REQ = 11,
  DHCPV6_MSG_MAX
};

enum dhcpv6_status_e
{
  DHCPV6_NOADDRSAVAIL = 2,
  DHCPV6_NOPREFIXAVAIL = 6
};

enum dhcpv6_mode_e
{
  DHCPV6_UNKNOWN,
  DHCPV6_STATELESS,
  DHCPV6_STATEFUL
};

enum dhcpv6_state_e
{
  STATE_CLIENT_ID,
  STATE_SERVER_ID,
  STATE_SERVER_CAND,
  STATE_ORO,
  STATE_DNS,
  STATE_SEARCH,
  STATE_IA_NA,
  STATE_IA_PD,
  STATE_CUSTOM_OPTS,
  STATE_SNTP_IP,
  STATE_SNTP_FQDN,
  STATE_SIP_IP,
  STATE_SIP_FQDN,
  STATE_MAX
};

enum dhcp6c_ia_mode_e
{
  IA_MODE_NONE,
  IA_MODE_TRY,
  IA_MODE_FORCE,
};

/* DHCPV6 Protocol Headers */

begin_packed_struct struct dhcpv6_header_s
{
  uint8_t msg_type;
  uint8_t tr_id[3];
} end_packed_struct;

begin_packed_struct struct dhcpv6_ia_hdr_s
{
  uint16_t type;
  uint16_t len;
  uint32_t iaid;
  uint32_t t1;
  uint32_t t2;
} end_packed_struct;

begin_packed_struct struct dhcpv6_ia_addr_s
{
  uint16_t type;
  uint16_t len;
  struct in6_addr addr;
  uint32_t preferred;
  uint32_t valid;
} end_packed_struct;

begin_packed_struct struct dhcpv6_ia_prefix_s
{
  uint16_t type;
  uint16_t len;
  uint32_t preferred;
  uint32_t valid;
  uint8_t prefix;
  struct in6_addr addr;
} end_packed_struct;

struct dhcpv6_server_cand_s
{
  bool has_noaddravail;
  bool wants_reconfigure;
  int16_t preference;
  uint8_t duid_len;
  uint8_t duid[130];
};

struct dhcp6c_retx_s
{
  bool delay;
  uint8_t init_timeo;
  uint16_t max_timeo;
  char name[8];
  int(*handler_reply)(FAR void *handle, enum dhcpv6_msg_e orig,
                      FAR const void *opt, FAR const void *end,
                      uint32_t elapsed);
  int(*handler_finish)(FAR void *handle, uint32_t elapsed);
};

struct dhcp6c_state_s
{
  pthread_t thread;
  bool cancel;
  dhcp6c_callback_t callback;
  int sockfd;
  int urandom_fd;
  int ifindex;
  time_t t1;
  time_t t2;
  time_t t3;
  bool request_prefix;
  enum dhcp6c_ia_mode_e ia_mode;
  bool accept_reconfig;
  FAR uint8_t *state_data[STATE_MAX];
  size_t state_len[STATE_MAX];
};

/****************************************************************************
 * Private Function Prototypes
 ****************************************************************************/

static int dhcp6c_handle_reconfigure(FAR void *handle,
                                     enum dhcpv6_msg_e orig,
                                     FAR const void *opt,
                                     FAR const void *end,
                                     uint32_t elapsed);
static int dhcp6c_handle_advert(FAR void *handle, enum dhcpv6_msg_e orig,
                                FAR const void *opt, FAR const void *end,
                                uint32_t elapsed);
static int dhcp6c_commit_advert(FAR void *handle, uint32_t elapsed);
static int dhcp6c_handle_reply(FAR void *handle, enum dhcpv6_msg_e orig,
                               FAR const void *opt, FAR const void *end,
                               uint32_t elapsed);
static int dhcp6c_handle_rebind_reply(FAR void *handle,
                                      enum dhcpv6_msg_e orig,
                                      FAR const void *opt,
                                      FAR const void *end,
                                      uint32_t elapsed);

/****************************************************************************
 * Private Data
 ****************************************************************************/

/* RFC 3315 - 5.5 Timeout and Delay values */

static const struct dhcp6c_retx_s g_dhcp6c_retx[DHCPV6_MSG_MAX] =
{
  {false, 1, 120, "<POLL>", dhcp6c_handle_reconfigure, NULL},
  {true, 1, 120, "SOLICIT", dhcp6c_handle_advert, dhcp6c_commit_advert},
  {0},
  {true, 1, 30, "REQUEST", dhcp6c_handle_reply, NULL},
  {0},
  {false, 10, 600, "RENEW", dhcp6c_handle_reply, NULL},
  {false, 10, 600, "REBIND", dhcp6c_handle_rebind_reply, NULL},
  {0},
  {false, 1, 600, "RELEASE", NULL, NULL},
  {false, 1, 3, "DECLINE", NULL, NULL},
  {0},
  {true, 1, 120, "INFOREQ", dhcp6c_handle_reply, NULL},
};

/****************************************************************************
 * Private Functions
 ****************************************************************************/

static uint64_t dhcp6c_get_milli_time(void)
{
  struct timespec t;

  clock_gettime(CLOCK_MONOTONIC, &t);

  return t.tv_sec * MSEC_PER_SEC + t.tv_nsec / USEC_PER_SEC;
}

static FAR uint8_t *dhcp6c_resize_state(FAR void *handle,
                                        enum dhcpv6_state_e state,
                                        ssize_t len)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  FAR uint8_t *n;

  if (len == 0)
    {
      return pdhcp6c->state_data[state] + pdhcp6c->state_len[state];
    }

  n = realloc(pdhcp6c->state_data[state], pdhcp6c->state_len[state] + len);
  if (n != NULL || pdhcp6c->state_len[state] + len == 0)
    {
      pdhcp6c->state_data[state] = n;
      n += pdhcp6c->state_len[state];
      pdhcp6c->state_len[state] += len;
    }

  return n;
}

static void dhcp6c_clear_state(FAR void *handle, enum dhcpv6_state_e state)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;

  pdhcp6c->state_len[state] = 0;
}

static void dhcp6c_add_state(FAR void *handle, enum dhcpv6_state_e state,
                             FAR const void *data, size_t len)
{
  FAR uint8_t *n = dhcp6c_resize_state(handle, state, len);

  if (n != NULL)
    {
      memcpy(n, data, len);
    }
}

static size_t dhcp6c_remove_state(FAR void *handle,
                                  enum dhcpv6_state_e state,
                                  size_t offset, size_t len)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  FAR uint8_t *data = pdhcp6c->state_data[state];
  ssize_t len_after = pdhcp6c->state_len[state] - (offset + len);

  if (len_after < 0)
    {
      return pdhcp6c->state_len[state];
    }

  memmove(data + offset, data + offset + len, len_after);

  return pdhcp6c->state_len[state] -= len;
}

static bool dhcp6c_commit_state(FAR void *handle, enum dhcpv6_state_e state,
                                size_t old_len)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  size_t new_len = pdhcp6c->state_len[state] - old_len;
  FAR uint8_t *old_data = pdhcp6c->state_data[state];
  FAR uint8_t *new_data = old_data + old_len;
  bool upd = (new_len != old_len) ||
             (memcmp(old_data, new_data, new_len) != 0);

  memmove(old_data, new_data, new_len);
  dhcp6c_resize_state(handle, state, -old_len);

  return upd;
}

static FAR void *dhcp6c_get_state(FAR void *handle,
                                  enum dhcpv6_state_e state,
                                  FAR size_t *len)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;

  *len = pdhcp6c->state_len[state];
  return pdhcp6c->state_data[state];
}

static void dhcp6c_get_result(FAR void *handle,
                              FAR struct dhcp6c_state *presult)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  size_t s_len;
  FAR uint8_t *s_data;
  uint16_t olen;
  uint16_t otype;
  FAR uint8_t *ite;
  FAR uint8_t *odata;
  FAR struct dhcpv6_ia_addr_s *addr;
  FAR struct dhcpv6_ia_prefix_s *pd;
  FAR struct in6_addr *dns;
  char addr_str[INET6_ADDRSTRLEN];

  if (handle == NULL || presult == NULL)
    {
      return;
    }

  s_data = dhcp6c_get_state(handle, STATE_IA_NA, &s_len);
  dhcpv6_for_each_option(ite, s_data, s_data + s_len, otype, olen, odata)
    {
      addr = (FAR void *)(odata - 4);
      memcpy(&presult->addr, &addr->addr, sizeof(presult->addr));
      inet_ntop(AF_INET6, &presult->addr, addr_str, sizeof(addr_str));
      ninfo("IA_NA %s for iface %i\n", addr_str, pdhcp6c->ifindex);
    }

  s_data = dhcp6c_get_state(handle, STATE_IA_PD, &s_len);
  dhcpv6_for_each_option(ite, s_data, s_data + s_len, otype, olen, odata)
    {
      pd = (FAR void *)(odata - 4);
      memcpy(&presult->pd, &pd->addr, sizeof(presult->pd));
      presult->pl = pd->prefix;
      netlib_prefix2ipv6netmask(presult->pl, &presult->netmask);
      inet_ntop(AF_INET6, &presult->pd, addr_str, sizeof(addr_str));
      ninfo("IA_PD %s for iface %i\n", addr_str, pdhcp6c->ifindex);
      inet_ntop(AF_INET6, &presult->netmask, addr_str, sizeof(addr_str));
      ninfo("netmask %s for iface %i\n", addr_str, pdhcp6c->ifindex);
    }

  dns = dhcp6c_get_state(handle, STATE_DNS, &s_len);
  memcpy(&presult->dns, dns, sizeof(presult->dns));
  inet_ntop(AF_INET6, &presult->dns, addr_str, sizeof(addr_str));
  ninfo("DNS server %s for iface %i\n", addr_str, pdhcp6c->ifindex);

  presult->t1 = pdhcp6c->t1;
  presult->t2 = pdhcp6c->t2;
  ninfo("T1:%d T2:%d for iface %i\n", presult->t1, presult->t2,
        pdhcp6c->ifindex);
}

static void dhcp6c_switch_process(FAR void *handle, FAR const char *name)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  struct dhcp6c_state result;

  ninfo("Process switch to %s\n", name);

  /* Delete lost prefixes and user opts */

  dhcp6c_clear_state(handle, STATE_CUSTOM_OPTS);

  if (pdhcp6c->callback != NULL)
    {
      memset(&result, 0, sizeof(result));
      dhcp6c_get_result(pdhcp6c, &result);
      pdhcp6c->callback(&result);
    }
}

static void dhcp6c_remove_addrs(FAR void *handle)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  size_t ia_na_len;
  FAR uint8_t *ite;
  FAR uint8_t *odata;
  FAR uint8_t *ia_na = dhcp6c_get_state(handle, STATE_IA_NA, &ia_na_len);
  uint16_t otype;
  uint16_t olen;
  FAR struct dhcpv6_ia_addr_s *addr;
  char addr_str[INET6_ADDRSTRLEN];

  dhcpv6_for_each_option(ite, ia_na, ia_na + ia_na_len, otype, olen, odata)
    {
      addr = (FAR void *)(odata - 4);
      inet_ntop(AF_INET6, &addr->addr, addr_str, sizeof(addr_str));
      ninfo("removing address %s/128 for iface %i\n",
            addr_str, pdhcp6c->ifindex);
    }
}

static void dhcp6c_set_iov(FAR struct iovec *piov,
                           FAR void *base, size_t len)
{
  piov->iov_base = base;
  piov->iov_len = len;
}

static void dhcp6c_send(FAR void *handle, enum dhcpv6_msg_e type,
                        uint8_t trid[3], uint32_t ecs)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  char fqdn_buf[256];
  struct
  {
    uint16_t type;
    uint16_t len;
    uint8_t flags;
    uint8_t data[256];
  } fqdn;

  size_t fqdn_len;
  size_t cl_id_len;
  FAR void *cl_id;
  size_t srv_id_len;
  FAR void *srv_id;
  size_t ia_pd_len;
  FAR void *ia_pd;
  struct dhcpv6_ia_hdr_s hdr_ia_pd;
  struct dhcpv6_ia_prefix_s pref;
  size_t ia_na_len;
  FAR void *ia_na;
  struct dhcpv6_ia_hdr_s hdr_ia_na;
  struct
  {
    uint16_t type;
    uint16_t length;
  } reconf_accept;

  uint16_t oro_refresh;
  size_t oro_len;
  FAR void *oro;
  struct
  {
    uint8_t type;
    uint8_t trid[3];
    uint16_t elapsed_type;
    uint16_t elapsed_len;
    uint16_t elapsed_value;
    uint16_t oro_type;
    uint16_t oro_len;
  } hdr;

  struct iovec iov[11];
  size_t cnt;
  struct sockaddr_in6 dest =
  {
    AF_INET6, htons(DHCPV6_SERVER_PORT),
    0, DHCPV6_ALL_RELAYS, pdhcp6c->ifindex
  };

  struct msghdr msg;

  /* Build FQDN */

  gethostname(fqdn_buf, sizeof(fqdn_buf));
  fqdn_len = 5 + dn_comp(fqdn_buf, fqdn.data, sizeof(fqdn.data), NULL, NULL);
  fqdn.type = htons(DHCPV6_OPT_FQDN);
  fqdn.len = htons(fqdn_len - 4);
  fqdn.flags = 0;

  /* Build Client ID */

  cl_id = dhcp6c_get_state(handle, STATE_CLIENT_ID, &cl_id_len);

  /* Build Server ID */

  srv_id = dhcp6c_get_state(handle, STATE_SERVER_ID, &srv_id_len);

  /* Build IA_PDs */

  ia_pd = dhcp6c_get_state(handle, STATE_IA_PD, &ia_pd_len);
  hdr_ia_pd.type = htons(DHCPV6_OPT_IA_PD);
  hdr_ia_pd.len = htons(sizeof(hdr_ia_pd) - 4 + ia_pd_len);
  hdr_ia_pd.iaid = 1;
  hdr_ia_pd.t1 = 0;
  hdr_ia_pd.t2 = 0;
  pref.type = htons(DHCPV6_OPT_IA_PREFIX);
  pref.len = htons(25);
  pref.prefix = pdhcp6c->request_prefix;

  if (ia_pd_len == 0 && pdhcp6c->request_prefix &&
      (type == DHCPV6_MSG_SOLICIT || type == DHCPV6_MSG_REQUEST))
    {
      ia_pd = &pref;
      ia_pd_len = sizeof(pref);
    }

  /* Build IA_NAs */

  ia_na = dhcp6c_get_state(handle, STATE_IA_NA, &ia_na_len);
  hdr_ia_na.type = htons(DHCPV6_OPT_IA_NA);
  hdr_ia_na.len = htons(sizeof(hdr_ia_na) - 4 + ia_na_len);
  hdr_ia_na.iaid = 1;
  hdr_ia_na.t1 = 0;
  hdr_ia_na.t2 = 0;

  /* Reconfigure Accept */

  reconf_accept.type = htons(DHCPV6_OPT_RECONF_ACCEPT);
  reconf_accept.length = 0;

  /* Request Information Refresh */

  oro_refresh = htons(DHCPV6_OPT_INFO_REFRESH);

  /* Prepare Header */

  oro = dhcp6c_get_state(handle, STATE_ORO, &oro_len);
  hdr.type = type;
  hdr.trid[0] = trid[0];
  hdr.trid[1] = trid[1];
  hdr.trid[2] = trid[2];
  hdr.elapsed_type = htons(DHCPV6_OPT_ELAPSED);
  hdr.elapsed_len =  htons(2);
  hdr.elapsed_value = htons((ecs > 0xffff) ? 0xffff : ecs);
  hdr.oro_type = htons(DHCPV6_OPT_ORO);
  hdr.oro_len = htons(oro_len);

  /* Prepare iov */

  dhcp6c_set_iov(&iov[0], &hdr, sizeof(hdr));
  dhcp6c_set_iov(&iov[1], oro, oro_len);
  dhcp6c_set_iov(&iov[2], &oro_refresh, 0);
  dhcp6c_set_iov(&iov[3], cl_id, cl_id_len);
  dhcp6c_set_iov(&iov[4], srv_id, srv_id_len);
  dhcp6c_set_iov(&iov[5], &reconf_accept, 0);
  dhcp6c_set_iov(&iov[6], &fqdn, fqdn_len);
  dhcp6c_set_iov(&iov[7], &hdr_ia_na, sizeof(hdr_ia_na));
  dhcp6c_set_iov(&iov[8], ia_na, ia_na_len);
  dhcp6c_set_iov(&iov[9], &hdr_ia_pd, sizeof(hdr_ia_pd));
  dhcp6c_set_iov(&iov[10], ia_pd, ia_pd_len);

  cnt = ARRAY_SIZE(iov);
  if (type == DHCPV6_MSG_INFO_REQ)
    {
      cnt = 5;
      iov[2].iov_len = sizeof(oro_refresh);
      hdr.oro_len = htons(oro_len + sizeof(oro_refresh));
    }
  else if (!pdhcp6c->request_prefix)
    {
      cnt = 9;
    }

  /* Disable IAs if not used */

  if (type == DHCPV6_MSG_SOLICIT)
    {
      iov[5].iov_len = sizeof(reconf_accept);
    }
  else if (type != DHCPV6_MSG_REQUEST)
    {
      if (ia_na_len == 0)
        {
          iov[7].iov_len = 0;
        }

      if (ia_pd_len == 0)
        {
          iov[9].iov_len = 0;
        }
    }

  if (pdhcp6c->ia_mode == IA_MODE_NONE)
    {
      iov[7].iov_len = 0;
    }

  msg.msg_name = &dest;
  msg.msg_namelen = sizeof(dest);
  msg.msg_iov = iov;
  msg.msg_iovlen = cnt;
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_flags = 0;

  sendmsg(pdhcp6c->sockfd, &msg, 0);
}

static int64_t dhcp6c_rand_delay(FAR void *handle, int64_t time)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  int random;

  read(pdhcp6c->urandom_fd, &random, sizeof(random));
  return (time * (random % 1000)) / 10000;
}

static bool dhcp6c_response_is_valid(FAR void *handle, FAR const void *buf,
                                     ssize_t len,
                                     const uint8_t transaction[3],
                                     enum dhcpv6_msg_e type)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  FAR const struct dhcpv6_header_s *rep = buf;
  FAR uint8_t *ite;
  FAR uint8_t *end;
  FAR uint8_t *odata;
  uint16_t otype;
  uint16_t olen;
  bool clientid_ok = false;
  bool serverid_ok = false;
  size_t client_id_len;
  size_t server_id_len;
  FAR void *client_id;
  FAR void *server_id;

  if (len < sizeof(*rep) ||
      memcmp(rep->tr_id, transaction, sizeof(rep->tr_id)) != 0)
    {
      return false;
    }

  if (type == DHCPV6_MSG_SOLICIT)
    {
      if (rep->msg_type != DHCPV6_MSG_ADVERT &&
          rep->msg_type != DHCPV6_MSG_REPLY)
        {
          return false;
        }
    }
  else if (type == DHCPV6_MSG_UNKNOWN)
    {
      if (!pdhcp6c->accept_reconfig ||
          rep->msg_type != DHCPV6_MSG_RECONF)
        {
          return false;
        }
    }
  else if (rep->msg_type != DHCPV6_MSG_REPLY)
    {
      return false;
    }

  end = ((FAR uint8_t *)buf) + len;
  client_id = dhcp6c_get_state(handle, STATE_CLIENT_ID, &client_id_len);
  server_id = dhcp6c_get_state(handle, STATE_SERVER_ID, &server_id_len);

  dhcpv6_for_each_option(ite, &rep[1], end, otype, olen, odata)
    {
      if (otype == DHCPV6_OPT_CLIENTID)
        {
          clientid_ok = (olen + 4u == client_id_len) &&
                        (memcmp((odata - 4), client_id, client_id_len) == 0);
        }
      else if (otype == DHCPV6_OPT_SERVERID)
        {
          serverid_ok = (olen + 4u == server_id_len) &&
                        (memcmp((odata - 4), server_id, server_id_len) == 0);
        }
    }

  return clientid_ok && (serverid_ok || server_id_len == 0);
}

static int dhcp6c_command(FAR void *handle, enum dhcpv6_msg_e type)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  const int buf_length = 1536;
  FAR uint8_t *buf = (FAR uint8_t *)malloc(buf_length);
  uint32_t timeout = CONFIG_NETUTILS_DHCP6C_REQUEST_TIMEOUT < 3 ? 3 :
                     CONFIG_NETUTILS_DHCP6C_REQUEST_TIMEOUT;
  FAR const struct dhcp6c_retx_s *retx = &g_dhcp6c_retx[type];
  uint64_t start;
  uint64_t round_start;
  uint64_t round_end;
  uint64_t elapsed;
  uint8_t trid[3];
  ssize_t len = -1;
  int64_t rto = 0;

  if (buf == NULL)
    {
      return -1;
    }

  if (retx->delay)
    {
      struct timespec ts;
      ts.tv_sec = 0;
      ts.tv_nsec = dhcp6c_rand_delay(handle, 10 * DHCPV6_REQ_DELAY);
      nanosleep(&ts, NULL);
    }

  if (type == DHCPV6_MSG_RELEASE || type == DHCPV6_MSG_DECLINE)
    {
      timeout = 3;
    }
  else if (type == DHCPV6_MSG_UNKNOWN)
    {
      timeout = pdhcp6c->t1;
    }
  else if (type == DHCPV6_MSG_RENEW)
    {
      timeout = pdhcp6c->t2 - pdhcp6c->t1;
    }
  else if (type == DHCPV6_MSG_REBIND)
    {
      timeout = pdhcp6c->t3 - pdhcp6c->t2;
    }

  if (timeout == 0)
    {
      len = -1;
      goto end;
    }

  ninfo("Sending %s (timeout %u s)\n", retx->name, timeout);
  start = dhcp6c_get_milli_time();
  round_start = start;

  /* Generate transaction ID */

  read(pdhcp6c->urandom_fd, trid, sizeof(trid));

  do
    {
      rto = (rto == 0) ? (retx->init_timeo * MSEC_PER_SEC +
              dhcp6c_rand_delay(handle, retx->init_timeo * MSEC_PER_SEC)) :
              (2 * rto + dhcp6c_rand_delay(handle, rto));

      if (rto >= retx->max_timeo * MSEC_PER_SEC)
        {
          rto = retx->max_timeo * MSEC_PER_SEC +
                dhcp6c_rand_delay(handle, retx->max_timeo * MSEC_PER_SEC);
        }

      /* Calculate end for this round and elapsed time */

      round_end = round_start + rto;
      elapsed = round_start - start;

      /* Don't wait too long */

      if (round_end - start > timeout * MSEC_PER_SEC)
        {
          round_end = timeout * MSEC_PER_SEC + start;
        }

      /* Built and send package */

      if (type != DHCPV6_MSG_UNKNOWN)
        {
          dhcp6c_send(handle, type, trid, elapsed / 10);
        }

      /* Receive rounds */

      for (; len < 0 && round_start < round_end;
              round_start = dhcp6c_get_milli_time())
        {
          /* Set timeout for receiving */

          uint64_t t = round_end - round_start;
          struct timeval retime =
          {
            t / MSEC_PER_SEC, (t % MSEC_PER_SEC) * MSEC_PER_SEC
          };

          /* check for dhcp6c_close */

          if (pdhcp6c->cancel)
            {
              len = -1;
              goto end;
            }

          setsockopt(pdhcp6c->sockfd, SOL_SOCKET, SO_RCVTIMEO,
                     &retime, sizeof(retime));

          /* Receive cycle */

          len = recv(pdhcp6c->sockfd, buf, buf_length, 0);
          if (type != DHCPV6_MSG_UNKNOWN)
            {
              ninfo("%s[type:%d] recv len[%d]\n", __func__, type, len);
            }

          if (!dhcp6c_response_is_valid(handle, buf, len, trid, type))
            {
              len = -1;
            }

          if (len > 0)
            {
              FAR uint8_t *opt = &buf[4];
              FAR uint8_t *opt_end = opt + len - 4;

              round_start = dhcp6c_get_milli_time();
              elapsed = round_start - start;
              ninfo("Got a valid reply after %ums\n", (unsigned)elapsed);

              if (retx->handler_reply != NULL)
                {
                  len = retx->handler_reply(handle, type, opt,
                                            opt_end, elapsed / MSEC_PER_SEC);
                }
            }
        }

      if (retx->handler_finish != NULL)
        {
          len = retx->handler_finish(handle, elapsed / MSEC_PER_SEC);
        }
    }
  while (len < 0 && elapsed / MSEC_PER_SEC < timeout);

end:
  free(buf);
  return len;
}

static int dhcp6c_poll_reconfigure(FAR void *handle)
{
  int ret = dhcp6c_command(handle, DHCPV6_MSG_UNKNOWN);
  if (ret != -1)
    {
      ret = dhcp6c_command(handle, ret);
    }

  return ret;
}

/* Collect all advertised servers */

static int dhcp6c_handle_advert(FAR void *handle, enum dhcpv6_msg_e orig,
                                FAR const void *opt, FAR const void *end,
                                uint32_t elapsed)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  uint16_t olen;
  uint16_t otype;
  FAR uint8_t *ite0;
  FAR uint8_t *odata;
  struct dhcpv6_server_cand_s cand;

  memset(&cand, 0, sizeof(cand));
  dhcpv6_for_each_option(ite0, opt, end, otype, olen, odata)
    {
      if (otype == DHCPV6_OPT_SERVERID && olen <= 130)
        {
          memcpy(cand.duid, odata, olen);
          cand.duid_len = olen;
        }
      else if (otype == DHCPV6_OPT_STATUS && olen >= 2 && !odata[0]
               && odata[1] == DHCPV6_NOADDRSAVAIL)
        {
          if (pdhcp6c->ia_mode == IA_MODE_FORCE)
            {
              return -1;
            }
          else
            {
              cand.has_noaddravail = true;
              cand.preference -= 1000;
            }
        }
      else if (otype == DHCPV6_OPT_STATUS && olen >= 2 && !odata[0]
               && odata[1] == DHCPV6_NOPREFIXAVAIL)
        {
          cand.preference -= 2000;
        }
      else if (otype == DHCPV6_OPT_PREF && olen >= 1 &&
               cand.preference >= 0)
        {
          cand.preference = odata[1];
        }
      else if (otype == DHCPV6_OPT_RECONF_ACCEPT)
        {
          cand.wants_reconfigure = true;
        }
      else if (otype == DHCPV6_OPT_IA_PD && pdhcp6c->request_prefix)
        {
          FAR struct dhcpv6_ia_hdr_s *h = (FAR void *)odata;
          FAR uint8_t *oend = odata + olen;
          FAR uint8_t *ite1;
          FAR uint8_t *d;

          dhcpv6_for_each_option(ite1, &h[1], oend, otype, olen, d)
            {
              if (otype == DHCPV6_OPT_IA_PREFIX)
                {
                  cand.preference += 2000;
                }
              else if (otype == DHCPV6_OPT_STATUS &&
                       olen >= 2 && d[0] == 0 &&
                       d[1] == DHCPV6_NOPREFIXAVAIL)
                {
                  cand.preference -= 2000;
                }
            }
        }
    }

  if (cand.duid_len > 0)
    {
      dhcp6c_add_state(handle, STATE_SERVER_CAND, &cand, sizeof(cand));
    }

  return 0;
}

static int dhcp6c_commit_advert(FAR void *handle, uint32_t elapsed)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  size_t cand_len;
  FAR struct dhcpv6_server_cand_s *c = NULL;
  FAR struct dhcpv6_server_cand_s *cand = dhcp6c_get_state(handle,
                                                           STATE_SERVER_CAND,
                                                           &cand_len);
  bool retry = false;

  for (size_t i = 0; i < cand_len / sizeof(*c); ++i)
    {
      if (cand[i].has_noaddravail)
        {
          retry = true;
        }

      if (c == NULL || c->preference < cand[i].preference)
        {
          c = &cand[i];
        }
    }

  if (retry && pdhcp6c->ia_mode == IA_MODE_TRY)
    {
      /* We give it a second try without the IA_NA */

      pdhcp6c->ia_mode = IA_MODE_NONE;
      return dhcp6c_command(handle, DHCPV6_MSG_SOLICIT);
    }

  if (c != NULL)
    {
      uint16_t hdr[2] =
      {
        htons(DHCPV6_OPT_SERVERID), htons(c->duid_len)
      };

      dhcp6c_add_state(handle, STATE_SERVER_ID, hdr, sizeof(hdr));
      dhcp6c_add_state(handle, STATE_SERVER_ID, c->duid, c->duid_len);
      pdhcp6c->accept_reconfig = c->wants_reconfigure;
    }

  dhcp6c_clear_state(handle, STATE_SERVER_CAND);

  if (c == NULL)
    {
      return -1;
    }
  else if (pdhcp6c->request_prefix || pdhcp6c->ia_mode != IA_MODE_NONE)
    {
      return DHCPV6_STATEFUL;
    }
  else
    {
      return DHCPV6_STATELESS;
    }
}

static time_t dhcp6c_parse_ia(FAR void *handle, FAR void *opt, FAR void *end)
{
  uint32_t timeout = UINT32_MAX;
  uint16_t otype;
  uint16_t olen;
  uint16_t stype;
  uint16_t slen;
  FAR uint8_t *ite0;
  FAR uint8_t *odata;
  FAR uint8_t *sdata;

  /* Update address IA */

  dhcpv6_for_each_option(ite0, opt, end, otype, olen, odata)
    {
      if (otype == DHCPV6_OPT_IA_PREFIX)
        {
          FAR struct dhcpv6_ia_prefix_s *prefix = (FAR void *)(odata - 4);
          FAR struct dhcpv6_ia_prefix_s *local = NULL;
          uint32_t valid;
          uint32_t pref;
          size_t pd_len;
          FAR uint8_t *pd;
          FAR uint8_t *ite1;

          if (olen + 4u < sizeof(*prefix))
            {
              continue;
            }

          olen = sizeof(*prefix);
          valid = ntohl(prefix->valid);
          pref = ntohl(prefix->preferred);

          if (pref > valid)
            {
              continue;
            }

          /* Search matching IA */

          pd = dhcp6c_get_state(handle, STATE_IA_PD, &pd_len);
          dhcpv6_for_each_option(ite1, pd, pd + pd_len,
                                 stype, slen, sdata)
            {
              if (memcmp(sdata + 8, odata + 8,
                         sizeof(local->addr) + 1) == 0)
                {
                  local = (FAR void *)(sdata - 4);
                }
            }

          if (local != NULL)
            {
              local->preferred = prefix->preferred;
              local->valid = prefix->valid;
            }
          else
            {
              dhcp6c_add_state(handle, STATE_IA_PD, prefix, olen);
            }

          if (timeout > valid)
            {
              timeout = valid;
            }
        }
      else if (otype == DHCPV6_OPT_IA_ADDR)
        {
          FAR struct dhcpv6_ia_addr_s *addr = (FAR void *)(odata - 4);
          FAR struct dhcpv6_ia_addr_s *local = NULL;
          uint32_t pref;
          uint32_t valid;
          size_t na_len;
          FAR uint8_t *na;
          FAR uint8_t *ite1;

          if (olen + 4u < sizeof(*addr))
            {
              continue;
            }

          olen = sizeof(*addr);
          pref = ntohl(addr->preferred);
          valid = ntohl(addr->valid);

          if (pref > valid)
            {
              continue;
            }

          /* Search matching IA */

          na = dhcp6c_get_state(handle, STATE_IA_NA, &na_len);
          dhcpv6_for_each_option(ite1, na, na + na_len,
                                 stype, slen, sdata)
            {
              if (memcmp(sdata, odata, sizeof(local->addr)) == 0)
                {
                  local = (FAR void *)(sdata - 4);
                }
            }

          if (local != NULL)
            {
              local->preferred = addr->preferred;
              local->valid = addr->valid;
            }
          else
            {
              dhcp6c_add_state(handle, STATE_IA_NA, addr, olen);
            }

          if (timeout > valid)
            {
              timeout = valid;
            }
        }
    }

  return timeout;
}

static int dhcp6c_handle_reply(FAR void *handle, enum dhcpv6_msg_e orig,
                               FAR const void *opt, FAR const void *end,
                               uint32_t elapsed)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  uint16_t otype;
  uint16_t olen;
  FAR uint8_t *ite0;
  FAR uint8_t *odata;
  bool have_update = false;
  size_t ia_na_len;
  size_t ia_pd_len;
  size_t dns_len;
  size_t search_len;
  size_t sntp_ip_len;
  size_t sntp_dns_len;
  size_t sip_ip_len;
  size_t sip_fqdn_len;
  FAR uint8_t *ia_na = dhcp6c_get_state(handle, STATE_IA_NA, &ia_na_len);
  FAR uint8_t *ia_pd = dhcp6c_get_state(handle, STATE_IA_PD, &ia_pd_len);
  FAR uint8_t *ia_end;
  pdhcp6c->t1 = UINT32_MAX;
  pdhcp6c->t2 = UINT32_MAX;
  pdhcp6c->t3 = UINT32_MAX;

  dhcp6c_get_state(handle, STATE_DNS, &dns_len);
  dhcp6c_get_state(handle, STATE_SEARCH, &search_len);
  dhcp6c_get_state(handle, STATE_SNTP_IP, &sntp_ip_len);
  dhcp6c_get_state(handle, STATE_SNTP_FQDN, &sntp_dns_len);
  dhcp6c_get_state(handle, STATE_SIP_IP, &sip_ip_len);
  dhcp6c_get_state(handle, STATE_SIP_FQDN, &sip_fqdn_len);

  /* Decrease valid and preferred lifetime of prefixes */

  dhcpv6_for_each_option(ite0, ia_pd, ia_pd + ia_pd_len, otype, olen, odata)
    {
      FAR struct dhcpv6_ia_prefix_s *p = (FAR void *)(odata - 4);
      uint32_t valid = ntohl(p->valid);
      uint32_t pref = ntohl(p->preferred);

      if (valid != UINT32_MAX)
        {
          p->valid = (valid < elapsed) ? 0 : htonl(valid - elapsed);
        }

      if (pref != UINT32_MAX)
        {
          p->preferred = (pref < elapsed) ? 0 : htonl(pref - elapsed);
        }
    }

  /* Decrease valid and preferred lifetime of addresses */

  dhcpv6_for_each_option(ite0, ia_na, ia_na + ia_na_len, otype, olen, odata)
    {
      FAR struct dhcpv6_ia_addr_s *p = (FAR void *)(odata - 4);
      uint32_t valid = ntohl(p->valid);
      uint32_t pref = ntohl(p->preferred);

      if (valid != UINT32_MAX)
        {
          p->valid = (valid < elapsed) ? 0 : htonl(valid - elapsed);
        }

      if (pref != UINT32_MAX)
        {
          p->preferred = (pref < elapsed) ? 0 : htonl(pref - elapsed);
        }
    }

  /* Parse and find all matching IAs */

  dhcpv6_for_each_option(ite0, opt, end, otype, olen, odata)
    {
      if ((otype == DHCPV6_OPT_IA_PD || otype == DHCPV6_OPT_IA_NA)
           && olen > sizeof(struct dhcpv6_ia_hdr_s))
        {
          FAR struct dhcpv6_ia_hdr_s *ia_hdr = (FAR void *)(odata - 4);
          time_t l_t1 = ntohl(ia_hdr->t1);
          time_t l_t2 = ntohl(ia_hdr->t2);
          uint16_t stype;
          uint16_t slen;
          FAR uint8_t *ite1;
          FAR uint8_t *sdata;
          time_t n;

          /* Test ID and T1-T2 validity */

          if (ia_hdr->iaid != 1 || l_t2 < l_t1)
            {
              continue;
            }

          /* Test status and bail if error */

          dhcpv6_for_each_option(ite1, &ia_hdr[1], odata + olen,
                                 stype, slen, sdata)
            {
              if (stype == DHCPV6_OPT_STATUS && slen >= 2 &&
                  (sdata[0] || sdata[1]))
                {
                  continue;
                }
            }

          /* Update times */

          if (l_t1 > 0 && pdhcp6c->t1 > l_t1)
            {
              pdhcp6c->t1 = l_t1;
            }

          if (l_t2 > 0 && pdhcp6c->t2 > l_t2)
            {
              pdhcp6c->t2 = l_t2;
            }

          /* Always report update in case we have IA_PDs so that
           * the state-script is called with updated times
           */

          if (otype == DHCPV6_OPT_IA_PD && pdhcp6c->request_prefix)
            {
              have_update = true;
            }

          n = dhcp6c_parse_ia(handle, &ia_hdr[1], odata + olen);
          if (n < pdhcp6c->t1)
            {
              pdhcp6c->t1 = n;
            }

          if (n < pdhcp6c->t2)
            {
              pdhcp6c->t2 = n;
            }

          if (n < pdhcp6c->t3)
            {
              pdhcp6c->t3 = n;
            }
        }
      else if (otype == DHCPV6_OPT_DNS_SERVERS)
        {
          if (olen % 16 == 0)
            {
              dhcp6c_add_state(handle, STATE_DNS, odata, olen);
            }
        }
      else if (otype == DHCPV6_OPT_DNS_DOMAIN)
        {
          dhcp6c_add_state(handle, STATE_SEARCH, odata, olen);
        }
      else if (otype == DHCPV6_OPT_NTP_SERVER)
        {
          uint16_t stype;
          uint16_t slen;
          FAR uint8_t *sdata;
          FAR uint8_t *ite1;

          /* Test status and bail if error */

          dhcpv6_for_each_option(ite1, odata, odata + olen,
                                 stype, slen, sdata)
            {
              if (slen == 16 &&
                  (stype == NTP_MC_ADDR || stype == NTP_SRV_ADDR))
                {
                  dhcp6c_add_state(handle, STATE_SNTP_IP, sdata, slen);
                }
              else if (slen > 0 && stype == NTP_SRV_FQDN)
                {
                  dhcp6c_add_state(handle, STATE_SNTP_FQDN, sdata, slen);
                }
            }
        }
      else if (otype == DHCPV6_OPT_SIP_SERVER_A)
        {
          if (olen == 16)
            {
              dhcp6c_add_state(handle, STATE_SIP_IP, odata, olen);
            }
        }
      else if (otype == DHCPV6_OPT_SIP_SERVER_D)
        {
          dhcp6c_add_state(handle, STATE_SIP_FQDN, odata, olen);
        }
      else if (otype == DHCPV6_OPT_INFO_REFRESH && olen >= 4)
        {
          uint32_t refresh = ntohl(*((FAR uint32_t *)odata));
          if (refresh < (uint32_t)pdhcp6c->t1)
            {
              pdhcp6c->t1 = refresh;
            }
        }
      else if (otype != DHCPV6_OPT_CLIENTID && otype != DHCPV6_OPT_SERVERID)
        {
          dhcp6c_add_state(handle, STATE_CUSTOM_OPTS, (odata - 4), olen + 4);
        }
    }

  if (opt != NULL)
    {
      size_t new_ia_pd_len;
      size_t new_ia_na_len;
      have_update |= dhcp6c_commit_state(handle, STATE_DNS, dns_len);
      have_update |= dhcp6c_commit_state(handle, STATE_SEARCH, search_len);
      have_update |= dhcp6c_commit_state(handle, STATE_SNTP_IP,
                                         sntp_ip_len);
      have_update |= dhcp6c_commit_state(handle, STATE_SNTP_FQDN,
                                         sntp_dns_len);
      have_update |= dhcp6c_commit_state(handle, STATE_SIP_IP, sip_ip_len);
      have_update |= dhcp6c_commit_state(handle, STATE_SIP_FQDN,
                                         sip_fqdn_len);
      dhcp6c_get_state(handle, STATE_IA_PD, &new_ia_pd_len);
      dhcp6c_get_state(handle, STATE_IA_NA, &new_ia_na_len);
      have_update |= (new_ia_pd_len != ia_pd_len) ||
                     (new_ia_na_len != ia_na_len);
    }

  /* Delete prefixes with 0 valid-time */

  ia_pd = dhcp6c_get_state(handle, STATE_IA_PD, &ia_pd_len);
  ia_end = ia_pd + ia_pd_len;
  dhcpv6_for_each_option(ite0, ia_pd, ia_end, otype, olen, odata)
    {
      FAR struct dhcpv6_ia_prefix_s *p = (FAR void *)(odata - 4);
      while (!p->valid)
        {
          ia_end = ia_pd + dhcp6c_remove_state(handle, STATE_IA_PD,
                   (FAR uint8_t *)p - ia_pd, olen + 4);
          have_update = true;
        }
    }

  /* Delete addresses with 0 valid-time */

  ia_na = dhcp6c_get_state(handle, STATE_IA_NA, &ia_na_len);
  ia_end = ia_na + ia_na_len;
  dhcpv6_for_each_option(ite0, ia_na, ia_end, otype, olen, odata)
    {
      FAR struct dhcpv6_ia_addr_s *p = (FAR void *)(odata - 4);
      while (!p->valid)
        {
          ia_end = ia_na + dhcp6c_remove_state(handle, STATE_IA_NA,
                   (FAR uint8_t *)p - ia_na, olen + 4);
          have_update = true;
        }
    }

  return have_update;
}

static int dhcp6c_handle_reconfigure(FAR void *handle,
                                     enum dhcpv6_msg_e orig,
                                     FAR const void *opt,
                                     FAR const void *end,
                                     uint32_t elapsed)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  uint16_t otype;
  uint16_t olen;
  FAR uint8_t *odata;
  FAR uint8_t *ite;
  uint8_t msg = DHCPV6_MSG_RENEW;

  /* TODO: should verify the reconfigure message */

  dhcpv6_for_each_option(ite, opt, end, otype, olen, odata)
    {
      if (otype == DHCPV6_OPT_RECONF_MESSAGE && olen == 1 &&
          (odata[0] == DHCPV6_MSG_RENEW ||
           odata[0] == DHCPV6_MSG_INFO_REQ))
        {
          msg = odata[0];
        }
    }

  pdhcp6c->t1 -= elapsed;
  pdhcp6c->t2 -= elapsed;
  pdhcp6c->t3 -= elapsed;

  if (pdhcp6c->t1 < 0)
    {
      pdhcp6c->t1 = 0;
    }

  if (pdhcp6c->t2 < 0)
    {
      pdhcp6c->t2 = 0;
    }

  if (pdhcp6c->t3 < 0)
    {
      pdhcp6c->t3 = 0;
    }

  dhcp6c_handle_reply(handle, DHCPV6_MSG_UNKNOWN, NULL, NULL, elapsed);

  return msg;
}

static int dhcp6c_handle_rebind_reply(FAR void *handle,
                                      enum dhcpv6_msg_e orig,
                                      FAR const void *opt,
                                      FAR const void *end,
                                      uint32_t elapsed)
{
  dhcp6c_handle_advert(handle, orig, opt, end, elapsed);
  if (dhcp6c_commit_advert(handle, elapsed) < 0)
    {
      return -1;
    }

  return dhcp6c_handle_reply(handle, orig, opt, end, elapsed);
}

static int dhcp6c_single_request(FAR void *args)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)args;
  FAR const char *process = NULL;
  enum dhcpv6_mode_e mode;
  enum dhcpv6_msg_e type;
  int ret = -1;

  dhcp6c_clear_state(pdhcp6c, STATE_SERVER_ID);
  dhcp6c_clear_state(pdhcp6c, STATE_SERVER_CAND);
  dhcp6c_clear_state(pdhcp6c, STATE_IA_PD);
  dhcp6c_clear_state(pdhcp6c, STATE_SNTP_IP);
  dhcp6c_clear_state(pdhcp6c, STATE_SNTP_FQDN);
  dhcp6c_clear_state(pdhcp6c, STATE_SIP_IP);
  dhcp6c_clear_state(pdhcp6c, STATE_SIP_FQDN);
  dhcp6c_clear_state(pdhcp6c, STATE_CUSTOM_OPTS);
  ret = dhcp6c_command(pdhcp6c, DHCPV6_MSG_SOLICIT);
  if (ret < 0)
    {
      return -1;
    }
  else if (ret == DHCPV6_STATELESS)
    {
      mode = DHCPV6_STATELESS;
      type = DHCPV6_MSG_INFO_REQ;
      process = "informed";
    }
  else
    {
      mode = DHCPV6_STATEFUL;
      type = DHCPV6_MSG_REQUEST;
      process = "bound";
    }

  ret = dhcp6c_command(pdhcp6c, type);
  if (ret >= 0)
    {
      ret = mode;
      dhcp6c_switch_process(pdhcp6c, process);
    }

  return ret;
}

static int dhcp6c_lease(FAR void *args, uint8_t type)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)args;
  enum dhcpv6_mode_e mode = (enum dhcpv6_mode_e)type;
  size_t ia_pd_len;
  size_t ia_na_len;
  size_t ia_pd_new;
  size_t ia_na_new;
  size_t server_id_len;
  int ret = -1;

  if (mode == DHCPV6_STATELESS)
    {
      /* Stateless mode */

      while (!pdhcp6c->cancel)
        {
          /* Wait for T1 to expire or until we get a reconfigure */

          ret = dhcp6c_poll_reconfigure(pdhcp6c);
          if (ret >= 0)
            {
              dhcp6c_switch_process(pdhcp6c, "informed");
            }

          if (pdhcp6c->cancel)
            {
              break;
            }

          /* Information-Request */

          ret = dhcp6c_command(pdhcp6c, DHCPV6_MSG_INFO_REQ);
          if (ret < 0)
            {
              nerr("DHCPV6_MSG_INFO_REQ error\n");
              break;
            }
          else
            {
              dhcp6c_switch_process(pdhcp6c, "informed");
            }
        }
    }
  else
    {
      /* Stateful mode */

      while (!pdhcp6c->cancel)
        {
          /* Renew Cycle
           * Wait for T1 to expire or until we get a reconfigure
           */

          ret = dhcp6c_poll_reconfigure(pdhcp6c);
          if (ret >= 0)
            {
              dhcp6c_switch_process(pdhcp6c, "updated");
            }

          if (pdhcp6c->cancel)
            {
              break;
            }

          dhcp6c_get_state(pdhcp6c, STATE_IA_PD, &ia_pd_len);
          dhcp6c_get_state(pdhcp6c, STATE_IA_NA, &ia_na_len);

          /* If we have any IAs, send renew, otherwise request */

          if (ia_pd_len == 0 && ia_na_len == 0)
            ret = dhcp6c_command(pdhcp6c, DHCPV6_MSG_REQUEST);
          else
            ret = dhcp6c_command(pdhcp6c, DHCPV6_MSG_RENEW);

          if (pdhcp6c->cancel)
            {
              break;
            }

          if (ret >= 0)
            {
              /* Publish updates */

              dhcp6c_switch_process(pdhcp6c, "updated");
            }
          else
            {
              /* Remove binding */

              dhcp6c_clear_state(pdhcp6c, STATE_SERVER_ID);

              /* If we have IAs, try rebind otherwise restart */

              ret = dhcp6c_command(pdhcp6c, DHCPV6_MSG_REBIND);
              dhcp6c_get_state(pdhcp6c, STATE_IA_PD, &ia_pd_new);
              dhcp6c_get_state(pdhcp6c, STATE_IA_NA, &ia_na_new);

              /* We lost all our IAs, restart */

              if (ret < 0 || (ia_pd_new == 0 && ia_pd_len) ||
                  (ia_na_new == 0 && ia_na_len))
                {
                  break;
                }
              else if (ret >= 0)
                {
                  dhcp6c_switch_process(pdhcp6c, "rebound");
                }
            }
        }
    }

  dhcp6c_get_state(pdhcp6c, STATE_IA_PD, &ia_pd_len);
  dhcp6c_get_state(pdhcp6c, STATE_IA_NA, &ia_na_len);
  dhcp6c_get_state(pdhcp6c, STATE_SERVER_ID, &server_id_len);

  /* Add all prefixes to lost prefixes */

  dhcp6c_clear_state(pdhcp6c, STATE_IA_PD);
  dhcp6c_switch_process(pdhcp6c, "unbound");

  /* Remove assigned addresses */

  if (ia_na_len > 0)
    {
      dhcp6c_remove_addrs(pdhcp6c);
    }

  if (server_id_len > 0 && (ia_pd_len > 0 || ia_na_len > 0))
    {
      dhcp6c_command(pdhcp6c, DHCPV6_MSG_RELEASE);
    }

  return ret;
}

static FAR void *dhcp6c_run(FAR void *args)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)args;
  int ret;

  while (!pdhcp6c->cancel)
    {
      ret = dhcp6c_single_request(pdhcp6c);
      if (ret > 0)
        {
          dhcp6c_lease(pdhcp6c, ret);
        }
    }

  return 0;
}

static FAR void *dhcp6c_precise_open(FAR const char *ifname,
                                     enum dhcp6c_ia_mode_e ia_mode,
                                     bool request_pd,
                                     uint16_t opt[], int cnt)
{
  FAR struct dhcp6c_state_s *pdhcp6c;
  struct sockaddr_in6 client_addr;
  struct ifreq ifr;
  size_t client_id_len;
  int val = 1;
  uint16_t oro[] =
  {
    htons(DHCPV6_OPT_DNS_SERVERS),
    htons(DHCPV6_OPT_DNS_DOMAIN),
    htons(DHCPV6_OPT_NTP_SERVER),
    htons(DHCPV6_OPT_SIP_SERVER_A),
    htons(DHCPV6_OPT_SIP_SERVER_D)
  };

  pdhcp6c = malloc(sizeof(struct dhcp6c_state_s));
  if (pdhcp6c == NULL)
    {
      return NULL;
    }

  memset(pdhcp6c, 0, sizeof(*pdhcp6c));
  pdhcp6c->urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY);
  if (pdhcp6c->urandom_fd < 0)
    {
      free(pdhcp6c);
      return NULL;
    }

  pdhcp6c->sockfd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
  if (pdhcp6c->sockfd < 0)
    {
      close(pdhcp6c->urandom_fd);
      free(pdhcp6c);
      return NULL;
    }

  /* Detect interface */

  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
  if (ioctl(pdhcp6c->sockfd, SIOCGIFINDEX, &ifr))
    {
      close(pdhcp6c->urandom_fd);
      close(pdhcp6c->sockfd);
      free(pdhcp6c);
      return NULL;
    }

  pdhcp6c->ifindex = ifr.ifr_ifindex;

  /* Create client DUID */

  dhcp6c_get_state(pdhcp6c, STATE_CLIENT_ID, &client_id_len);
  if (client_id_len == 0)
    {
      uint8_t duid[14] =
      {
        0, DHCPV6_OPT_CLIENTID, 0, 10, 0,
        DHCPV6_DUID_LLADDR, 0, 1
      };

      uint8_t zero[ETHER_ADDR_LEN];
      struct ifreq ifs[100];
      FAR struct ifreq *ifp;
      FAR struct ifreq *ifend;
      struct ifconf ifc;

      ioctl(pdhcp6c->sockfd, SIOCGIFHWADDR, &ifr);
      memcpy(&duid[8], ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
      memset(zero, 0, sizeof(zero));
      ifc.ifc_req = ifs;
      ifc.ifc_len = sizeof(ifs);

      if (memcmp(&duid[8], zero, ETHER_ADDR_LEN) == 0 &&
          ioctl(pdhcp6c->sockfd, SIOCGIFCONF, &ifc) >= 0)
        {
          /* If our interface doesn't have an address... */

          ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
          for (ifp = ifc.ifc_req; ifp < ifend &&
               memcmp(&duid[8], zero, 6) == 0; ifp++)
            {
              memcpy(ifr.ifr_name, ifp->ifr_name,
                     sizeof(ifr.ifr_name));
              ioctl(pdhcp6c->sockfd, SIOCGIFHWADDR, &ifr);
              memcpy(&duid[8], ifr.ifr_hwaddr.sa_data,
                     ETHER_ADDR_LEN);
            }
        }

      dhcp6c_add_state(pdhcp6c, STATE_CLIENT_ID, duid, sizeof(duid));
    }

  /* Create ORO */

  dhcp6c_add_state(pdhcp6c, STATE_ORO, oro, sizeof(oro));

  /* Configure IPv6-options */

  setsockopt(pdhcp6c->sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
  setsockopt(pdhcp6c->sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
  setsockopt(pdhcp6c->sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifname,
             strlen(ifname));

  memset(&client_addr, 0, sizeof(client_addr));
  client_addr.sin6_family = AF_INET6;
  client_addr.sin6_port = htons(DHCPV6_CLIENT_PORT);

  if (bind(pdhcp6c->sockfd, (struct sockaddr *)&client_addr,
           sizeof(client_addr)) != 0)
    {
      close(pdhcp6c->urandom_fd);
      close(pdhcp6c->sockfd);
      free(pdhcp6c);
      return NULL;
    }

  pdhcp6c->thread = 0;
  pdhcp6c->cancel = false;
  pdhcp6c->t1 = 0;
  pdhcp6c->t2 = 0;
  pdhcp6c->t3 = 0;
  pdhcp6c->request_prefix = request_pd;
  switch (ia_mode)
    {
      case IA_MODE_NONE:
      case IA_MODE_TRY:
      case IA_MODE_FORCE:
        break;
      default:
        ia_mode = IA_MODE_TRY;
        break;
    }

  pdhcp6c->ia_mode = ia_mode;
  pdhcp6c->accept_reconfig = false;
  if (opt != NULL && cnt > 0)
    {
      uint16_t opttype;
      for (int i = 0; i < cnt; i++)
        {
          opttype = htons(opt[i]);
          dhcp6c_add_state(pdhcp6c, STATE_ORO, &opttype, 2);
        }
    }

  return pdhcp6c;
}

/****************************************************************************
 * Public Functions
 ****************************************************************************/

FAR void *dhcp6c_open(FAR const char *interface)
{
  return dhcp6c_precise_open(interface, IA_MODE_TRY, true, NULL, 0);
}

int dhcp6c_request(FAR void *handle, FAR struct dhcp6c_state *presult)
{
  int ret;

  if (handle == NULL)
    {
      return ERROR;
    }

  ret = dhcp6c_single_request(handle);
  if (ret >= 0)
    {
      dhcp6c_get_result(handle, presult);
      return OK;
    }
  else
    {
      return ERROR;
    }
}

int dhcp6c_request_async(FAR void *handle, dhcp6c_callback_t callback)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  int ret;

  if (handle == NULL)
    {
      return ERROR;
    }

  if (pdhcp6c->thread)
    {
      nerr("DHCP6C thread already running\n");
      return ERROR;
    }

  pdhcp6c->callback = callback;
  ret = pthread_create(&pdhcp6c->thread, NULL, dhcp6c_run, pdhcp6c);
  if (ret != 0)
    {
      nerr("Failed to start the DHCP6C thread\n");
      return ERROR;
    }

  return OK;
}

void dhcp6c_cancel(FAR void *handle)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;
  sighandler_t old;
  int ret;

  if (pdhcp6c != NULL)
    {
      pdhcp6c->cancel = true;
      if (pdhcp6c->thread)
        {
          old = signal(SIGQUIT, SIG_IGN);

          /* Signal the dhcp6c_run */

          ret = pthread_kill(pdhcp6c->thread, SIGQUIT);
          if (ret != 0)
            {
              nerr("pthread_kill DHCP6C thread\n");
            }

          /* Wait for the end of dhcp6c_run */

          ret = pthread_join(pdhcp6c->thread, NULL);
          if (ret != 0)
            {
              nerr("pthread_join DHCP6C thread\n");
            }

          pdhcp6c->thread = 0;
          signal(SIGQUIT, old);
        }
    }
}

void dhcp6c_close(FAR void *handle)
{
  FAR struct dhcp6c_state_s *pdhcp6c = (FAR struct dhcp6c_state_s *)handle;

  if (pdhcp6c != NULL)
    {
      dhcp6c_cancel(pdhcp6c);
      if (pdhcp6c->urandom_fd > 0)
        {
          close(pdhcp6c->urandom_fd);
        }

      if (pdhcp6c->sockfd > 0)
        {
          close(pdhcp6c->sockfd);
        }

      for (int i = 0; i < STATE_MAX; i++)
        {
          if (pdhcp6c->state_data[i] != NULL)
            {
              free(pdhcp6c->state_data[i]);
            }
        }

      free(pdhcp6c);
    }
}
