From b82fd5d10153d1159edb41a9dfd1d52413b49445 Mon Sep 17 00:00:00 2001 From: Amin Ben Ramdhane Date: Mon, 29 Oct 2018 00:34:10 +0100 Subject: [PATCH] Ticket refs #16134: TR181: PPP object permission doesn't conform with standard --- dm/dmtree/tr181/nat.c | 225 ++++++++++++++++++++++++++---------------- dm/dmtree/tr181/nat.h | 5 + 2 files changed, 143 insertions(+), 87 deletions(-) diff --git a/dm/dmtree/tr181/nat.c b/dm/dmtree/tr181/nat.c index df7dbce..11280cf 100644 --- a/dm/dmtree/tr181/nat.c +++ b/dm/dmtree/tr181/nat.c @@ -4,8 +4,9 @@ * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * - * Copyright (C) 2016 Inteno Broadband Technology AB + * Copyright (C) 2018 Inteno Broadband Technology AB * Author: Anis Ellouze + * Author: Amin Ben Ramdhane * */ @@ -20,31 +21,118 @@ /*** NAT. ***/ DMOBJ tnatObj[] = { -/* OBJ, permission, addobj, delobj, browseinstobj, finform, notification, nextobj, leaf*/ -{"InterfaceSetting", &DMREAD, NULL, NULL, NULL, browseInterfaceSettingInst, NULL, NULL, NULL, tInterfaceSettingParam, NULL}, +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, finform, notification, nextobj, leaf*/ +{"InterfaceSetting", &DMWRITE, add_NAT_InterfaceSetting, delete_NAT_InterfaceSetting, NULL, browseInterfaceSettingInst, NULL, NULL, NULL, tInterfaceSettingParam, NULL}, {0} }; /*** NAT.InterfaceSetting. ***/ DMLEAF tInterfaceSettingParam[] = { -{"Enable", &DMREAD, DMT_BOOL, get_nat_enable, NULL, NULL, NULL}, +{"Enable", &DMWRITE, DMT_BOOL, get_nat_enable, set_nat_enable, NULL, NULL}, {"Alias", &DMWRITE, DMT_STRING, get_nat_alias, set_nat_alias, NULL, NULL}, -{"Interface", &DMREAD, DMT_STRING, get_nat_interface, NULL, NULL, NULL}, +{"Interface", &DMWRITE, DMT_STRING, get_nat_interface, set_nat_interface, NULL, NULL}, {0} }; - -int get_nat_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +/************************************************************* + * ADD DEL OBJ +/*************************************************************/ +int add_NAT_InterfaceSetting(char *refparam, struct dmctx *ctx, void *data, char **instance) { - *value = "1"; + char *value, *v; + char name[8]; + char *inst; + struct uci_section *s = NULL; + struct uci_section *dmmap_firewall=NULL; + + check_create_dmmap_package("dmmap_firewall"); + inst = get_last_instance_icwmpd("dmmap_firewall", "zone", "natinstance"); + sprintf(name, "NAT_%d", inst ? (atoi(inst)+1) : 1); + dmuci_add_section("firewall", "zone", &s, &value); + dmuci_set_value_by_section(s, "input", "REJECT"); + dmuci_set_value_by_section(s, "output", "ACCEPT"); + dmuci_set_value_by_section(s, "forward", "REJECT"); + dmuci_set_value_by_section(s, "name", name); + + dmuci_add_section_icwmpd("dmmap_firewall", "zone", &dmmap_firewall, &v); + dmuci_set_value_by_section(dmmap_firewall, "section_name", section_name(s)); + *instance = update_instance_icwmpd(dmmap_firewall, inst, "natinstance"); + return 0; + +} + +int delete_NAT_InterfaceSetting(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + int found = 0; + char *lan_name; + struct uci_section *s = NULL; + struct uci_section *ss = NULL, *dmmap_firewall= NULL; + + switch (del_action) { + case DEL_INST: + get_dmmap_section_of_config_section("dmmap_firewall", "zone", section_name((struct uci_section *)data), &dmmap_firewall); + if(dmmap_firewall != NULL) + dmuci_delete_by_section(dmmap_firewall, NULL, NULL); + dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); + break; + case DEL_ALL: + uci_foreach_sections("firewall", "zone", s) { + if (found != 0){ + get_dmmap_section_of_config_section("dmmap_firewall", "zone", section_name(ss), &dmmap_firewall); + if(dmmap_firewall != NULL) + dmuci_delete_by_section(dmmap_firewall, NULL, NULL); + dmuci_delete_by_section(ss, NULL, NULL); + } + ss = s; + found++; + } + if (ss != NULL){ + get_dmmap_section_of_config_section("dmmap_firewall", "zone", section_name(ss), &dmmap_firewall); + if(dmmap_firewall != NULL) + dmuci_delete_by_section(dmmap_firewall, NULL, NULL); + dmuci_delete_by_section(ss, NULL, NULL); + } + return 0; + } return 0; } +/************************************************************************** +* SET & GET VALUE +***************************************************************************/ +int get_nat_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *val; + dmuci_get_value_by_section_string((struct uci_section *)data, "masq", &val); + *value = (*val == '1') ? "1" : "0"; + return 0; +} + +int set_nat_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + bool b; + switch (action) { + case VALUECHECK: + if (string_to_bool(value, &b)) + return FAULT_9007; + return 0; + case VALUESET: + string_to_bool(value, &b); + if (b) + dmuci_set_value_by_section((struct uci_section *)data, "masq", "1"); + else + dmuci_set_value_by_section((struct uci_section *)data, "masq", "0"); + return 0; + } + return 0; +} + + int get_nat_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *dmmap_section; - get_dmmap_section_of_config_section("dmmap_network", "interface", section_name((struct uci_section *)data), &dmmap_section); + get_dmmap_section_of_config_section("dmmap_firewall", "zone", section_name((struct uci_section *)data), &dmmap_section); dmuci_get_value_by_section_string(dmmap_section, "natalias", value); return 0; } @@ -53,7 +141,7 @@ int set_nat_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, { struct uci_section *dmmap_section; - get_dmmap_section_of_config_section("dmmap_network", "interface", section_name((struct uci_section *)data), &dmmap_section); + get_dmmap_section_of_config_section("dmmap_firewall", "zone", section_name((struct uci_section *)data), &dmmap_section); switch (action) { case VALUECHECK: return 0; @@ -66,102 +154,65 @@ int set_nat_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, int get_nat_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *linker; - linker = dmstrdup(section_name(((struct uci_section *)data))); - adm_entry_get_linker_param(ctx, dm_print_path("%s%cIP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value); // MEM WILL BE FREED IN DMMEMCLEAN - if (*value == NULL) - *value = ""; - dmfree(linker); + struct uci_list *v; + struct uci_element *e; + char *ifaceobj, buf[256] = ""; + + *value = ""; + dmuci_get_value_by_section_list((struct uci_section *)data, "network", &v); + if (v == NULL) + return 0; + uci_foreach_element(v, e) { + adm_entry_get_linker_param(ctx, dm_print_path("%s%cIP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), e->name, &ifaceobj); // MEM WILL BE FREED IN DMMEMCLEAN + if (*ifaceobj == '\0') + continue; + if (*buf != '\0') + strcat(buf, ","); + strcat(buf, ifaceobj); + } + *value = dmstrdup(buf); return 0; } -int get_nat_last_inst() +int set_nat_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - char *rinst = "0", *tmp; - int max; - struct uci_section *s; - int cnt = 0; - - uci_foreach_sections("dmmap_network", "interface", s) { - dmuci_get_value_by_section_string(s, "natinstance", &tmp); - if (tmp[0] == '\0') - continue; - else if (atoi(rinst) < atoi(tmp)) - { - rinst = tmp; - } + char *iface, *pch, *pchr, buf[256] = ""; + + switch (action) { + case VALUECHECK: + return 0; + case VALUESET: + strcpy(buf, value); + dmuci_set_value_by_section((struct uci_section *)data, "network", ""); + for(pch = strtok_r(buf, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) { + adm_entry_get_linker_value(ctx, pch, &iface); + if (iface) { + dmuci_add_list_value_by_section((struct uci_section *)data, "network", iface); + free(iface); + } + } + return 0; } - max = atoi(rinst); - return max; + return 0; } -char *nat_update_instance_alias(int action, char **last_inst, void *argv[]) -{ - char *instance, *alias; - char buf[8] = {0}; - - struct uci_section *s = (struct uci_section *) argv[0]; - char *inst_opt = (char *) argv[1]; - char *alias_opt = (char *) argv[2]; - bool *find_max = (bool *) argv[3]; - - dmuci_get_value_by_section_string(s, inst_opt, &instance); - if (instance[0] == '\0') { - if (*find_max) { - int m = get_nat_last_inst(); - sprintf(buf, "%d", m+1); - *find_max = false; - } - else if (last_inst == NULL) { - sprintf(buf, "%d", 1); - } - else { - sprintf(buf, "%d", atoi(*last_inst)+1); - } - instance= DMUCI_SET_VALUE_BY_SECTION(icwmpd, s, inst_opt, buf); - } - *last_inst = instance; - if (action == INSTANCE_MODE_ALIAS) { - dmuci_get_value_by_section_string(s, alias_opt, &alias); - if (alias[0] == '\0') { - sprintf(buf, "cpe-%s", instance); - alias = DMUCI_SET_VALUE_BY_SECTION(icwmpd, s, alias_opt, buf); - } - sprintf(buf, "[%s]", alias); - instance = dmstrdup(buf); - } - return instance; -} - - /************************************************************* * ENTRY METHOD /*************************************************************/ - int browseInterfaceSettingInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { - struct uci_section *net_sec = NULL, *s = NULL, *dmmap_sect; - char *nat = NULL, *instance= NULL; - char *nati, *nati_last = NULL, *v= NULL, *stmp= NULL; - int id = 0; + char *nati, *nati_last = NULL; bool find_max = true; struct dmmap_dup *p; LIST_HEAD(dup_list); - synchronize_specific_config_sections_with_dmmap("network", "interface", "dmmap_network", &dup_list); + synchronize_specific_config_sections_with_dmmap("firewall", "zone", "dmmap_firewall", &dup_list); list_for_each_entry(p, &dup_list, list) { - uci_foreach_list_cont("firewall", "zone", "network", section_name(p->config_section), s) { - dmuci_get_value_by_section_string(s, "masq", &nat); - if(nat[0] == '1') { - nati = handle_update_instance(1, dmctx, &nati_last, nat_update_instance_alias, 4, p->dmmap_section, "natinstance", "natalias", &find_max); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, nati) == DM_STOP) - goto end; - break; - } - } + nati = handle_update_instance(1, dmctx, &nati_last, update_instance_alias, 3, p->dmmap_section, "natinstance", "natalias"); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, nati) == DM_STOP) + return 0; } free_dmmap_config_dup_list(&dup_list); -end: return 0; } diff --git a/dm/dmtree/tr181/nat.h b/dm/dmtree/tr181/nat.h index 3b35d45..eb20f8c 100644 --- a/dm/dmtree/tr181/nat.h +++ b/dm/dmtree/tr181/nat.h @@ -16,10 +16,15 @@ extern DMOBJ tnatObj[]; int browseInterfaceSettingInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance); +int add_NAT_InterfaceSetting(char *refparam, struct dmctx *ctx, void *data, char **instance); +int delete_NAT_InterfaceSetting(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action); + int get_nat_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); int get_nat_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); int get_nat_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +int set_nat_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action); int set_nat_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action); +int set_nat_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action); #endif