T#8504: DHCPv4 options value is not implemented as standard

This commit is contained in:
Amin Ben Ramdhane 2022-08-16 10:41:11 +00:00
parent 2ea3d2b52e
commit 87ad6c5f22
4 changed files with 185 additions and 21 deletions

View file

@ -891,8 +891,7 @@ static int browseDHCPv4ServerPoolOptionInst(struct dmctx *dmctx, DMNODE *parent_
struct dhcp_args *curr_dhcp_args = (struct dhcp_args *)prev_data;
struct uci_list *dhcp_options_list = NULL;
struct uci_section *dmmap_sect = NULL;
char **dhcpv4_option = NULL, *inst = NULL, *dhcpv4_tag, *dhcpv4_value;
size_t length = 0;
char *inst = NULL, *dhcpv4_tag, *dhcpv4_value;
struct dhcp_client_option_args dhcp_client_opt_args = {0};
dmuci_get_value_by_section_list(curr_dhcp_args->sections->config_section, "dhcp_option", &dhcp_options_list);
@ -901,16 +900,18 @@ static int browseDHCPv4ServerPoolOptionInst(struct dmctx *dmctx, DMNODE *parent_
struct uci_element *e = NULL;
uci_foreach_element(dhcp_options_list, e) {
char buf[512] = {0};
dhcpv4_option = strsplit(e->name, ",", &length);
if (!dhcpv4_option)
continue;
snprintf(buf, sizeof(buf), "%s", e->name);
char *p = strchr(buf, ',');
if (p)
*p = 0;
if ((dmmap_sect = get_dup_section_in_dmmap_eq("dmmap_dhcp", "servpool_option", section_name(curr_dhcp_args->sections->config_section), "option_tag", dhcpv4_option[0])) == NULL) {
if ((dmmap_sect = get_dup_section_in_dmmap_eq("dmmap_dhcp", "servpool_option", section_name(curr_dhcp_args->sections->config_section), "option_tag", buf)) == NULL) {
dmuci_add_section_bbfdm("dmmap_dhcp", "servpool_option", &dmmap_sect);
dmuci_set_value_by_section_bbfdm(dmmap_sect, "option_tag", dhcpv4_option[0]);
dmuci_set_value_by_section_bbfdm(dmmap_sect, "option_tag", buf);
dmuci_set_value_by_section_bbfdm(dmmap_sect, "section_name", section_name(curr_dhcp_args->sections->config_section));
dmuci_set_value_by_section_bbfdm(dmmap_sect, "option_value", length > 1 ? dhcpv4_option[1] : "");
dmuci_set_value_by_section_bbfdm(dmmap_sect, "option_value", p ? p + 1 : "");
}
}
}
@ -2090,11 +2091,12 @@ static int get_DHCPv4ServerPoolClientOption_Tag(char *refparam, struct dmctx *ct
static int get_DHCPv4ServerPoolClientOption_Value(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
const char *tag_option = ((struct client_options_args *)data)->tag;
const char *tag_value = ((struct client_options_args *)data)->value;
char hex[256] = {0};
if (tag_value && *tag_value)
convert_string_to_hex(tag_value, hex, sizeof(hex));
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) : "";
return 0;
@ -2653,11 +2655,12 @@ 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 (tag_value && *tag_value)
convert_string_to_hex(tag_value, hex, sizeof(hex));
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) : "";
return 0;
@ -2675,7 +2678,7 @@ static int set_DHCPv4ClientSentOption_Value(char *refparam, struct dmctx *ctx, v
return FAULT_9007;
break;
case VALUESET:
convert_hex_to_string(value, res, sizeof(res));
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));
@ -2988,11 +2991,12 @@ static int set_DHCPv4ServerPoolOption_Tag(char *refparam, struct dmctx *ctx, voi
static int get_DHCPv4ServerPoolOption_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 (tag_value && *tag_value)
convert_string_to_hex(tag_value, hex, sizeof(hex));
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) : "";
return 0;
@ -3026,7 +3030,7 @@ static int set_DHCPv4ServerPoolOption_Value(char *refparam, struct dmctx *ctx, v
}
}
convert_hex_to_string(value, res, sizeof(res));
convert_hex_option_to_string(DM_STRTOL(dhcp_client_s->option_tag), value, res, sizeof(res));
if (option_enabled) {
char new_tag_value[512] = {0}, old_tag_value[128] = {0};
@ -3296,8 +3300,8 @@ static int get_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *c
dmuci_get_value_by_section_string(user_class_s, "userclass", &ucid);
if (ucid && *ucid)
convert_string_to_hex(ucid, hex, sizeof(hex));
if (DM_STRLEN(ucid))
convert_str_option_to_hex(77, ucid, hex, sizeof(hex));
*value = (*hex) ? dmstrdup(hex) : "";
}
@ -3326,7 +3330,7 @@ static int set_DHCPv4RelayForwarding_UserClassID(char *refparam, struct dmctx *c
if (user_class_s) {
char res[256] = {0};
convert_hex_to_string(value, res, sizeof(res));
convert_hex_option_to_string(77, value, res, sizeof(res));
dmuci_set_value_by_section(user_class_s, "userclass", res);
}
}

View file

@ -66,6 +66,77 @@ 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},
{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},
{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}
};
pid_t get_pid(const char *pname)
{
DIR* dir;
@ -1110,6 +1181,82 @@ void convert_hex_to_string(const char *hex, char *str, size_t size)
str[pos] = '\0';
}
void convert_str_option_to_hex(unsigned int tag, const char *str, char *hex, size_t size)
{
int idx = -1;
for (int i = 0; i < ARRAY_SIZE(TYPE_TAG_ARRAY); i++) {
if (TYPE_TAG_ARRAY[i].tag == tag) {
idx = i;
break;
}
}
if (idx > 0) {
char *pch = NULL, *spch = NULL;
unsigned pos = 0;
char buf[512] = {0};
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) {
struct in_addr ip_bin;
if (!inet_aton(pch, &ip_bin))
continue;
unsigned int ip = ntohl(ip_bin.s_addr);
pos += snprintf(&hex[pos], size - pos, "%08X", ip);
} else {
long int val = DM_STRTOL(pch);
pos += snprintf(&hex[pos], size - pos, (TYPE_TAG_ARRAY[idx].len == 4) ? "%08lX" : (TYPE_TAG_ARRAY[idx].len == 2) ? "%04lX" : "%02lX", val);
}
}
} else {
convert_string_to_hex(str, hex, size);
}
}
void convert_hex_option_to_string(unsigned int tag, const char *hex, char *str, size_t size)
{
int idx = -1;
for (int i = 0; i < ARRAY_SIZE(TYPE_TAG_ARRAY); i++) {
if (TYPE_TAG_ARRAY[i].tag == tag) {
idx = i;
break;
}
}
if (idx > 0) {
unsigned pos = 0;
unsigned int str_len = DM_STRLEN(hex);
unsigned int len = TYPE_TAG_ARRAY[idx].len * 2;
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) {
struct in_addr addr;
unsigned int ip;
sscanf(buf, "%X", &ip);
addr.s_addr = htonl(ip);
char *ipaddr = inet_ntoa(addr);
pos += snprintf(&str[pos], size - pos, "%s,", ipaddr);
} else {
int a = (int)strtol(buf, NULL, 16);
pos += snprintf(&str[pos], size - pos, "%d,", a);
}
}
if (pos)
str[pos - 1] = 0;
} else {
convert_hex_to_string(hex, str, size);
}
}
bool match(const char *string, const char *pattern)
{
regex_t re;

View file

@ -164,6 +164,11 @@ enum fs_size_type_enum {
FS_SIZE_USED,
};
enum option_type_enum {
OPTION_IP,
OPTION_INT
};
#define IPPING_PATH "/usr/share/bbfdm/ipping_launch"
#define IPPING_STOP dmcmd("/bin/sh", 2, IPPING_PATH, "stop");
#define DOWNLOAD_DIAGNOSTIC_PATH "/usr/share/bbfdm/download_launch"
@ -204,6 +209,12 @@ struct browse_args {
char *value;
};
struct option_tag_type {
int tag;
int type;
int len;
};
pid_t get_pid(const char *pname);
int check_file(char *path);
char *cidr2netmask(int bits);
@ -263,6 +274,8 @@ int dm_time_utc_format(time_t ts, char **dst);
int dm_time_format(time_t ts, char **dst);
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);
bool match(const char *string, const char *pattern);
int dm_validate_string(char *value, int min_length, int max_length, char *enumeration[], char *pattern[]);
int dm_validate_boolean(char *value);

View file

@ -41,8 +41,8 @@ config dhcp 'lan'
list ra_flags 'managed-config'
list ra_flags 'other-config'
list dhcp_option '26,1470'
list dhcp_option '3,192.168.1.254'
list dhcp_option '6,iopsys.eu'
list dhcp_option '3,192.168.1.30,192.168.1.254'
list dhcp_option '6,192.168.1.1'
config dhcp 'wan'
option interface 'wan'