diff --git a/libbbfdm-api/dmcommon.c b/libbbfdm-api/dmcommon.c index 0ffe2f87..7219b2d8 100644 --- a/libbbfdm-api/dmcommon.c +++ b/libbbfdm-api/dmcommon.c @@ -70,77 +70,97 @@ char *IPPrefix[] = {"^$", "^/(3[0-2]|[012]?[0-9])$", "^((25[0-5]|2[0-4][0-9]|[01 char *IPv4Prefix[] = {"^$", "^/(3[0-2]|[012]?[0-9])$", "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/(3[0-2]|[012]?[0-9])$", NULL}; char *IPv6Prefix[] = {"^$", "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/(12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$", NULL}; -struct option_tag_type TYPE_TAG_ARRAY[] = { -{1, OPTION_IP, 4}, -{2, OPTION_INT, 4}, -{3, OPTION_IP, 4}, -{4, OPTION_IP, 4}, -{5, OPTION_IP, 4}, -{6, OPTION_IP, 4}, -{7, OPTION_IP, 4}, -{8, OPTION_IP, 4}, -{9, OPTION_IP, 4}, -{10, OPTION_IP, 4}, -{11, OPTION_IP, 4}, -{13, OPTION_INT, 2}, -{16, OPTION_IP, 4}, -{19, OPTION_INT, 1}, -{20, OPTION_INT, 1}, -{21, OPTION_IP, 4}, -{22, OPTION_INT, 2}, -{23, OPTION_INT, 1}, -{24, OPTION_INT, 4}, -{25, OPTION_INT, 2}, -{26, OPTION_INT, 2}, -{27, OPTION_INT, 1}, -{28, OPTION_IP, 4}, -{29, OPTION_INT, 1}, -{30, OPTION_INT, 1}, -{31, OPTION_INT, 1}, -{32, OPTION_IP, 4}, -{33, OPTION_IP, 4}, -{34, OPTION_INT, 1}, -{35, OPTION_INT, 4}, -{36, OPTION_INT, 1}, -{37, OPTION_INT, 1}, -{38, OPTION_INT, 4}, -{39, OPTION_INT, 1}, -{41, OPTION_IP, 4}, -{42, OPTION_IP, 4}, -{43, OPTION_HEX, 1}, -{44, OPTION_IP, 4}, -{45, OPTION_IP, 4}, -{46, OPTION_INT, 1}, -{48, OPTION_IP, 4}, -{49, OPTION_IP, 4}, -{50, OPTION_IP, 4}, -{51, OPTION_IP, 4}, -{52, OPTION_INT, 1}, -{53, OPTION_INT, 1}, -{54, OPTION_INT, 4}, -{57, OPTION_INT, 2}, -{58, OPTION_INT, 4}, -{59, OPTION_INT, 4}, -{65, OPTION_IP, 4}, -{68, OPTION_IP, 4}, -{69, OPTION_IP, 4}, -{70, OPTION_IP, 4}, -{71, OPTION_IP, 4}, -{72, OPTION_IP, 4}, -{73, OPTION_IP, 4}, -{74, OPTION_IP, 4}, -{75, OPTION_IP, 4}, -{76, OPTION_IP, 4}, -{118, OPTION_IP, 4}, -{125, OPTION_HEX, 1}, -{145, OPTION_INT, 1}, -{152, OPTION_INT, 4}, -{153, OPTION_INT, 4}, -{154, OPTION_INT, 4}, -{155, OPTION_INT, 4}, -{156, OPTION_INT, 1}, -{157, OPTION_INT, 1}, -{159, OPTION_INT, 4} +struct dhcp_options_type DHCP_OPTIONS_ARRAY[] = { +/* config_name, tag, type, length */ +{"subnet", 1, OPTION_IP, 4}, /* DHCP_SUBNET */ +{"timezone", 2, OPTION_INT, 4}, /* DHCP_TIME_OFFSET */ +{"router", 3, OPTION_IP, 4}, /* DHCP_ROUTER */ +{"timesrv", 4, OPTION_IP, 4}, /* DHCP_TIME_SERVER */ +{"namesrv", 5, OPTION_IP, 4}, /* DHCP_NAME_SERVER */ +{"dns", 6, OPTION_IP, 4}, /* DHCP_DNS_SERVER */ +{"logsrv", 7, OPTION_IP, 4}, /* DHCP_LOG_SERVER */ +{"cookiesrv", 8, OPTION_IP, 4}, /* DHCP_COOKIE_SERVER */ +{"lprsrv", 9, OPTION_IP, 4}, /* DHCP_LPR_SERVER */ +{"", 10, OPTION_IP, 4}, /* DHCP_IMPRESS_SERVER */ +{"", 11, OPTION_IP, 4}, /* DHCP_RLP SERVER */ +{"hostname", 12, OPTION_STRING, 0}, /* DHCP_HOST_NAME */ +{"bootsize", 13, OPTION_INT, 2}, /* DHCP_BOOT_SIZE */ +{"domain", 15, OPTION_STRING, 0}, /* DHCP_DOMAIN_NAME */ +{"swapsrv", 16, OPTION_IP, 4}, /* DHCP_SWAP_SERVER */ +{"rootpath", 17, OPTION_STRING, 0}, /* DHCP_ROOT_PATH */ +{"", 19, OPTION_INT, 1}, /* DHCP_FORWARD */ +{"", 20, OPTION_INT, 1}, /* DHCP_SOURCE_ROUTING */ +{"", 21, OPTION_IP, 4}, /* DHCP_POLICY_FILTER */ +{"", 22, OPTION_INT, 2}, /* DHCP_MAX_DG_ASSEMBLY */ +{"ipttl", 23, OPTION_INT, 1}, /* DHCP_IP_TTL */ +{"", 24, OPTION_INT, 4}, /* DHCP_MTU_TIMEOUT */ +{"", 25, OPTION_INT, 2}, /* DHCP_MTU_PLATEAU */ +{"mtu", 26, OPTION_INT, 2}, /* DHCP_MTU_INTERFACE */ +{"", 27, OPTION_INT, 1}, /* DHCP_MTU_SUBNET */ +{"broadcast", 28, OPTION_IP, 4}, /* DHCP_BROADCAST */ +{"", 29, OPTION_INT, 1}, /* DHCP_MASK_DISCOVERY */ +{"", 30, OPTION_INT, 1}, /* DHCP_MASK_SUPPLIER */ +{"", 31, OPTION_INT, 1}, /* DHCP_ROUTER_DISCOVERY */ +{"", 32, OPTION_IP, 4}, /* DHCP_ROUTER_REQUEST */ +{"routes", 33, OPTION_IP, 4}, /* DHCP_ROUTES */ +{"", 34, OPTION_INT, 1}, /* DHCP_TRAILER */ +{"", 35, OPTION_INT, 4}, /* DHCP_ARP_TIMEOUT */ +{"", 36, OPTION_INT, 1}, /* DHCP_ETHERNET */ +{"", 37, OPTION_INT, 1}, /* DHCP_DEFAULT_TCP_TTL */ +{"", 38, OPTION_INT, 4}, /* DHCP_KEEPALIVE_TIME */ +{"", 39, OPTION_INT, 1}, /* DHCP_KEEPALIVE_DATA */ +{"nisdomain", 40, OPTION_STRING, 0}, /* DHCP_NIS_DOMAIN */ +{"nissrv", 41, OPTION_IP, 4}, /* DHCP_NIS_SERVER */ +{"ntpsrv", 42, OPTION_IP, 4}, /* DHCP_NTP_SERVER */ +{"", 43, OPTION_HEX, 1}, /* DHCP_VENDOR_SPECIFIC */ +{"wins", 44, OPTION_IP, 4}, /* DHCP_WINS_SERVER */ +{"", 46, OPTION_INT, 1}, /* DHCP_NETBIOS */ +{"", 50, OPTION_IP, 4}, /* DHCP_ADDRESS_REQUEST */ +{"lease", 51, OPTION_INT, 4}, /* DHCP_LEASE_TIME */ +{"", 52, OPTION_INT, 1}, /* DHCP_OVERLOAD */ +{"", 53, OPTION_INT, 1}, /* DHCP_MESSSAGE_TYPE */ +{"serverid", 54, OPTION_IP, 4}, /* DHCP_SERVER_ID */ +{"message", 56, OPTION_STRING, 0}, /* DHCP_ERR_MESSAGE */ +{"", 57, OPTION_INT, 2}, /* DHCP_MAX_MESSAGE_SIZE */ +{"", 58, OPTION_INT, 4}, /* DHCP_RENEWAL_TIME */ +{"", 59, OPTION_INT, 4}, /* DHCP_REBINDING_TIME */ +{"vendor", 60, OPTION_STRING, 0}, /* DHCP_VENDOR */ +{"", 65, OPTION_IP, 4}, /* DHCP_NIS_SERVER_ADDR */ +{"tftp", 66, OPTION_STRING, 0}, /* DHCP_TFTP_SERVER_NAME */ +{"bootfile", 67, OPTION_STRING, 0}, /* DHCP_BOOT_FILE */ +{"", 68, OPTION_IP, 4}, /* DHCP_HOME_AGENT */ +{"", 69, OPTION_IP, 4}, /* DHCP_SMTP_SERVER */ +{"", 70, OPTION_IP, 4}, /* DHCP_POP3_SERVER */ +{"", 71, OPTION_IP, 4}, /* DHCP_NNTP_SERVER */ +{"", 72, OPTION_IP, 4}, /* DHCP_WWW_SERVER */ +{"", 73, OPTION_IP, 4}, /* DHCP_FINGER_SERVER */ +{"", 74, OPTION_IP, 4}, /* DHCP_IRC_SERVER */ +{"", 75, OPTION_IP, 4}, /* DHCP_STREET_TALK_SERVER */ +{"", 76, OPTION_IP, 4}, /* DHCP_STDA_SERVER */ +{"userclass", 77, OPTION_STRING, 0}, /* DHCP_USER_CLASS */ +{"tzstr", 100, OPTION_STRING, 0}, /* DHCP_PCODE */ +{"tzdbstr", 101, OPTION_STRING, 0}, /* DHCP_TCODE */ +{"", 118, OPTION_IP, 4}, /* DHCP_SUBNET_SELECTION */ +{"search", 119, OPTION_STRING, 0}, /* DHCP_DOMAIN_SEARCH */ +{"sipsrv", 120, OPTION_STRING, 0}, /* DHCP_SIP_SERVERS */ +{"staticroutes", 121, OPTION_STRING, 0}, /* DHCP_STATIC_ROUTES */ +{"", 125, OPTION_HEX, 1}, /* DHCP_VI_VENDOR_SPECIFIC */ +{"vlanid", 132, OPTION_INT, 2}, /* DHCP_VLAN_ID */ +{"vlanpriority", 133, OPTION_INT, 1}, /* DHCP_VLAN_PRIORITY */ +{"", 145, OPTION_INT, 1}, /* DHCP_FORCERENEW */ +{"", 152, OPTION_INT, 4}, /* DHCP_BASE_TIME */ +{"", 153, OPTION_INT, 4}, /* DHCP_START_TIME */ +{"", 154, OPTION_INT, 4}, /* DHCP_QUERY_START_TIME */ +{"", 155, OPTION_INT, 4}, /* DHCP_QUERY_END_TIME */ +{"", 156, OPTION_INT, 1}, /* DHCP_STATE */ +{"", 157, OPTION_INT, 1}, /* DHCP_DATA_SOURCE */ +{"", 159, OPTION_INT, 4}, /* DHCP_PORT_PARAMS */ +{"pxeconffile", 209, OPTION_STRING, 0}, /* DHCP_PXE_CONF_FILE */ +{"pxepathprefix", 210, OPTION_STRING, 0}, /* DHCP_PXE_PATH_PREFIX */ +{"reboottime", 211, OPTION_INT, 4}, /* DHCP_REBOOT_TIME */ +{"ip6rd", 212, OPTION_STRING, 0}, /* DHCP_6RD */ +{"msstaticroutes", 249, OPTION_STRING, 0}, /* DHCP_MS_STATIC_ROUTES */ +{"wpad", 225, OPTION_STRING, 0}, /* DHCP_WPAD */ }; pid_t get_pid(const char *pname) @@ -687,11 +707,29 @@ unsigned int count_occurrences(char *str, char c) return count; } -unsigned char isdigit_str(char *str) +bool isdigit_str(const char *str) { - if (!(*str)) return 0; + if (!DM_STRLEN(str)) + return 0; + while(isdigit(*str++)); - return ((*(str-1)) ? 0 : 1); + + return (*(str-1)) ? 0 : 1; +} + +bool ishex_str(const char *str) +{ + char *endptr = NULL; + + if (DM_STRLEN(str) < 2) + return 0; + + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) + return 0; + + strtol(str, &endptr, 0); + + return DM_STRLEN(endptr) ? 0 : 1; } bool special_char(char c) @@ -831,7 +869,7 @@ bool value_exists_in_uci_list(struct uci_list *list, const char *value) { struct uci_element *e = NULL; - if (list == NULL) + if (list == NULL || value == NULL) return false; uci_foreach_element(list, e) { @@ -842,78 +880,63 @@ bool value_exists_in_uci_list(struct uci_list *list, const char *value) return false; } -bool value_exits_in_str_list(char *str_list, const char *delimitor, const char *value) +bool value_exits_in_str_list(char *str_list, const char *delimitor, const char *str) { - char *pch, *spch; + char *pch = NULL, *spch = NULL; - if (str_list == NULL || *str_list == '\0') + if (!DM_STRLEN(str_list) || !delimitor || !str) return false; char *list = dmstrdup(str_list); + for (pch = strtok_r(list, delimitor, &spch); pch != NULL; pch = strtok_r(NULL, delimitor, &spch)) { - if (DM_STRCMP(pch, value) == 0) + if (DM_STRCMP(pch, str) == 0) return true; } + return false; } -void add_elt_to_str_list(char **str_list, char *elt) +char *add_str_to_str_list(char *str_list, const char *delimitor, const char *str) { - if (*str_list == NULL || DM_STRLEN(*str_list) == 0) { - dmasprintf(str_list, "%s", elt); - return; - } + char *res = ""; - char *list = dmstrdup(*str_list); - dmfree(*str_list); - *str_list = NULL; - dmasprintf(str_list, "%s %s", list, elt); + if (!str_list || !delimitor || !str) + return ""; + + dmasprintf(&res, "%s%s%s", str_list, strlen(str_list) ? delimitor : "", str); + + return res; } -void remove_elt_from_str_list(char **str_list, char *ifname) +char *remove_str_from_str_list(char *str_list, const char *delimitor, const char *str) { - char *list = NULL, *tmp = NULL, *pch = NULL, *spch = NULL; + char *pch = NULL, *spch = NULL; + unsigned pos = 0; - if (*str_list == NULL || DM_STRLEN(*str_list) == 0) - return; + if (!str_list || !delimitor || !str) + return ""; - list = dmstrdup(*str_list); - dmfree(*str_list); - *str_list = NULL; + int len = strlen(str_list); + int del_len = strlen(delimitor); - for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { - if (DM_STRCMP(pch, ifname) == 0) + char *res = (char *)dmcalloc(len + 1, sizeof(char)); + char *list = dmstrdup(str_list); + + for (pch = strtok_r(list, delimitor, &spch); pch != NULL; pch = strtok_r(NULL, delimitor, &spch)) { + + if (DM_STRCMP(pch, str) == 0) continue; - if (tmp == NULL) - dmasprintf(str_list, "%s", pch); - else - dmasprintf(str_list, "%s %s", tmp, pch); - - if (tmp) { - dmfree(tmp); - tmp = NULL; - } - - if (*str_list) { - tmp = dmstrdup(*str_list); - dmfree(*str_list); - *str_list = NULL; - } + pos += snprintf(&res[pos], len + 1 - pos, "%s%s", pch, delimitor); } - dmasprintf(str_list, "%s", tmp ? tmp : ""); -} + dmfree(list); -bool elt_exists_in_array(char **str_array, char *str, int length) -{ - int i; + if (pos) + res[pos - del_len] = 0; - for (i = 0; i < length; i++) { - if (DM_STRCMP(str_array[i], str) == 0) - return true; - } - return false; + return res; } int get_shift_utc_time(int shift_time, char *utc_time, int size) @@ -1114,6 +1137,23 @@ void convert_hex_to_string(const char *hex, char *str, size_t size) str[pos] = '\0'; } +int get_dhcp_option_number_by_name(const char *tag_name) +{ + if (!DM_STRLEN(tag_name)) + return -1; + + for (int i = 0; i < ARRAY_SIZE(DHCP_OPTIONS_ARRAY); i++) { + + if (DM_STRLEN(DHCP_OPTIONS_ARRAY[i].config_name) == 0) + continue; + + if (strcmp(DHCP_OPTIONS_ARRAY[i].config_name, tag_name) == 0) + return DHCP_OPTIONS_ARRAY[i].tag; + } + + return -1; +} + void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, size_t size) { int idx = -1; @@ -1121,8 +1161,8 @@ void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, siz if (str == NULL || hex == NULL || size == 0) return; - for (int i = 0; i < ARRAY_SIZE(TYPE_TAG_ARRAY); i++) { - if (TYPE_TAG_ARRAY[i].tag == tag) { + for (int i = 0; i < ARRAY_SIZE(DHCP_OPTIONS_ARRAY); i++) { + if (DHCP_OPTIONS_ARRAY[i].tag == tag) { idx = i; break; } @@ -1139,7 +1179,7 @@ void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, siz DM_STRNCPY(buf, str, sizeof(buf)); for (pch = strtok_r(buf, ",", &spch); pch != NULL; pch = strtok_r(NULL, ",", &spch)) { - if (TYPE_TAG_ARRAY[idx].type == OPTION_IP) { + if (DHCP_OPTIONS_ARRAY[idx].type == OPTION_IP) { struct in_addr ip_bin; if (!inet_aton(pch, &ip_bin)) @@ -1147,24 +1187,26 @@ void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, siz unsigned int ip = ntohl(ip_bin.s_addr); - if (size - pos < TYPE_TAG_ARRAY[idx].len * 2) + if (size - pos < DHCP_OPTIONS_ARRAY[idx].len * 2) return; pos += snprintf(&hex[pos], size - pos, "%08X", ip); - } else if (TYPE_TAG_ARRAY[idx].type == OPTION_HEX) { + } else if (DHCP_OPTIONS_ARRAY[idx].type == OPTION_HEX) { for (int j = 0; j < DM_STRLEN(pch) && pos < size - 1; j++) { if (pch[j] == ':') continue; pos += snprintf(&hex[pos], size - pos, "%c", pch[j]); } + } else if (DHCP_OPTIONS_ARRAY[idx].type == OPTION_STRING) { + convert_string_to_hex(pch, hex, size); } else { long int val = DM_STRTOL(pch); - if (size - pos < TYPE_TAG_ARRAY[idx].len * 2) + if (size - pos < DHCP_OPTIONS_ARRAY[idx].len * 2) return; - pos += snprintf(&hex[pos], size - pos, (TYPE_TAG_ARRAY[idx].len == 4) ? "%08lX" : (TYPE_TAG_ARRAY[idx].len == 2) ? "%04lX" : "%02lX", val); + pos += snprintf(&hex[pos], size - pos, (DHCP_OPTIONS_ARRAY[idx].len == 4) ? "%08lX" : (DHCP_OPTIONS_ARRAY[idx].len == 2) ? "%04lX" : "%02lX", val); } } } @@ -1176,8 +1218,8 @@ void convert_hex_option_to_string(unsigned int tag, const char *hex, char *str, if (hex == NULL || str == NULL || size == 0) return; - for (int i = 0; i < ARRAY_SIZE(TYPE_TAG_ARRAY); i++) { - if (TYPE_TAG_ARRAY[i].tag == tag) { + for (int i = 0; i < ARRAY_SIZE(DHCP_OPTIONS_ARRAY); i++) { + if (DHCP_OPTIONS_ARRAY[i].tag == tag) { idx = i; break; } @@ -1190,14 +1232,14 @@ void convert_hex_option_to_string(unsigned int tag, const char *hex, char *str, unsigned pos = 0; unsigned int str_len = DM_STRLEN(hex); - unsigned int len = TYPE_TAG_ARRAY[idx].len * 2; + unsigned int len = DHCP_OPTIONS_ARRAY[idx].len * 2; char buffer[32] = {0}; char buf[16] = {0}; for (int i = 0; i + len <= str_len; i = i + len) { DM_STRNCPY(buf, &hex[i], len + 1); - if (TYPE_TAG_ARRAY[idx].type == OPTION_IP) { + if (DHCP_OPTIONS_ARRAY[idx].type == OPTION_IP) { struct in_addr addr; unsigned int ip; @@ -1205,7 +1247,7 @@ void convert_hex_option_to_string(unsigned int tag, const char *hex, char *str, addr.s_addr = htonl(ip); char *ipaddr = inet_ntoa(addr); snprintf(buffer, sizeof(buffer), "%s,", ipaddr); - } else if (TYPE_TAG_ARRAY[idx].type == OPTION_HEX) { + } else if (DHCP_OPTIONS_ARRAY[idx].type == OPTION_HEX) { snprintf(buffer, sizeof(buffer), "%s:", buf); } else { snprintf(buffer, sizeof(buffer), "%d,", (int)strtol(buf, NULL, 16)); diff --git a/libbbfdm-api/dmcommon.h b/libbbfdm-api/dmcommon.h index ab9bf682..dfb13bbb 100644 --- a/libbbfdm-api/dmcommon.h +++ b/libbbfdm-api/dmcommon.h @@ -174,6 +174,7 @@ enum fs_size_type_enum { enum option_type_enum { OPTION_IP, OPTION_INT, + OPTION_STRING, OPTION_HEX }; @@ -199,7 +200,8 @@ struct browse_args { char *value; }; -struct option_tag_type { +struct dhcp_options_type { + char *config_name; int tag; int type; int len; @@ -235,7 +237,8 @@ int dm_entry_validate_external_linker_allowed_objects(struct dmctx *ctx, char *v int dm_validate_allowed_objects(struct dmctx *ctx, struct dm_reference *reference, char *objects[]); char *check_create_dmmap_package(const char *dmmap_package); unsigned int count_occurrences(char *str, char c); -unsigned char isdigit_str(char *str); +bool isdigit_str(const char *str); +bool ishex_str(const char *str); bool special_char(char c); bool special_char_exits(const char *str); void replace_special_char(char *str, char c); @@ -246,9 +249,9 @@ char *get_macaddr(char *interface_name); char *get_device(char *interface_name); char *get_l3_device(char *interface_name); bool value_exists_in_uci_list(struct uci_list *list, const char *value); -bool value_exits_in_str_list(char *str_list, const char *delimitor, const char *value); -void add_elt_to_str_list(char **str_list, char *elt); -void remove_elt_from_str_list(char **str_list, char *ifname); +bool value_exits_in_str_list(char *str_list, const char *delimitor, const char *str); +char *add_str_to_str_list(char *str_list, const char *delimitor, const char *str); +char *remove_str_from_str_list(char *str_list, const char *delimitor, const char *str); struct uci_section *get_origin_section_from_config(char *package, char *section_type, char *orig_section_name); struct uci_section *get_origin_section_from_dmmap(char *package, char *section_type, char *orig_section_name); struct uci_section *get_dup_section_in_dmmap(char *dmmap_package, char *section_type, char *orig_section_name); @@ -256,7 +259,6 @@ struct uci_section *get_dup_section_in_config_opt(char *package, char *section_t struct uci_section *get_dup_section_in_dmmap_opt(char *dmmap_package, char *section_type, char *opt_name, char *opt_value); struct uci_section *get_dup_section_in_dmmap_eq(char *dmmap_package, char* section_type, char*sect_name, char *opt_name, char* opt_value); struct uci_section *get_section_in_dmmap_with_options_eq(char *dmmap_package, char *section_type, char *opt1_name, char *opt1_value, char *opt2_name, char *opt2_value); -bool elt_exists_in_array(char **str_array, char *str, int length); int get_shift_utc_time(int shift_time, char *utc_time, int size); int get_shift_time_time(int shift_time, char *local_time, int size); struct uci_section *is_dmmap_section_exist(char* package, char* section); @@ -271,6 +273,7 @@ void convert_string_to_hex(const char *str, char *hex, size_t size); void convert_hex_to_string(const char *hex, char *str, size_t size); void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, size_t size); void convert_hex_option_to_string(unsigned int tag, const char *hex, char *str, size_t size); +int get_dhcp_option_number_by_name(const char *tag_name); bool match(const char *string, const char *pattern, size_t nmatch, regmatch_t pmatch[]); void bbfdm_set_fault_message(struct dmctx *ctx, const char *format, ...); int bbfdm_validate_boolean(struct dmctx *ctx, char *value); diff --git a/libbbfdm/dmtree/tr181/dhcpv4.c b/libbbfdm/dmtree/tr181/dhcpv4.c index 15237efe..93ee05cd 100644 --- a/libbbfdm/dmtree/tr181/dhcpv4.c +++ b/libbbfdm/dmtree/tr181/dhcpv4.c @@ -554,6 +554,156 @@ static char *get_dhcp_option_name(int tag) } } +static void create_dhcp_client_option_instance(char *sec_name, char *key, char *tag, char *value) +{ + struct uci_section *dmmap_s = NULL; + + dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", sec_name, "dhcp_client_key", key, "option_tag", tag); + if (dmmap_s == NULL) { + dmuci_add_section_bbfdm("dmmap_dhcp_client", sec_name, &dmmap_s); + + dmuci_set_value_by_section_bbfdm(dmmap_s, "enable", "1"); + dmuci_set_value_by_section_bbfdm(dmmap_s, "dhcp_client_key", key); + dmuci_set_value_by_section_bbfdm(dmmap_s, "option_tag", tag); + } + + dmuci_set_value_by_section_bbfdm(dmmap_s, "option_value", value); +} + +static void fill_dhcp_option_value(char *option, char *tag, size_t tag_size, char *value, size_t value_size) +{ + long tag_num = 0; + + if (!option || !tag || !tag_size || !value || !value_size) + return; + + char *p = strchr(option, ':'); + if (!p) + return; + + *p = 0; + + if (isdigit_str(option) || ishex_str(option)) { + tag_num = strtol(option, NULL, 0); + unsigned pos = 0; + + char *val = p + 1; + + for (int i = 0; i < DM_STRLEN(val); i++) { + if (val[i] == ':') + continue; + + pos += snprintf(&value[pos], value_size - pos, "%c", val[i]); + } + } else { + tag_num = get_dhcp_option_number_by_name(option); + if (tag_num < 0) + return; + + convert_str_option_to_hex(tag_num, p + 1, value, value_size); + } + + snprintf(tag, tag_size, "%ld", tag_num); +} + +static void create_dhcp_sent_option_list(struct uci_section *iface_s, char *key) +{ + struct uci_section *dmmap_s = NULL; + char buf[1024] = {0}; + unsigned pos = 0; + + uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", key, dmmap_s) { + char *enable = NULL; + char *tag = NULL; + char *value = NULL; + + dmuci_get_value_by_section_string(dmmap_s, "enable", &enable); + if (DM_LSTRCMP(enable, "1") != 0) + continue; + + dmuci_get_value_by_section_string(dmmap_s, "option_tag", &tag); + dmuci_get_value_by_section_string(dmmap_s, "option_value", &value); + + char *option_name = get_dhcp_option_name(DM_STRTOL(tag)); + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s:%s ", tag, value); + } else { + char str[256] = {0}; + + convert_hex_to_string(value, str, sizeof(str)); + + dmuci_set_value_by_section(iface_s, option_name, str); + } + } + + if (pos) + buf[pos - 1] = 0; + + dmuci_set_value_by_section(iface_s, "sendopts", buf); +} + +static void create_dhcp_req_option_list(struct uci_section *iface_s, char *key) +{ + struct uci_section *dmmap_s = NULL; + char buf[256] = {0}; + unsigned pos = 0; + + uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", key, dmmap_s) { + char *enable = NULL; + char *tag = NULL; + + dmuci_get_value_by_section_string(dmmap_s, "enable", &enable); + if (DM_LSTRCMP(enable, "1") != 0) + continue; + + dmuci_get_value_by_section_string(dmmap_s, "option_tag", &tag); + + pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s ", tag); + } + + if (pos) + buf[pos - 1] = 0; + + dmuci_set_value_by_section(iface_s, "reqopts", buf); +} + +static char *remove_option_from_str_list(char *str_list, long tag) +{ + char *pch = NULL, *spch = NULL; + unsigned pos = 0; + + if (!str_list || !tag) + return ""; + + int len = strlen(str_list); + + char *res = (char *)dmcalloc(len + 1, sizeof(char)); + char *list = dmstrdup(str_list); + + for (pch = strtok_r(list, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + + char *p = strchr(pch, ':'); + if (!p) + continue; + + *p = 0; + + long tag_num = (isdigit_str(pch) || ishex_str(pch)) ? strtol(pch, NULL, 0) : get_dhcp_option_number_by_name(pch); + + if (tag_num == tag) + continue; + + pos += snprintf(&res[pos], len + 1 - pos, "%s:%s ", pch, p + 1); + } + + dmfree(list); + + if (pos) + res[pos - 1] = 0; + + return res; +} + /************************************************************* * ENTRY METHOD **************************************************************/ @@ -763,79 +913,58 @@ static int browseDHCPv4ClientSentOptionInst(struct dmctx *dmctx, DMNODE *parent_ struct uci_section *dhcp_client_s = ((struct dhcp_client_args *)prev_data)->iface_s; struct dhcp_client_option_args dhcp_client_opt_args = {0}; struct uci_section *dhcp_client_dmmap_s = NULL; - char *dhcp_client_key = NULL; - char *inst = NULL; + char *dhcp_client_key = NULL, *inst = NULL; + char value[256] = {0}; dmuci_get_value_by_section_string(((struct dhcp_client_args *)prev_data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); if (dhcp_client_s) { - size_t length = 0, length2 = 0; - char **sentopts = NULL; - char **buf = NULL; - char *vendorid = NULL; - char *clientid = NULL; - char *hostname = NULL; - char *options = NULL; + char *vendorid = NULL, *clientid = NULL, *hostname = NULL, *sendopts = NULL; - // vendorid option dmuci_get_value_by_section_string(dhcp_client_s, "vendorid", &vendorid); - if (vendorid && *vendorid != '\0') { - if ((dhcp_client_dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", "60")) == NULL) { - dmuci_add_section_bbfdm("dmmap_dhcp_client", "send_option", &dhcp_client_dmmap_s); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_tag", "60"); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "enable", "1"); - } - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_value", vendorid); + if (DM_STRLEN(vendorid)) { + // vendorid (option 60) + convert_str_option_to_hex(60, vendorid, value, sizeof(value)); + create_dhcp_client_option_instance("send_option", dhcp_client_key, "60", value); } - // clienid option dmuci_get_value_by_section_string(dhcp_client_s, "clientid", &clientid); - if (clientid && *clientid != '\0') { - if ((dhcp_client_dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", "61")) == NULL) { - dmuci_add_section_bbfdm("dmmap_dhcp_client", "send_option", &dhcp_client_dmmap_s); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_tag", "61"); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "enable", "1"); - } - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_value", clientid); + if (DM_STRLEN(clientid)) { + // clientid (option 61) + convert_str_option_to_hex(61, clientid, value, sizeof(value)); + create_dhcp_client_option_instance("send_option", dhcp_client_key, "61", value); } - // hostname option dmuci_get_value_by_section_string(dhcp_client_s, "hostname", &hostname); - if (hostname && *hostname != '\0') { - if ((dhcp_client_dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", "12")) == NULL) { - dmuci_add_section_bbfdm("dmmap_dhcp_client", "send_option", &dhcp_client_dmmap_s); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_tag", "12"); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "enable", "1"); - } - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_value", hostname); + if (DM_STRLEN(hostname)) { + // hostname (option 12) + convert_str_option_to_hex(12, hostname, value, sizeof(value)); + create_dhcp_client_option_instance("send_option", dhcp_client_key, "12", value); } // sendopts option - dmuci_get_value_by_section_string(dhcp_client_s, "sendopts", &options); + dmuci_get_value_by_section_string(dhcp_client_s, "sendopts", &sendopts); + if (DM_STRLEN(sendopts)) { + // sendopts (other options) + char *pch = NULL, *spch = NULL; - if (options && *options) - sentopts = strsplit(options, " ", &length); + for (pch = strtok_r(sendopts, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) { + char tag[16] = {0}; - for (int i = 0; i < length; i++) { - if (sentopts && sentopts[i]) - buf = strsplit(sentopts[i], ":", &length2); + value[0] = 0; - if ((dhcp_client_dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", buf[0])) == NULL) { - dmuci_add_section_bbfdm("dmmap_dhcp_client", "send_option", &dhcp_client_dmmap_s); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_tag", buf[0]); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "enable", "1"); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_value", length2 > 1 ? buf[1] : ""); + fill_dhcp_option_value(pch, tag, sizeof(tag), value, sizeof(value)); + + if (!DM_STRLEN(tag) || !DM_STRLEN(tag)) + continue; + + create_dhcp_client_option_instance("send_option", dhcp_client_key, tag, value); } } } uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, dhcp_client_dmmap_s) { - char *option_tag = NULL; - char *option_value = NULL; + char *option_tag = NULL, *option_value = NULL; dmuci_get_value_by_section_string(dhcp_client_dmmap_s, "option_tag", &option_tag); dmuci_get_value_by_section_string(dhcp_client_dmmap_s, "option_value", &option_value); @@ -850,6 +979,7 @@ static int browseDHCPv4ClientSentOptionInst(struct dmctx *dmctx, DMNODE *parent_ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&dhcp_client_opt_args, inst) == DM_STOP) break; } + return 0; } @@ -858,42 +988,31 @@ static int browseDHCPv4ClientReqOptionInst(struct dmctx *dmctx, DMNODE *parent_n struct uci_section *dhcp_client_s = ((struct dhcp_client_args *)prev_data)->iface_s; struct uci_section *dhcp_client_dmmap_s = NULL; struct dhcp_client_option_args dhcp_client_opt_args = {0}; - char *dhcp_client_key = NULL; - char *inst = NULL; + char *dhcp_client_key = NULL, *inst = NULL; dmuci_get_value_by_section_string(((struct dhcp_client_args *)prev_data)->dmmap_s, "dhcp_client_key", &dhcp_client_key); if (dhcp_client_s) { - char **reqtopts = NULL; - char *options = NULL; - size_t length = 0; + char *reqopts = NULL; - dmuci_get_value_by_section_string(dhcp_client_s, "reqopts", &options); + dmuci_get_value_by_section_string(dhcp_client_s, "reqopts", &reqopts); + if (DM_STRLEN(reqopts)) { + // reqopts option + char *pch = NULL, *spch = NULL; - if (options && *options) - reqtopts = strsplit(options, " ", &length); - - for (int i = 0; i < length; i++) { - if (reqtopts == NULL) - continue; - - if ((dhcp_client_dmmap_s = get_section_in_dmmap_with_options_eq("dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, "option_tag", reqtopts[i])) == NULL) { - dmuci_add_section_bbfdm("dmmap_dhcp_client", "req_option", &dhcp_client_dmmap_s); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "option_tag", reqtopts[i]); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "dhcp_client_key", dhcp_client_key); - dmuci_set_value_by_section_bbfdm(dhcp_client_dmmap_s, "enable", "1"); - } + for (pch = strtok_r(reqopts, " ", &spch); pch != NULL; pch = strtok_r(NULL, " ", &spch)) + create_dhcp_client_option_instance("req_option", dhcp_client_key, pch, ""); } } uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, dhcp_client_dmmap_s) { - char *option_tag = NULL; + char *tag = NULL; - dmuci_get_value_by_section_string(dhcp_client_dmmap_s, "option_tag", &option_tag); + dmuci_get_value_by_section_string(dhcp_client_dmmap_s, "option_tag", &tag); dhcp_client_opt_args.client_sect = dhcp_client_s; dhcp_client_opt_args.dmmap_sect = dhcp_client_dmmap_s; - dhcp_client_opt_args.option_tag = option_tag; + dhcp_client_opt_args.option_tag = tag; dhcp_client_opt_args.value = ""; inst = handle_instance(dmctx, parent_node, dhcp_client_dmmap_s, "bbf_dhcpv4_reqtopt_instance", "bbf_dhcpv4_reqtopt_alias"); @@ -901,6 +1020,7 @@ static int browseDHCPv4ClientReqOptionInst(struct dmctx *dmctx, DMNODE *parent_n if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&dhcp_client_opt_args, inst) == DM_STOP) break; } + return 0; } @@ -1179,11 +1299,8 @@ static int delObjDHCPv4ClientSentOption(char *refparam, struct dmctx *ctx, void char *sendopts = NULL; dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", &sendopts); - if (sendopts && *sendopts) { - char tag_value[128] = {0}; - - snprintf(tag_value, sizeof(tag_value), "%s:%s", ((struct dhcp_client_option_args *)data)->option_tag, ((struct dhcp_client_option_args *)data)->value); - remove_elt_from_str_list(&sendopts, tag_value); + if (DM_STRLEN(sendopts)) { + sendopts = remove_option_from_str_list(sendopts, DM_STRTOL(((struct dhcp_client_option_args *)data)->option_tag)); dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "sendopts", sendopts); } } else { @@ -1240,7 +1357,7 @@ static int delObjDHCPv4ClientReqOption(char *refparam, struct dmctx *ctx, void * dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", &reqopts); if (reqopts && *reqopts) { - remove_elt_from_str_list(&reqopts, ((struct dhcp_client_option_args*) data)->option_tag); + reqopts = remove_str_from_str_list(reqopts, " ", ((struct dhcp_client_option_args*) data)->option_tag); dmuci_set_value_by_section(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", reqopts); } } @@ -2214,51 +2331,14 @@ static int set_DHCPv4Client_Interface(char *refparam, struct dmctx *ctx, void *d dmuci_set_value_by_section_bbfdm(dhcpv4_client->dmmap_s, "iface_name", reference.value); dmuci_get_value_by_section_string(dhcpv4_client->dmmap_s, "dhcp_client_key", &dhcp_client_key); - if (DM_STRLEN(dhcp_client_key)) { - struct uci_section *option_s = NULL; - char buf[128] = {0}; - unsigned pos = 0; + if (!DM_STRLEN(dhcp_client_key)) + break; - // Added the enabled options for sendopts - uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, option_s) { - char *enable = NULL; + // Added the enabled options for sendopts + create_dhcp_sent_option_list(interface_s, dhcp_client_key); - - dmuci_get_value_by_section_string(option_s, "enable", &enable); - if (DM_LSTRCMP(enable, "1") == 0) { - char *opt_tag = NULL; - char *opt_value = NULL; - - dmuci_get_value_by_section_string(option_s, "option_tag", &opt_tag); - dmuci_get_value_by_section_string(option_s, "option_value", &opt_value); - pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s:%s ", opt_tag, opt_value); - } - } - - if (pos) { - buf[pos - 1] = 0; - dmuci_set_value_by_section(interface_s, "sendopts", buf); - } - - // Added the enabled options for reqopts - pos = 0; - uci_path_foreach_option_eq(bbfdm, "dmmap_dhcp_client", "req_option", "dhcp_client_key", dhcp_client_key, option_s) { - char *enable = NULL; - - dmuci_get_value_by_section_string(option_s, "enable", &enable); - if (DM_LSTRCMP(enable, "1") == 0) { - char *opt_tag = NULL; - - dmuci_get_value_by_section_string(option_s, "option_tag", &opt_tag); - pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s ", opt_tag); - } - } - - if (pos) { - buf[pos - 1] = 0; - dmuci_set_value_by_section(interface_s, "reqopts", buf); - } - } + // Added the enabled options for reqopts + create_dhcp_req_option_list(interface_s, dhcp_client_key); } break; } @@ -2480,23 +2560,25 @@ static int set_DHCPv4ClientSentOption_Enable(char *refparam, struct dmctx *ctx, option_name = get_dhcp_option_name(DM_STRTOL(dhcp_client_s->option_tag)); if (DM_LSTRCMP(option_name, "sendopts") == 0) { - char tag_value[128] = {0}; char *sendopts = NULL; - snprintf(tag_value, sizeof(tag_value), "%s:%s", dhcp_client_s->option_tag, dhcp_client_s->value); dmuci_get_value_by_section_string(dhcp_client_s->client_sect, "sendopts", &sendopts); if (b) { - if (!value_exits_in_str_list(sendopts, " ", tag_value)) { - add_elt_to_str_list(&sendopts, tag_value); - dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); - } + char tag_value[128] = {0}; + + snprintf(tag_value, sizeof(tag_value), "%s:%s", dhcp_client_s->option_tag, dhcp_client_s->value); + sendopts = add_str_to_str_list(sendopts, " ", tag_value); } else { - remove_elt_from_str_list(&sendopts, tag_value); - dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); + sendopts = remove_option_from_str_list(sendopts, DM_STRTOL(dhcp_client_s->option_tag)); } + + dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); } else { - dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, b ? dhcp_client_s->value : ""); + char str[256] = {0}; + + convert_hex_to_string(dhcp_client_s->value, str, sizeof(str)); + dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, b ? str : ""); } } @@ -2518,15 +2600,13 @@ static int set_DHCPv4ClientSentOption_Alias(char *refparam, struct dmctx *ctx, v static int get_DHCPv4ClientSentOption_Tag(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - *value = dmstrdup(((struct dhcp_client_option_args *)data)->option_tag); + *value = ((struct dhcp_client_option_args *)data)->option_tag; return 0; } static int set_DHCPv4ClientSentOption_Tag(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { struct dhcp_client_option_args *dhcp_client_s = (struct dhcp_client_option_args *)data; - char *new_option_name = NULL; - char *old_option_name = NULL; char *dhcp_client_key = NULL; switch (action) { @@ -2534,70 +2614,46 @@ static int set_DHCPv4ClientSentOption_Tag(char *refparam, struct dmctx *ctx, voi if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","254"}}, 1)) return FAULT_9007; - if (dhcp_client_s->option_tag && DM_STRCMP(dhcp_client_s->option_tag, value) == 0) + if (DM_STRCMP(dhcp_client_s->option_tag, value) == 0) break; dmuci_get_value_by_section_string(dhcp_client_s->dmmap_sect, "dhcp_client_key", &dhcp_client_key); - new_option_name = get_dhcp_option_name(DM_STRTOL(value)); - if (DM_LSTRCMP(new_option_name ,"sendopts") == 0) { - if (tag_option_exists("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", value)) - return FAULT_9007; - } else { - if (dhcp_client_s->client_sect) { - char *option_value = NULL; - - dmuci_get_value_by_section_string(dhcp_client_s->client_sect, new_option_name, &option_value); - if (option_value && *option_value) - return FAULT_9007; - } - } + if (tag_option_exists("dmmap_dhcp_client", "send_option", "dhcp_client_key", dhcp_client_key, "option_tag", value)) + return FAULT_9007; break; case VALUESET: if (dhcp_client_s->client_sect) { - old_option_name = get_dhcp_option_name(DM_STRTOL(dhcp_client_s->option_tag)); - new_option_name = get_dhcp_option_name(DM_STRTOL(value)); + char *enable = NULL; - if (DM_LSTRCMP(old_option_name, "sendopts") == 0) { - char old_tag_value[128] = {0}; + dmuci_get_value_by_section_string(dhcp_client_s->dmmap_sect, "enable", &enable); + + if (DM_STRCMP(enable, "1") == 0) { + char *option_name = NULL; char *sendopts = NULL; + char str[256] = {0}; dmuci_get_value_by_section_string(dhcp_client_s->client_sect, "sendopts", &sendopts); - snprintf(old_tag_value, sizeof(old_tag_value), "%s:%s", dhcp_client_s->option_tag, dhcp_client_s->value); - if (value_exits_in_str_list(sendopts, " ", old_tag_value)) { - remove_elt_from_str_list(&sendopts, old_tag_value); + // Remove the old option + option_name = get_dhcp_option_name(DM_STRTOL(dhcp_client_s->option_tag)); + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + sendopts = remove_option_from_str_list(sendopts, DM_STRTOL(dhcp_client_s->option_tag)); dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); - - if (DM_LSTRCMP(new_option_name, "sendopts") == 0) { - char new_tag_value[128] = {0}; - - snprintf(new_tag_value, sizeof(new_tag_value), "%s:%s", value, dhcp_client_s->value); - add_elt_to_str_list(&sendopts, new_tag_value); - dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); - } else { - dmuci_set_value_by_section(dhcp_client_s->client_sect, new_option_name, dhcp_client_s->value); - } + } else { + dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, ""); } - } else { - char *option_value = NULL; - dmuci_get_value_by_section_string(dhcp_client_s->client_sect, old_option_name, &option_value); - if (option_value && *option_value) { - dmuci_set_value_by_section(dhcp_client_s->client_sect, old_option_name, ""); - - if (DM_LSTRCMP(new_option_name, "sendopts") == 0) { - char new_tag_value[128] = {0}; - char *sendopts = NULL; - - snprintf(new_tag_value, sizeof(new_tag_value), "%s:%s", value, dhcp_client_s->value); - dmuci_get_value_by_section_string(dhcp_client_s->client_sect, "sendopts", &sendopts); - add_elt_to_str_list(&sendopts, new_tag_value); - dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); - } else { - dmuci_set_value_by_section(dhcp_client_s->client_sect, new_option_name, dhcp_client_s->value); - } + // Add the new option + option_name = get_dhcp_option_name(DM_STRTOL(value)); + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + snprintf(str, sizeof(str), "%s:%s", value, dhcp_client_s->value); + sendopts = add_str_to_str_list(sendopts, " ", str); + dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); + } else { + convert_hex_to_string(dhcp_client_s->value, str, sizeof(str)); + dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, str); } } } @@ -2610,22 +2666,13 @@ static int set_DHCPv4ClientSentOption_Tag(char *refparam, struct dmctx *ctx, voi static int get_DHCPv4ClientSentOption_Value(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - const char *tag_option = ((struct dhcp_client_option_args *)data)->option_tag; - const char *tag_value = ((struct dhcp_client_option_args *)data)->value; - char hex[256] = {0}; - - if (DM_STRLEN(tag_option) && DM_STRLEN(tag_value)) - convert_str_option_to_hex(DM_STRTOL(tag_option), tag_value, hex, sizeof(hex)); - - *value = (*hex) ? dmstrdup(hex) : ""; + *value = ((struct dhcp_client_option_args *)data)->value; return 0; } static int set_DHCPv4ClientSentOption_Value(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { struct dhcp_client_option_args *dhcp_client_s = (struct dhcp_client_option_args *)data; - char *option_name = NULL; - char res[256] = {0}; switch (action) { case VALUECHECK: @@ -2633,35 +2680,40 @@ static int set_DHCPv4ClientSentOption_Value(char *refparam, struct dmctx *ctx, v return FAULT_9007; break; case VALUESET: - convert_hex_option_to_string(DM_STRTOL(dhcp_client_s->option_tag), value, res, sizeof(res)); if (dhcp_client_s->client_sect) { - option_name = get_dhcp_option_name(DM_STRTOL(dhcp_client_s->option_tag)); + char *enable = NULL; - if (DM_LSTRCMP(option_name, "sendopts") == 0) { - char old_tag_value[128] = {0}; + dmuci_get_value_by_section_string(dhcp_client_s->dmmap_sect, "enable", &enable); + + if (DM_STRCMP(enable, "1") == 0) { + char *option_name = NULL; char *sendopts = NULL; + char str[256] = {0}; dmuci_get_value_by_section_string(dhcp_client_s->client_sect, "sendopts", &sendopts); - snprintf(old_tag_value, sizeof(old_tag_value), "%s:%s", dhcp_client_s->option_tag, dhcp_client_s->value); + option_name = get_dhcp_option_name(DM_STRTOL(dhcp_client_s->option_tag)); - if (value_exits_in_str_list(sendopts, " ", old_tag_value)) { - char new_tag_value[512] = {0}; - - snprintf(new_tag_value, sizeof(new_tag_value), "%s:%s", dhcp_client_s->option_tag, res); - - remove_elt_from_str_list(&sendopts, old_tag_value); - add_elt_to_str_list(&sendopts, new_tag_value); + // Remove the old option + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + sendopts = remove_option_from_str_list(sendopts, DM_STRTOL(dhcp_client_s->option_tag)); dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); + } else { + dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, ""); } - } else { - char *option_value = NULL; - dmuci_get_value_by_section_string(dhcp_client_s->client_sect, option_name, &option_value); - dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, (option_value && *option_value) ? res : ""); + // Add the new option + if (DM_LSTRCMP(option_name, "sendopts") == 0) { + snprintf(str, sizeof(str), "%s:%s", dhcp_client_s->option_tag, value); + sendopts = add_str_to_str_list(sendopts, " ", str); + dmuci_set_value_by_section(dhcp_client_s->client_sect, "sendopts", sendopts); + } else { + convert_hex_to_string(value, str, sizeof(str)); + dmuci_set_value_by_section(dhcp_client_s->client_sect, option_name, str); + } } } - dmuci_set_value_by_section_bbfdm(dhcp_client_s->dmmap_sect, "option_value", res); + dmuci_set_value_by_section_bbfdm(dhcp_client_s->dmmap_sect, "option_value", value); break; } return 0; @@ -2690,11 +2742,11 @@ static int set_DHCPv4ClientReqOption_Enable(char *refparam, struct dmctx *ctx, v dmuci_get_value_by_section_string(dhcp_client_s->client_sect, "reqopts", &reqopts); if (b) { if (!value_exits_in_str_list(reqopts, " ", dhcp_client_s->option_tag)) { - add_elt_to_str_list(&reqopts, dhcp_client_s->option_tag); + reqopts = add_str_to_str_list(reqopts, " ", dhcp_client_s->option_tag); dmuci_set_value_by_section(dhcp_client_s->client_sect, "reqopts", reqopts); } } else { - remove_elt_from_str_list(&reqopts, dhcp_client_s->option_tag); + reqopts = remove_str_from_str_list(reqopts, " ", dhcp_client_s->option_tag); dmuci_set_value_by_section(dhcp_client_s->client_sect, "reqopts", reqopts); } } @@ -2717,7 +2769,7 @@ static int set_DHCPv4ClientReqOption_Alias(char *refparam, struct dmctx *ctx, vo static int get_DHCPv4ClientReqOption_Tag(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - *value = dmstrdup(((struct dhcp_client_option_args *)data)->option_tag); + *value = ((struct dhcp_client_option_args *)data)->option_tag; return 0; } @@ -2725,14 +2777,13 @@ static int set_DHCPv4ClientReqOption_Tag(char *refparam, struct dmctx *ctx, void { struct dhcp_client_option_args *dhcp_client_s = (struct dhcp_client_option_args *)data; char *dhcp_client_key = NULL; - char *reqopts = NULL; switch (action) { case VALUECHECK: if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","254"}}, 1)) return FAULT_9007; - if (dhcp_client_s->option_tag && DM_STRCMP(dhcp_client_s->option_tag, value) == 0) + if (DM_STRCMP(dhcp_client_s->option_tag, value) == 0) break; dmuci_get_value_by_section_string(dhcp_client_s->dmmap_sect, "dhcp_client_key", &dhcp_client_key); @@ -2744,16 +2795,17 @@ static int set_DHCPv4ClientReqOption_Tag(char *refparam, struct dmctx *ctx, void case VALUESET: if (dhcp_client_s->client_sect) { bool tag_enabled = false; + char *reqopts = NULL; dmuci_get_value_by_section_string(((struct dhcp_client_option_args *)data)->client_sect, "reqopts", &reqopts); if (value_exits_in_str_list(reqopts, " ", dhcp_client_s->option_tag)) { - remove_elt_from_str_list(&reqopts, dhcp_client_s->option_tag); + reqopts = remove_str_from_str_list(reqopts, " ", dhcp_client_s->option_tag); tag_enabled = true; } if (tag_enabled) { - add_elt_to_str_list(&reqopts, value); + reqopts = add_str_to_str_list(reqopts, " ", value); dmuci_set_value_by_section(dhcp_client_s->client_sect, "reqopts", reqopts); } } diff --git a/test/cmocka/functional_api_test_bbfd.c b/test/cmocka/functional_api_test_bbfd.c index 37adefc5..8568060e 100644 --- a/test/cmocka/functional_api_test_bbfd.c +++ b/test/cmocka/functional_api_test_bbfd.c @@ -73,7 +73,7 @@ static void test_bbf_api_uci(void **state) // dmuci_get_option_value_string: test correct config/section/option uci_res = dmuci_get_option_value_string("network", "wan", "vendorid", &value); assert_int_equal(uci_res, 0); - assert_string_equal(value, "eg400"); + assert_string_equal(value, "dslforum.org"); // dmuci_get_option_value_string: test correct config/section/option uci_res = dmuci_get_option_value_string("dropbear", "@dropbear[0]", "Port", &value); diff --git a/test/files/etc/config/network b/test/files/etc/config/network index 70bc3d55..f44868a2 100644 --- a/test/files/etc/config/network +++ b/test/files/etc/config/network @@ -28,10 +28,11 @@ config interface 'lan' config interface 'wan' option proto 'dhcp' option hostname 'iopsysWrt-44D43771B810' - option vendorid 'eg400' + option vendorid 'dslforum.org' + option clientid '44:D4:37:71:B8:10' option device 'eth0' - option reqopts '12 43' - option sendopts '60:iopsystest 61:iopsys' + option reqopts '12 43 55' + option sendopts '0x38:6661696c20746f20636f6e6e656374 125:00:00:0D:E9:1C:01:06:34:34:44:34:33:37:02:0B:59:30:37:32:31:31:34:30:30:38:36:03:05:45:41:47:4C:45 lease:3600' option macaddr '44:D4:37:71:B8:12' config interface 'wan6' @@ -145,3 +146,4 @@ config device 'dev_eth0' option ifname 'eth0' option name 'eth0' option macaddr '44:D4:37:71:B8:12' +