diff options
| author | Yeongdeok Suh <yduck.suh@samsung.com> | 2015-10-23 17:03:57 +0900 | 
|---|---|---|
| committer | Rob Landley <rob@landley.net> | 2015-10-23 12:33:29 -0500 | 
| commit | c9e2a656c7305fac00a5a8c09201e1e39fea6a1b (patch) | |
| tree | 47d4ce4ee61fe8d26f8f70ead57af316ae46b5f7 | |
| parent | c10638d3b16d065c1efd97ae17c1a8bf417be706 (diff) | |
| download | toybox-c9e2a656c7305fac00a5a8c09201e1e39fea6a1b.tar.gz | |
fix dhcpd warning
| -rw-r--r-- | toys/pending/dhcpd.c | 237 | 
1 files changed, 107 insertions, 130 deletions
diff --git a/toys/pending/dhcpd.c b/toys/pending/dhcpd.c index 17f5009b..cd9f2ded 100644 --- a/toys/pending/dhcpd.c +++ b/toys/pending/dhcpd.c @@ -5,7 +5,7 @@   * Copyright 2015 Yeongdeok Suh <skyducks111@gmail.com>   *   * No Standard -USE_DHCPD(NEWTOY(dhcpd, ">1P#<0>65535=67fi:S46[!46]", TOYFLAG_SBIN|TOYFLAG_ROOTONLY)) +USE_DHCPD(NEWTOY(dhcpd, ">1P#<0>65535fi:S46[!46]", TOYFLAG_SBIN|TOYFLAG_ROOTONLY))  config DHCPD    bool "dhcpd" @@ -26,8 +26,7 @@ config DEBUG_DHCP  */  /* - * Things to do - *  + * TODO   * - Working as an relay agent   * - Rapid commit option support   * - Additional packet options (commented on the middle of sources) @@ -186,7 +185,7 @@ typedef struct static_lease6_s {    uint16_t duid_len;    uint16_t ia_type;    uint32_t iaid; -  uint32_t nip6[4]; +  uint8_t nip6[16];    uint8_t duid[20];  } static_lease6; @@ -203,7 +202,7 @@ typedef struct {    uint16_t ia_type;    uint32_t expires;    uint32_t iaid; -  uint32_t lease_nip6[4]; +  uint8_t lease_nip6[16];    uint8_t duid[20];  } dyn_lease6; @@ -218,28 +217,28 @@ struct __attribute__((packed)) optval_duid_llt {    uint16_t type;    uint16_t hwtype;    uint32_t time; -  uint8_t *lladdr; +  uint8_t lladdr[];   //flexible  };  struct __attribute__((packed)) optval_ia_na {    uint32_t iaid;    uint32_t t1, t2; -  uint8_t *optval; +  uint8_t optval[];   //flexible  };  struct __attribute__((packed)) optval_ia_addr { -  uint32_t ipv6_addr[4]; +  uint8_t ipv6_addr[16];    uint32_t pref_lifetime;    uint32_t valid_lifetime;  };  struct __attribute__((packed)) optval_status_code {    uint16_t status_code; -  uint8_t *status_msg; +  uint8_t status_msg[]; //flexible  };  typedef struct __attribute__((__may_alias__)) server_config_s {    char *interface;                // interface to use    int ifindex; -  uint32_t server_nip6[4]; +  uint8_t server_nip6[16];    uint32_t server_nip;    uint32_t port;    uint8_t server_mac[6];          // our MAC address (used only for ARP probing) @@ -247,8 +246,8 @@ typedef struct __attribute__((__may_alias__)) server_config_s {    /* start,end are in host order: we need to compare start <= ip <= end*/    uint32_t start_ip;              // start address of leases, in host order    uint32_t end_ip;                // end of leases, in host order -  uint32_t start_ip6[4];          // start address of leases, in IPv6 mode -  uint32_t end_ip6[4];            // end of leases, in IPv6 mode +  uint8_t start_ip6[16];          // start address of leases, in IPv6 mode +  uint8_t end_ip6[16];            // end of leases, in IPv6 mode    uint32_t max_lease_sec;         // maximum lease time (host order)    uint32_t min_lease_sec;         // minimum lease time a client can request    uint32_t max_leases;            // maximum number of leases (including reserved addresses) @@ -272,6 +271,8 @@ typedef struct __attribute__((__may_alias__)) server_config_s {  } server_config_t;  typedef struct __attribute__((__may_alias__)) server_state_s { +  uint8_t client_nip6[16]; +  uint32_t client_port;    uint8_t rqcode;    int listensock;    union { @@ -330,26 +331,6 @@ static struct fd_pair sigfd;  static int constone = 1;  static sa_family_t addr_version = AF_INET; -static void htonl6(uint32_t *host_order, uint32_t *network_order) -{ -  int i; -  if(!host_order) { -    error_msg("NULL ipv6 address"); -  } else { -    for(i=0;i<4;i++) network_order[i] = htonl(host_order[i]); -  } -} - -static void ntohl6(uint32_t *network_order, uint32_t *host_order) -{ -  int i; -  if(!network_order) { -    error_msg("NULL ipv6 address"); -  } else { -    for(i=0;i<4;i++) host_order[i] = ntohl(network_order[i]); -  } -} -  // calculate options size.  static int dhcp_opt_size(uint8_t *optionptr)  { @@ -378,7 +359,7 @@ static uint16_t dhcp_checksum(void *addr, int count)  }  // gets information of INTERFACE and updates IFINDEX, MAC and IP -static int get_interface(const char *interface, int *ifindex, uint32_t *oip, +static int get_interface(const char *interface, int *ifindex, void *oip,      uint8_t *mac)  {    struct ifreq req; @@ -397,20 +378,19 @@ static int get_interface(const char *interface, int *ifindex, uint32_t *oip,    if (addr_version == AF_INET6) {      FILE *fd6 = fopen("/proc/net/if_inet6", "r"); +    uint8_t *oip6 = (uint8_t*)oip;      int i;      while(fgets(toybuf, sizeof(toybuf), fd6)) {        if (!strstr(toybuf, interface))          continue; -      if (sscanf(toybuf, "%32s \n", ipv6_addr) != 1) -        continue; - -      if (strstr(ipv6_addr, "fe80")) break; +      if (sscanf(toybuf, "%32s \n", ipv6_addr) == 1) +        break;      }      fclose(fd6); -    if (oip) { +    if (oip6) {        char *ptr = ipv6_addr+sizeof(ipv6_addr)-1;        // convert giant hex string into colon-spearated ipv6 address by @@ -422,14 +402,15 @@ static int get_interface(const char *interface, int *ifindex, uint32_t *oip,        if(inet_pton(AF_INET6, ipv6_addr, &ip6.sin6_addr) <= 0)          error_msg("inet : the ipv6 address is not proper");        else -        ntohl6(ip6.sin6_addr.s6_addr32, oip); +        memcpy(oip6, ip6.sin6_addr.s6_addr32, sizeof(uint32_t)*4);      }    } else { -    if (oip) { +    uint32_t *oip4 = (uint32_t*)oip; +    if (oip4) {        xioctl(fd, SIOCGIFADDR, &req);        ip = (struct sockaddr_in*) &req.ifr_addr;        dbg("IP %s\n", inet_ntoa(ip->sin_addr)); -      *oip = ntohl(ip->sin_addr.s_addr); +      *oip4 = ntohl(ip->sin_addr.s_addr);      }    } @@ -803,6 +784,7 @@ static int open_listensock6(void)    gstate.listensock = xsocket(PF_INET6, SOCK_DGRAM, 0);    setsockopt(gstate.listensock, SOL_SOCKET, SO_REUSEADDR, &constone, sizeof(constone)); +  setsockopt(gstate.listensock, IPPROTO_IPV6, IPV6_CHECKSUM, &constone, sizeof(constone));    if (setsockopt(gstate.listensock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &constone,          sizeof(constone)) == -1) { @@ -815,7 +797,7 @@ static int open_listensock6(void)    memset(&addr6, 0, sizeof(addr6));    addr6.sin6_family = AF_INET6; -  addr6.sin6_port = (flag_chk(FLAG_P))?htons(TT.port):htons(gconfig.port); //SERVER_PORT +  addr6.sin6_port = htons(gconfig.port); //SERVER_PORT    addr6.sin6_scope_id = if_nametoindex(gconfig.interface);    //Listening for multicast packet    inet_pton(AF_INET6, "ff02::1:2", &addr6.sin6_addr); @@ -861,7 +843,7 @@ static int open_listensock(void)    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET; -  addr.sin_port = (flag_chk(FLAG_P))?htons(TT.port):htons(gconfig.port); //SERVER_PORT +  addr.sin_port = htons(gconfig.port); //SERVER_PORT    addr.sin_addr.s_addr = INADDR_ANY ;    if (bind(gstate.listensock, (struct sockaddr *) &addr, sizeof(addr))) { @@ -878,7 +860,6 @@ static int send_packet6(uint8_t relay, uint8_t *client_lla, uint16_t optlen)    dhcp6_raw_t packet;    unsigned padding;    int fd, result = -1; -  uint32_t front, back;    memset(&packet, 0, sizeof(dhcp6_raw_t));    memcpy(&packet.dhcp6, &gstate.send.send_pkt6, sizeof(dhcp6_msg_t)); @@ -893,7 +874,7 @@ static int send_packet6(uint8_t relay, uint8_t *client_lla, uint16_t optlen)    dest_sll.sll_protocol = htons(ETH_P_IPV6);    dest_sll.sll_ifindex = gconfig.ifindex;    dest_sll.sll_halen = ETH_ALEN; -  memcpy(dest_sll.sll_addr, client_lla, sizeof(client_lla)); +  memcpy(dest_sll.sll_addr, client_lla, sizeof(uint8_t)*6);    if (bind(fd, (struct sockaddr *) &dest_sll, sizeof(dest_sll)) < 0) {      dbg("SEND : bind failed\n"); @@ -901,19 +882,10 @@ static int send_packet6(uint8_t relay, uint8_t *client_lla, uint16_t optlen)      return -1;    }    memcpy(&packet.iph.ip6_src, &gconfig.server_nip6, sizeof(uint32_t)*4); -  //HW addr to Link-Local addr -  inet_pton(AF_INET6, "fe80::0200:00ff:fe00:0000", &packet.iph.ip6_dst); -  ntohl6(packet.iph.ip6_dst.__in6_u.__u6_addr32,packet.iph.ip6_dst.__in6_u.__u6_addr32); -  front = ntohl(*(uint32_t*)(client_lla+3) & 0x00ffffff) >> 8; -  back = ntohl(*(uint32_t*)(client_lla) & 0x00ffffff); -  packet.iph.ip6_dst.__in6_u.__u6_addr32[3] = -    packet.iph.ip6_dst.__in6_u.__u6_addr32[3] | front; -  packet.iph.ip6_dst.__in6_u.__u6_addr32[2] = -    packet.iph.ip6_dst.__in6_u.__u6_addr32[2] | back; -  htonl6(packet.iph.ip6_dst.__in6_u.__u6_addr32,packet.iph.ip6_dst.__in6_u.__u6_addr32); - -  packet.udph.source = htons(gconfig.port); -  packet.udph.dest = htons(546); +  memcpy(&packet.iph.ip6_dst, &gstate.client_nip6, sizeof(uint32_t)*4); + +  packet.udph.source = htons(gconfig.port); //SERVER_PORT +  packet.udph.dest = gstate.client_port; //CLIENT_PORT    packet.udph.len = htons(sizeof(dhcp6_raw_t) - sizeof(struct ip6_hdr) - padding);    packet.iph.ip6_ctlun.ip6_un1.ip6_un1_plen = htons(ntohs(packet.udph.len) + 0x11);    packet.udph.check = dhcp_checksum(&packet, sizeof(dhcp6_raw_t) - padding); @@ -962,9 +934,10 @@ static int send_packet(uint8_t broadcast)    padding = 308 - 1 - dhcp_opt_size(gstate.send.send_pkt.options);    packet.iph.protocol = IPPROTO_UDP;    packet.iph.saddr = gconfig.server_nip; -  packet.iph.daddr = (broadcast || (gstate.rcvd.rcvd_pkt.ciaddr == 0))?INADDR_BROADCAST:gstate.rcvd.rcvd_pkt.ciaddr; -  packet.udph.source = htons(67);//SERVER_PORT -  packet.udph.dest = htons(68); //CLIENT_PORT +  packet.iph.daddr = (broadcast || (gstate.rcvd.rcvd_pkt.ciaddr == 0))? +    INADDR_BROADCAST : gstate.rcvd.rcvd_pkt.ciaddr; +  packet.udph.source = htons(gconfig.port);//SERVER_PORT +  packet.udph.dest = gstate.client_port; //CLIENT_PORT    packet.udph.len = htons(sizeof(dhcp_raw_t) - sizeof(struct iphdr) - padding);    packet.iph.tot_len = packet.udph.len;    packet.udph.check = dhcp_checksum(&packet, sizeof(dhcp_raw_t) - padding); @@ -986,9 +959,14 @@ static int send_packet(uint8_t broadcast)  static int read_packet6(void)  {    int ret; +  struct sockaddr_in6 c_addr; +  socklen_t c_addr_size = sizeof(c_addr);    memset(&gstate.rcvd.rcvd_pkt6, 0, sizeof(dhcp6_msg_t)); -  ret = read(gstate.listensock, &gstate.rcvd.rcvd_pkt6, sizeof(dhcp6_msg_t)); +  ret = recvfrom(gstate.listensock, &gstate.rcvd.rcvd_pkt6, sizeof(dhcp6_msg_t), +      0, (struct sockaddr*) &c_addr, &c_addr_size); +  memcpy(gstate.client_nip6, &c_addr.sin6_addr, sizeof(uint32_t)*4); +  memcpy(&gstate.client_port, &c_addr.sin6_port, sizeof(uint32_t));    if (ret < 0) {      dbg("Packet read error, ignoring. \n");      return ret; // returns -1 @@ -1006,9 +984,14 @@ static int read_packet6(void)  static int read_packet(void)  {    int ret; +  struct sockaddr_in c_addr; +  socklen_t c_addr_size = sizeof(c_addr);    memset(&gstate.rcvd.rcvd_pkt, 0, sizeof(dhcp_msg_t)); -  ret = read(gstate.listensock, &gstate.rcvd.rcvd_pkt, sizeof(dhcp_msg_t)); +  ret = recvfrom(gstate.listensock, &gstate.rcvd.rcvd_pkt, sizeof(dhcp_msg_t), +      0, (struct sockaddr*) &c_addr, &c_addr_size); +  memcpy(&gstate.client_port, &c_addr.sin_port, sizeof(uint32_t)); +  /*ret = read(gstate.listensock, &gstate.rcvd.rcvd_pkt, sizeof(dhcp_msg_t));*/    if (ret < 0) {      dbg("Packet read error, ignoring. \n");      return ret; // returns -1 @@ -1323,11 +1306,10 @@ static uint32_t get_lease(uint32_t req_exp)    return req_exp;  } -static int verifyip6_in_lease(uint32_t *nip6, uint8_t *duid, uint16_t ia_type, uint32_t iaid) +static int verifyip6_in_lease(uint8_t *nip6, uint8_t *duid, uint16_t ia_type, uint32_t iaid)  {    static_lease6 *sls6;    struct arg_list *listdls; -  uint32_t tmpnip6[4] = {0,};    for (listdls = gstate.dleases; listdls; listdls = listdls->next) {      if (!memcmp(((dyn_lease6*) listdls->arg)->lease_nip6, nip6, sizeof(uint32_t)*4)) @@ -1340,9 +1322,8 @@ static int verifyip6_in_lease(uint32_t *nip6, uint8_t *duid, uint16_t ia_type, u    for (sls6 = gstate.leases.sleases6; sls6; sls6 = sls6->next)      if (memcmp(sls6->nip6, nip6, sizeof(uint32_t)*4)==0) return -2; -  ntohl6(nip6, tmpnip6); -  if (memcmp(tmpnip6, gconfig.start_ip6, sizeof(tmpnip6)) < 0 || -      memcmp(tmpnip6, gconfig.end_ip6, sizeof(tmpnip6)) > 0) +  if (memcmp(nip6, gconfig.start_ip6, sizeof(uint32_t)*4) < 0 || +      memcmp(nip6, gconfig.end_ip6, sizeof(uint32_t)*4) > 0)      return -3;    return 0; @@ -1403,7 +1384,7 @@ static int addip_to_lease(uint32_t assigned_nip, uint8_t mac[6], uint32_t *req_e    return 0;  } -static int addip6_to_lease(uint32_t *assigned_nip, uint8_t *duid, uint16_t ia_type, uint32_t iaid, uint32_t *lifetime, uint8_t update) +static int addip6_to_lease(uint8_t *assigned_nip, uint8_t *duid, uint16_t duid_len, uint16_t ia_type, uint32_t iaid, uint32_t *lifetime, uint8_t update)  {    dyn_lease6 *dls6;    struct arg_list *listdls = gstate.dleases; @@ -1419,8 +1400,8 @@ static int addip6_to_lease(uint32_t *assigned_nip, uint8_t *duid, uint16_t ia_ty    }    dls6 = xzalloc(sizeof(dyn_lease6)); -  dls6->duid_len = sizeof(duid); -  memcpy(dls6->duid, duid, dls6->duid_len); +  dls6->duid_len = duid_len;  +  memcpy(dls6->duid, duid, duid_len);    dls6->ia_type = ia_type;    dls6->iaid = iaid;    memcpy(dls6->lease_nip6, assigned_nip, sizeof(uint32_t)*4); @@ -1499,9 +1480,9 @@ static uint32_t getip_from_pool(uint32_t req_nip, uint8_t mac[6], uint32_t *req_    return nip;  } -static uint32_t *getip6_from_pool(uint8_t *duid, uint16_t duid_len, uint16_t ia_type, uint32_t iaid, uint32_t *lifetime) +static uint8_t *getip6_from_pool(uint8_t *duid, uint16_t duid_len, uint16_t ia_type, uint32_t iaid, uint32_t *lifetime)  { -  uint32_t nip6[4] = {0,}; +  static uint8_t nip6[16] = {0, };    static_lease6 *sls6 = gstate.leases.sleases6;    struct arg_list *listdls6 = gstate.dleases, *tmp = NULL; @@ -1521,7 +1502,7 @@ static uint32_t *getip6_from_pool(uint8_t *duid, uint16_t duid_len, uint16_t ia_      listdls6 = listdls6->next;    } -  if(!nip6[0] && !nip6[1] && !nip6[2] && !nip6[3]) { +  if(!memcmp(nip6, (uint8_t[16]){0}, sizeof(uint32_t)*4)) {      while(sls6) {        if(!memcmp(sls6->duid, duid, 6)) {          memcpy(nip6, sls6->nip6, sizeof(nip6)); @@ -1531,34 +1512,33 @@ static uint32_t *getip6_from_pool(uint8_t *duid, uint16_t duid_len, uint16_t ia_      }    } -  if(!nip6[0] && !nip6[1] && !nip6[2] && !nip6[3]) { -    uint32_t tmpip6[4] = {0,}; -    int i=3; -    memcpy(tmpip6, gconfig.start_ip6, sizeof(tmpip6)); -    htonl6(gconfig.start_ip6, nip6); -    while(memcmp(tmpip6, gconfig.end_ip6, sizeof(tmpip6))<=0) { +  if(!memcmp(nip6, (uint8_t[16]){0}, sizeof(uint32_t)*4)) { +    memcpy(nip6, gconfig.start_ip6, sizeof(nip6)); +    while(memcmp(nip6, gconfig.end_ip6, sizeof(nip6)) < 0) {        if(!verifyip6_in_lease(nip6, duid, ia_type, iaid)) break; -      ntohl6(nip6, tmpip6); +      int i=sizeof(nip6);        while(i--) { -        if (tmpip6[i] == 0xffff) { -          tmpip6[i] = 0x0001; -        } else { -          ++tmpip6[i]; +        ++nip6[i]; +        if (!nip6[i]) { +          if(i==(sizeof(nip6)-1)) ++nip6[i]; +          ++nip6[i-1]; +        } else            break; -        }        } -      htonl6(tmpip6, nip6);      } -    ntohl6(nip6, tmpip6); -    if (memcmp(tmpip6, gconfig.end_ip6, sizeof(tmpip6))>0) { +    if (memcmp(nip6, gconfig.end_ip6, sizeof(nip6)) > 0) {        memset(nip6, 0, sizeof(nip6));        infomsg(infomode, "can't find free IP in IPv6 Pool.");      }    } -  if(nip6[0] && nip6[1] && nip6[2] && nip6[3]) -    addip6_to_lease(nip6, duid, ia_type, iaid, lifetime, 1); +  if(memcmp(nip6, (uint8_t[16]){0}, sizeof(uint32_t)*4)) { +    addip6_to_lease(nip6, duid, duid_len, ia_type, iaid, lifetime, 1); +    infomsg(infomode, "Assigned IPv6 %02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X", +        nip6[0], nip6[1], nip6[2], nip6[3], nip6[4], nip6[5], nip6[6], nip6[7], nip6[8], +        nip6[9], nip6[10], nip6[11], nip6[12], nip6[13], nip6[14], nip6[15]); +  }    return nip6;  } @@ -1595,7 +1575,7 @@ lease_error_exit:  static void read_lease6file(void)  { -  uint32_t passed, ip6[4]; +  uint32_t passed;    uint32_t tmp_time;    int64_t timestamp;    dyn_lease6 *dls6; @@ -1611,12 +1591,11 @@ static void read_lease6file(void)    if ((uint64_t)passed > 12 * 60 * 60) goto lease6_error_exit;    while (read(fd, dls6, sizeof(dyn_lease6)) == sizeof(dyn_lease6)) { -    ntohl6(dls6->lease_nip6, ip6); -    if (memcmp(ip6, gconfig.start_ip6, sizeof(ip6))<0 && -        memcmp(ip6, gconfig.end_ip6, sizeof(ip6))>9) { +    if (memcmp(dls6->lease_nip6, gconfig.start_ip6, sizeof(uint32_t)*4) > 0 && +        memcmp(dls6->lease_nip6, gconfig.end_ip6, sizeof(uint32_t)*4) < 0) {        tmp_time = ntohl(dls6->expires) - passed;        if (tmp_time < 0U) continue; -      addip6_to_lease(dls6->lease_nip6, dls6->duid, dls6->ia_type, dls6->iaid, +      addip6_to_lease(dls6->lease_nip6, dls6->duid, dls6->duid_len, dls6->ia_type, dls6->iaid,            (uint32_t*)&tmp_time, 0);      }    } @@ -1633,7 +1612,6 @@ void dhcpd_main(void)    uint8_t *optptr, msgtype = 0;    uint16_t optlen = 0;    uint32_t waited = 0, serverid = 0, requested_nip = 0; -  uint32_t requested_nip6[4] = {0,};    uint8_t transactionid[3] = {0,};    uint32_t reqested_lease = 0, ip_pool_size = 0;    char *hstname = NULL; @@ -1655,12 +1633,11 @@ void dhcpd_main(void)    if (flag_chk(FLAG_6)){      addr_version = AF_INET6; -    ntohl6(gconfig.start_ip6, gconfig.start_ip6); -    ntohl6(gconfig.end_ip6, gconfig.end_ip6);      gconfig.t1 = ntohl(gconfig.t1);      gconfig.t2 = ntohl(gconfig.t2);      gconfig.pref_lifetime = ntohl(gconfig.pref_lifetime);      gconfig.valid_lifetime = ntohl(gconfig.valid_lifetime); +    gconfig.port = 547;      for(i=0;i<4;i++)        ip_pool_size += (gconfig.end_ip6[i]-gconfig.start_ip6[i])<<((3-i)*8);    } else { @@ -1676,17 +1653,17 @@ void dhcpd_main(void)    }    write_pid(gconfig.pidfile);    set_maxlease(); -  read_leasefile();    if(TT.iface) gconfig.interface = TT.iface; +  if(TT.port) gconfig.port = TT.port;    (addr_version==AF_INET6) ? read_lease6file() : read_leasefile(); +    if (get_interface(gconfig.interface, &gconfig.ifindex, -        (addr_version==AF_INET6)? gconfig.server_nip6 : &gconfig.server_nip, -        gconfig.server_mac)<0) +        (addr_version==AF_INET6)? (void*)gconfig.server_nip6 : +        (void*)&gconfig.server_nip, gconfig.server_mac) < 0)      perror_exit("Failed to get interface %s", gconfig.interface);    setup_signal();    if (addr_version==AF_INET6) { -    htonl6(gconfig.server_nip6, gconfig.server_nip6);      open_listensock6();    } else {      gconfig.server_nip = htonl(gconfig.server_nip); @@ -1720,14 +1697,14 @@ void dhcpd_main(void)      if (!retval) { // Timed out         dbg("select wait Timed Out...\n");        waited = 0; -      (addr_version==AF_INET6)? write_lease6file() : write_leasefile(); +      (addr_version == AF_INET6)? write_lease6file() : write_leasefile();        if (get_interface(gconfig.interface, &gconfig.ifindex, -            (addr_version==AF_INET6)? gconfig.server_nip6 : &gconfig.server_nip, -            gconfig.server_mac)<0) +            (addr_version==AF_INET6)? (void*)gconfig.server_nip6 : +            (void*)&gconfig.server_nip, gconfig.server_mac)<0)          perror_exit("Failed to get interface %s", gconfig.interface); -      if(addr_version == AF_INET6) { -        htonl6(gconfig.server_nip6, gconfig.server_nip6); -      } else gconfig.server_nip = htonl(gconfig.server_nip); +      if(addr_version != AF_INET6) { +        gconfig.server_nip = htonl(gconfig.server_nip); +      }        continue;      }      if (FD_ISSET(sigfd.rd, &rfds)) { // Some Activity on RDFDs : is signal  @@ -1750,11 +1727,11 @@ void dhcpd_main(void)          default: break;        }      } -    if (FD_ISSET(gstate.listensock, &rfds)) { // Some Activity on RDFDs : is socke +    if (FD_ISSET(gstate.listensock, &rfds)) { // Some Activity on RDFDs : is socket        dbg("select listen sock read\n");        if(addr_version==AF_INET6) {          void *client_duid, *server_duid, *client_ia_na, *server_ia_na, -             *client_ia_pd, *server_ia_pd; +             *client_ia_pd;          uint8_t client_lla[6] = {0,};          uint16_t client_duid_len = 0, server_duid_len = 0, server_ia_na_len = 0,                   client_ia_na_len = 0, client_ia_pd_len = 0; @@ -1790,6 +1767,10 @@ void dhcpd_main(void)              //TODO policy check              //TODO Receive: ORO check (e.g. DNS) +            //Receive: Client Identifier (DUID) +            get_optval6((uint8_t*)&gstate.rcvd.rcvd_pkt6.options, +                DHCP6_OPT_CLIENTID, &client_duid_len, &client_duid); +              //Receive: Identity Association for Non-temporary Address              if(get_optval6((uint8_t*)&gstate.rcvd.rcvd_pkt6.options,                    DHCP6_OPT_IA_NA, &client_ia_na_len, &client_ia_na)) { @@ -1797,7 +1778,7 @@ void dhcpd_main(void)                void *ia_addr, *status_code;                char *status_code_msg;                uint16_t status_code_len = 0; -              server_ia_na_len = sizeof(struct optval_ia_na)-sizeof(uint8_t*); +              server_ia_na_len = sizeof(struct optval_ia_na);                //IA Address                ia_addr = xzalloc(ia_addr_len); @@ -1811,14 +1792,14 @@ void dhcpd_main(void)                server_ia_na_len += (ia_addr_len+4);                //Status Code -              if(*(*ia_addr_p).ipv6_addr) { +              if(memcmp((*ia_addr_p).ipv6_addr, (uint8_t[16]){0}, sizeof(uint32_t)*4)) {                  status_code_msg = xstrdup("Assigned an address.");                  status_code_len = strlen(status_code_msg)+1;                  status_code = xzalloc(status_code_len);                  struct optval_status_code *status_code_p =                    (struct optval_status_code*)status_code;                  (*status_code_p).status_code = htons(DHCP6_STATUS_SUCCESS); -                memcpy(&(*status_code_p).status_msg, status_code_msg, +                memcpy((*status_code_p).status_msg, status_code_msg,                      status_code_len);                  server_ia_na_len += (status_code_len+4);                  free(status_code_msg); @@ -1829,7 +1810,7 @@ void dhcpd_main(void)                  struct optval_status_code *status_code_p =                    (struct optval_status_code*)status_code;                  (*status_code_p).status_code = htons(DHCP6_STATUS_NOADDRSAVAIL); -                memcpy(&(*status_code_p).status_msg, status_code_msg, +                memcpy((*status_code_p).status_msg, status_code_msg,                      status_code_len);                  server_ia_na_len += (status_code_len+4);                  server_ia_na_len -= (ia_addr_len+4); @@ -1847,7 +1828,7 @@ void dhcpd_main(void)                (*ia_na_p).t1 = gconfig.t1;                (*ia_na_p).t2 = gconfig.t2; -              uint8_t* ia_na_optptr = &(*ia_na_p).optval; +              uint8_t* ia_na_optptr = (*ia_na_p).optval;                if(ia_addr_len) {                  set_optval6(ia_na_optptr, DHCP6_OPT_IA_ADDR, ia_addr, ia_addr_len);                  ia_na_optptr += (ia_addr_len + 4); @@ -1874,10 +1855,6 @@ void dhcpd_main(void)                //Response: Identity Association for Prefix Delegation              } -            //Receive: Client Identifier (DUID) -            get_optval6((uint8_t*)&gstate.rcvd.rcvd_pkt6.options, -                DHCP6_OPT_CLIENTID, &client_duid_len, &client_duid); -              //DUID type: link-layer address plus time              if(ntohs((*(struct optval_duid_llt*)client_duid).type) ==                  DHCP6_DUID_LLT) { @@ -1889,9 +1866,9 @@ void dhcpd_main(void)                (*server_duid_p).hwtype = htons(1);                (*server_duid_p).time = htonl((uint32_t)                    (time(NULL) - 946684800) & 0xffffffff); -              memcpy(&(*server_duid_p).lladdr, gconfig.server_mac, +              memcpy((*server_duid_p).lladdr, gconfig.server_mac,                    sizeof(gconfig.server_mac)); -              memcpy(&client_lla, &(*(struct optval_duid_llt*)client_duid).lladdr, +              memcpy(&client_lla, (*(struct optval_duid_llt*)client_duid).lladdr,                    sizeof(client_lla));                //Response: Server Identifier (DUID) @@ -1919,7 +1896,7 @@ void dhcpd_main(void)              optptr = set_optval6(optptr, DHCP6_OPT_CLIENTID, client_duid,                  client_duid_len);              optlen += (client_duid_len + 4); -            memcpy(&client_lla, &(*(struct optval_duid_llt*)client_duid).lladdr, +            memcpy(client_lla, (*(struct optval_duid_llt*)client_duid).lladdr,                  sizeof(client_lla));              //Receive: Identity Association for Non-temporary Address @@ -1927,12 +1904,11 @@ void dhcpd_main(void)                    DHCP6_OPT_IA_NA, &client_ia_na_len, &client_ia_na)) {                uint16_t ia_addr_len = 0, status_code_len = 0;                void *ia_addr, *status_code; -              uint16_t server_ia_na_len = -                sizeof(struct optval_ia_na)-sizeof(uint8_t*); +              uint16_t server_ia_na_len = sizeof(struct optval_ia_na);                char *status_code_msg;                //Check IA Address -              get_optval6((uint8_t*)&(*(struct optval_ia_na*)client_ia_na).optval, +              get_optval6((uint8_t*)(*(struct optval_ia_na*)client_ia_na).optval,                    DHCP6_OPT_IA_ADDR, &ia_addr_len, &ia_addr);                struct optval_ia_addr *ia_addr_p = (struct optval_ia_addr*)ia_addr;                if(verifyip6_in_lease((*ia_addr_p).ipv6_addr, client_duid, @@ -1946,7 +1922,7 @@ void dhcpd_main(void)                  struct optval_status_code *status_code_p =                    (struct optval_status_code*)status_code;                  (*status_code_p).status_code = htons(DHCP6_STATUS_SUCCESS); -                memcpy(&(*status_code_p).status_msg, status_code_msg, +                memcpy((*status_code_p).status_msg, status_code_msg,                      status_code_len);                  server_ia_na_len += (status_code_len+4);                } else { @@ -1961,7 +1937,7 @@ void dhcpd_main(void)                (*ia_na_p).t1 = gconfig.t1;                (*ia_na_p).t2 = gconfig.t2; -              uint8_t* ia_na_optptr = &(*ia_na_p).optval; +              uint8_t* ia_na_optptr = (*ia_na_p).optval;                ia_na_optptr = set_optval6(ia_na_optptr, DHCP6_OPT_IA_ADDR,                    ia_addr, ia_addr_len);                free(ia_addr); @@ -1992,8 +1968,9 @@ void dhcpd_main(void)              send_packet6(0, client_lla, optlen);              write_lease6file();              break; -          case DHCP6RENEW:  //TODO -          case DHCP6REBIND: //TODO +          case DHCP6DECLINE:  //TODO +          case DHCP6RENEW:    //TODO +          case DHCP6REBIND:   //TODO            case DHCP6RELEASE:              dbg("Message Type: DHCP6RELEASE\n");              optptr = prepare_send_pkt6(DHCP6REPLY);  | 
