diff options
-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); |