DHCPv4: Fix the handling of dhcp options

This commit is contained in:
Amin Ben Romdhane 2023-10-12 14:51:15 +02:00
parent c6fabd07d1
commit 8c6aa34a1b
5 changed files with 458 additions and 359 deletions

View file

@ -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));

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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'