diff --git a/gitlab-ci/compile.sh b/gitlab-ci/compile.sh index 3a6962853ec1d9b0f7fbed73c821489e01b8c268..6b09f0ab8aa4da4fe1e5b259317534fa7864132a 100755 --- a/gitlab-ci/compile.sh +++ b/gitlab-ci/compile.sh @@ -16,3 +16,4 @@ cd $orig_dir/src/ pwd # just the existence of macro INCLUDE_PORT_TRIGGER is checked in code make CFLAGS='-DINCLUDE_PORT_TRIGGER=\"yes\"' +make CFLAGS='-DINCLUDE_BACKEND_FIREWALLMNGR=\"yes\"' diff --git a/src/Makefile b/src/Makefile index 2c38144e97a893a72a70ddfe600bae4e96f1666f..2b91e4d3901f831b7d79fa09cbc745ffcf03438f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,14 @@ LIB = libfirewallmngr.so # then include nat_porttrigger.o # else # do not include nat_porttrigger.o -ifneq (,$(filter -DINCLUDE_PORT_TRIGGER, $(CFLAGS))) +ifneq (,$(filter -DINCLUDE_BACKEND_FIREWALLMNGR, $(CFLAGS))) +PROG = firewallmngr +LIB_IPT = libporttrigger.so +OBJS = ./firewallmngr_backend_firewallmngr/firewallmngrd.o +LIB_OBJS = ./firewallmngr_backend_firewallmngr/bbf_plugin/firewall.o \ + ./firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.o \ + ./firewallmngr_backend_firewallmngr/bbf_plugin/nat_porttrigger.o +else ifneq (,$(filter -DINCLUDE_PORT_TRIGGER, $(CFLAGS))) LIB_OBJS = firewallmngr.o firewall.o nat.o nat_porttrigger.o else LIB_OBJS = firewallmngr.o firewall.o nat.o @@ -12,14 +19,30 @@ endif PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC LIB_LDFLAGS = $(LDFLAGS) +ifneq (,$(filter -DINCLUDE_BACKEND_FIREWALLMNGR, $(CFLAGS))) +LIB_LDFLAGS += -luci -lubus -lubox -ljson-c -lblobmsg_json +endif %.o: %.c $(CC) $(PROG_CFLAGS) -c -o $@ $< + +ifneq (,$(filter -DINCLUDE_BACKEND_FIREWALLMNGR, $(CFLAGS))) +all: $(PROG) $(LIB) + +$(PROG): $(OBJS) + $(CC) $(PROG_CFLAGS) -shared -o $@ $^ $(LIB_LDFLAGS) +$(LIB): $(LIB_OBJS) + $(CC) $(PROG_CFLAGS) -shared -o $@ $^ $(LDFLAGS) +else all: $(LIB) $(LIB): $(LIB_OBJS) $(CC) $(PROG_CFLAGS) -shared -o $@ $^ $(LIB_LDFLAGS) +endif clean: rm -f *.o $(LIB) +ifneq (,$(filter -DINCLUDE_BACKEND_FIREWALLMNGR, $(CFLAGS))) + rm -f *.o $(LIB_IPT) $(PROG) +endif diff --git a/src/firewallmngr_backend_firewallmngr/bbf_plugin/Makefile b/src/firewallmngr_backend_firewallmngr/bbf_plugin/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ea497d906ef818ca162dc1503ef4b3b9801dfadc --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/bbf_plugin/Makefile @@ -0,0 +1,22 @@ +LIB_FIREWALL := libfirewallmngr.so + +OBJS := firewall.o firewall_plugin.o nat_porttrigger.o + +LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fstrict-aliasing +LIB_LDFLAGS = $(LDFLAGS) +FPIC := -fPIC + +.PHONY: all + +%.o: %.c + $(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $< + +all: $(LIB_FIREWALL) + +$(LIB_FIREWALL): $(OBJS) + $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ + +clean: + rm -f *.o $(LIB_FIREWALL) +# rm -f *.o $(LIB_IPT) + diff --git a/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall.c b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall.c new file mode 100644 index 0000000000000000000000000000000000000000..8e5897fd539e0b04440f151dab3f27c98b6a2903 --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall.c @@ -0,0 +1,822 @@ +/* + * Copyright (C) 2023 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Husaam Mehdi <husaam.mehdi@iopsys.eu> + */ + +#include <libbbfdm-api/dmcommon.h> +#include <libbbfdm_api.h> + + +/************************************************************* +* UTILITY METHODS +**************************************************************/ + +static int browseFirewallChainRuleInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + struct dm_data *p = NULL; + LIST_HEAD(dup_list); + char *inst = NULL; + char *parent_chain = NULL; + + if (!(((struct dm_data *)prev_data)->config_section)) { + return 0; + } + + bbf_uci_get_value_by_section(((struct dm_data *)prev_data)->config_section, "name", &parent_chain); + + if (!parent_chain) { + return 0; + } + + synchronize_specific_config_sections_with_dmmap("firewallmngr", "rule", "dmmap_firewallmngr", &dup_list); + list_for_each_entry(p, &dup_list, list) { + char *current_chain = NULL; + + bbf_uci_get_value_by_section(p->config_section, "chain", ¤t_chain); + if (!current_chain) { + continue; + } + + if (DM_STRCMP(current_chain, parent_chain)) { + continue; + } + + inst = handle_instance(dmctx, parent_node, p->dmmap_section, "firewall_rule_instance", "firewall_rule_alias"); + + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) + break; + } + free_dmmap_config_dup_list(&dup_list); + + return 0; +} + + +/************************************************************* +* ADD & DEL OBJ +**************************************************************/ + +static int addObjFirewallChainRule(char *refparam, struct dmctx *ctx, void *data, char **instance) +{ + struct uci_section *s = NULL; + struct uci_section *dmmap_firewall_rule = NULL; + char creation_date[32] = {0}; + char rule_name[32] = {0}; + char *parent_chain = NULL; + time_t now = time(NULL); + + if (!((struct dm_data *)data)->config_section) + return 0; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "name", &parent_chain); + if (!parent_chain || !DM_STRLEN(parent_chain)) + return 0; + + snprintf(rule_name, sizeof(rule_name), "%s_rule_%s", section_name(((struct dm_data *)data)->config_section), *instance); + + // Add rule section + dmuci_add_section("firewallmngr", "rule", &s); + dmuci_rename_section_by_section(s, rule_name); + dmuci_set_value_by_section(s, "name", rule_name); + dmuci_set_value_by_section(s, "chain", parent_chain); + dmuci_set_value_by_section(s, "target", "0"); + dmuci_set_value_by_section(s, "enable", "0"); + dmuci_set_value_by_section(s, "proto", "0"); + + // Add rule section in dmmap_firewallmngr file + dmuci_add_section_bbfdm("dmmap_firewallmngr", "rule", &dmmap_firewall_rule); + dmuci_set_value_by_section(dmmap_firewall_rule, "section_name", rule_name); + dmuci_set_value_by_section(dmmap_firewall_rule, "firewall_rule_instance", *instance); + + strftime(creation_date, sizeof(creation_date), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); + dmuci_set_value_by_section(dmmap_firewall_rule, "creation_date", creation_date); + + return 0; +} + +static int delObjFirewallChainRule(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + switch (del_action) { + case DEL_INST: + char buf[32] = {0}; + char *rule_name = NULL; + char *rule_order = NULL; + + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "order", &rule_order); + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "name", &rule_name); + + + snprintf(buf, sizeof(buf), "%lu", DM_STRTOUL(rule_order) + 1); + + + // Remove section + dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL); + + // Remove section in dmmap file + dmuci_delete_by_section(((struct dm_data *)data)->dmmap_section, NULL, NULL); + + break; + case DEL_ALL: + //TODO + break; + } + return 0; +} + +/************************************************************* +* GET & SET PARAM +**************************************************************/ + +static int get_FirewallChain_RuleNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + int cnt = get_number_of_entries(ctx, data, instance, browseFirewallChainRuleInst); + dmasprintf(value, "%d", cnt); + return 0; +} + +static int get_FirewallChainRule_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0"); + return 0; +} + +static int set_FirewallChainRule_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_boolean(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + bool b = true; + string_to_bool(value, &b); + + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "enable", value); + break; + } + + return 0; +} + +static int get_FirewallChainRule_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "status", "Enabled"); + + return 0; +} + +static int get_FirewallChainRule_Order(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "order", ""); + return 0; +} + +static int set_FirewallChainRule_Order(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1",NULL}}, 1)) + return FAULT_9007; + + break; + case VALUESET: + + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "order", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + return bbf_get_alias(ctx, ((struct dm_data *)data)->dmmap_section, "firewall_rule_alias", instance, value); +} + +static int set_FirewallChainRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, "firewall_rule_alias", instance, value); +} + +static int get_FirewallChainRule_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "name", ""); + return 0; +} + +static int set_FirewallChainRule_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "name", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_Target(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *target_arr[] = {"Drop", "Accept", "Reject", "Return", "TargetChain", NULL}; + + char *target = NULL; + + target = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "target", "0"); + + if (target) { + int c = atoi(target); + + if (c >=0 && c < 5) + *value = target_arr[c]; + else + *value = "Drop";//TODO verify default behaviour + } + return 0; +} + +static int set_FirewallChainRule_Target(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *target_arr[] = {"Drop", "Accept", "Reject", "Return", "TargetChain", NULL}; + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, -1, target_arr, NULL)) + return FAULT_9007; + break; + case VALUESET: + int i = 0; + bool found = false; + + for (i = 0; i < 5; i++) { + if (!DM_STRCMP(value, target_arr[i])) { + found = true; + break; + } + } + + if (found) { + char str[2] = {0}; + snprintf(str, 2, "%d", i); + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "target", str); + } else { + // TODO correct default behaviour? + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "target", "DROP"); + } + + break; + } + return 0; +} + +static int get_FirewallChainRule_Log(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "log", "0"); + + return 0; +} + +static int set_FirewallChainRule_Log(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_boolean(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + bool b = false; + string_to_bool(value, &b); + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "log", b ? "1" : "0"); + break; + } + return 0; +} + +static int get_FirewallChainRule_CreationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "creation_date", "0001-01-01T00:00:00Z"); + return 0; +} + +static int get_FirewallChainRule_ExpiryDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *expiry_date = NULL; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "expiry", &expiry_date); + + if (expiry_date && DM_STRLEN(expiry_date) != 0 && DM_STRTOL(expiry_date) > 0) { + char expiry[sizeof "AAAA-MM-JJTHH:MM:SSZ"]; + time_t time_value = DM_STRTOL(expiry_date); + + strftime(expiry, sizeof expiry, "%Y-%m-%dT%H:%M:%SZ", gmtime(&time_value)); + *value = dmstrdup(expiry); + } else { + *value = "9999-12-31T23:59:59Z"; + } + + return 0; +} + +static int set_FirewallChainRule_ExpiryDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char expiry_date[16]; + struct tm tm; + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_dateTime(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + strptime(value, "%Y-%m-%dT%H:%M:%SZ", &tm); + snprintf(expiry_date, sizeof(expiry_date), "%lld", (long long)timegm(&tm)); + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "expiry", expiry_date); + break; + } + + return 0; +} + +static int get_FirewallChainRule_SourceInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *linker = NULL; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "src", &linker); + _bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", linker, value); + + return 0; +} + +static int set_FirewallChainRule_SourceInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *allowed_objects[] = {"Device.IP.Interface.", NULL}; + struct dm_reference reference = {0}; + + bbfdm_get_reference_linker(ctx, value, &reference); + + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL)) { + return FAULT_9007; + } + + + if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) + return FAULT_9007; + break; + case VALUESET: + if (DM_STRLEN(reference.value)) { + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src", reference.value); + } + + break; + } + return 0; +} + +static int get_FirewallChainRule_SourceAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_all_interfaces", "0"); + return 0; +} + +static int set_FirewallChainRule_SourceAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_boolean(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + bool b = false; + string_to_bool(value, &b); + + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_all_interfaces", b ? "1" : "0"); + break; + } + return 0; +} + +static int get_FirewallChainRule_DestInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *linker = NULL; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "dest", &linker); + _bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", linker, value); + + return 0; +} + +static int set_FirewallChainRule_DestInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *allowed_objects[] = {"Device.IP.Interface.", NULL}; + struct dm_reference reference = {0}; + + bbfdm_get_reference_linker(ctx, value, &reference); + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL)) { + return FAULT_9007; + } + + if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) + return FAULT_9007; + break; + case VALUESET: + if (DM_STRLEN(reference.value)) { + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest", reference.value); + } + break; + } + return 0; +} + +static int get_FirewallChainRule_DestAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_all_interfaces", "0"); + return 0; +} + +static int set_FirewallChainRule_DestAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_boolean(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + bool b = false; + string_to_bool(value, &b); + + + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_all_interfaces", b ? "1" : "0"); + break; + } + return 0; +} + +static int get_FirewallChainRule_IPVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *ipversion = NULL; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "family", &ipversion); + + if (!ipversion) { + *value = "-1"; + return 0; + } + + if (strcasecmp(ipversion, "ipv4") == 0) { + *value = "4"; + } else if (strcasecmp(ipversion, "ipv6") == 0) { + *value = "6"; + } else { + *value = "-1"; + } + + return 0; +} + +static int set_FirewallChainRule_IPVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","15"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + if (DM_LSTRCMP(value, "4") == 0) + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", "ipv4"); + else if (DM_LSTRCMP(value, "6") == 0) + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", "ipv6"); + else if (DM_LSTRCMP(value, "-1") == 0) + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", ""); + break; + } + return 0; +} + +static int get_FirewallChainRule_DestIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_ip", ""); + return 0; +} + +static int set_FirewallChainRule_DestIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 45, NULL, IPAddress)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_ip", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_DestMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_mask", ""); + + return 0; +} + +static int set_FirewallChainRule_DestMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 49, NULL, IPPrefix)) + return FAULT_9007; + break; + case VALUESET: + char *pch = NULL; + pch = DM_STRCHR(value, '/'); + if (pch == NULL) + return 0; + pch++; + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_mask", pch); + break; + } + return 0; +} + +static int get_FirewallChainRule_SourceIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "src_ip", ""); + + return 0; +} + +static int set_FirewallChainRule_SourceIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 45, NULL, IPAddress)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src_ip", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_SourceMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_mask", ""); + + return 0; +} + +static int set_FirewallChainRule_SourceMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 49, NULL, IPPrefix)) + return FAULT_9007; + break; + case VALUESET: + char *pch = NULL; + pch = DM_STRCHR(value, '/'); + if (pch == NULL) + return 0; + pch++; + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_mask", pch); + break; + } + return 0; +} + +static int get_FirewallChainRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *proto = NULL, buf[256], protocol[32], protocol_nbr[16]; + + bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "proto", &proto); + + if (!proto || DM_STRLEN(proto) == 0 || strchr(proto, ' ')) { + *value = "255"; + return 0; + } + + if (*proto == '0' || strcmp(proto, "all") == 0) { + *value = "-1"; + return 0; + } + + if (isdigit_str(proto)) { + *value = proto; + return 0; + } + + FILE *fp = fopen("/etc/protocols", "r"); + if (fp == NULL) + return 0; + + while (fgets (buf , 256 , fp) != NULL) { + sscanf(buf, "%31s %15s", protocol, protocol_nbr); + if (DM_STRCASECMP(protocol, proto) == 0) { + *value = dmstrdup(protocol_nbr); + fclose(fp); + return 0; + } + } + fclose(fp); + + return 0; +} + +static int set_FirewallChainRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","255"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "proto", (*value == '-') ? "0" : value); + break; + } + return 0; +} + +static int get_FirewallChainRule_DestPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_port", "-1"); + return 0; +} + +static int set_FirewallChainRule_DestPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_port", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_DestPortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_port_range_max", "-1"); + return 0; +} + +static int set_FirewallChainRule_DestPortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_port_range_max", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_SourcePort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_port", "-1"); + + return 0; +} + +static int set_FirewallChainRule_SourcePort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_port", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_SourcePortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_port_range_max", "-1"); + + return 0; +} + +static int set_FirewallChainRule_SourcePortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_port_range_max", value); + break; + } + return 0; +} + +static int get_FirewallChainRule_SourceMAC(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "src_mac", ""); + + return 0; +} + +static int set_FirewallChainRule_SourceMAC(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 17, NULL, MACAddress)) + return FAULT_9007; + break; + case VALUESET: + bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src_mac", value); + break; + } + return 0; +} + +/********************************************************************************************************************************** +* OBJ & PARAM DEFINITION +***********************************************************************************************************************************/ + +/* *** Device.Firewall.Chain.{i}.Rule.{i}. *** */ +DMLEAF tFirewallChainRuleParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */ +{"Enable", &DMWRITE, DMT_BOOL, get_FirewallChainRule_Enable, set_FirewallChainRule_Enable, BBFDM_BOTH}, +{"Status", &DMREAD, DMT_STRING, get_FirewallChainRule_Status, NULL, BBFDM_BOTH}, +{"Order", &DMWRITE, DMT_STRING, get_FirewallChainRule_Order, set_FirewallChainRule_Order, BBFDM_BOTH}, +{"Alias", &DMWRITE, DMT_STRING, get_FirewallChainRule_Alias, set_FirewallChainRule_Alias, BBFDM_BOTH}, +{"Description", &DMWRITE, DMT_STRING, get_FirewallChainRule_Description, set_FirewallChainRule_Description, BBFDM_BOTH}, +{"Target", &DMWRITE, DMT_STRING, get_FirewallChainRule_Target, set_FirewallChainRule_Target, BBFDM_BOTH}, +/*{"TargetChain", &DMWRITE, DMT_STRING, get_FirewallChainRule_TargetChain, set_FirewallChainRule_TargetChain, BBFDM_BOTH, DM_FLAG_REFERENCE},*/ +{"Log", &DMWRITE, DMT_BOOL, get_FirewallChainRule_Log, set_FirewallChainRule_Log, BBFDM_BOTH}, +{"CreationDate", &DMREAD, DMT_TIME, get_FirewallChainRule_CreationDate, NULL, BBFDM_BOTH}, +{"ExpiryDate", &DMWRITE, DMT_TIME, get_FirewallChainRule_ExpiryDate, set_FirewallChainRule_ExpiryDate, BBFDM_BOTH}, +{"SourceInterface", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceInterface, set_FirewallChainRule_SourceInterface, BBFDM_BOTH, DM_FLAG_REFERENCE}, +/*{"SourceInterfaceExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceInterfaceExclude, set_FirewallChainRule_SourceInterfaceExclude, BBFDM_BOTH},*/ +{"SourceAllInterfaces", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceAllInterfaces, set_FirewallChainRule_SourceAllInterfaces, BBFDM_BOTH}, +{"DestInterface", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestInterface, set_FirewallChainRule_DestInterface, BBFDM_BOTH, DM_FLAG_REFERENCE}, +/*{"DestInterfaceExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestInterfaceExclude, set_FirewallChainRule_DestInterfaceExclude, BBFDM_BOTH},*/ +{"DestAllInterfaces", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestAllInterfaces, set_FirewallChainRule_DestAllInterfaces, BBFDM_BOTH}, +{"IPVersion", &DMWRITE, DMT_INT, get_FirewallChainRule_IPVersion, set_FirewallChainRule_IPVersion, BBFDM_BOTH}, +{"DestIP", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestIP, set_FirewallChainRule_DestIP, BBFDM_BOTH}, +{"DestMask", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestMask, set_FirewallChainRule_DestMask, BBFDM_BOTH}, +/*{"DestIPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestIPExclude, set_FirewallChainRule_DestIPExclude, BBFDM_BOTH},*/ +{"SourceIP", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceIP, set_FirewallChainRule_SourceIP, BBFDM_BOTH}, +{"SourceMask", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceMask, set_FirewallChainRule_SourceMask, BBFDM_BOTH}, +/*{"SourceIPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceIPExclude, set_FirewallChainRule_SourceIPExclude, BBFDM_BOTH},*/ +{"Protocol", &DMWRITE, DMT_INT, get_FirewallChainRule_Protocol, set_FirewallChainRule_Protocol, BBFDM_BOTH}, +/*{"ProtocolExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_ProtocolExclude, set_FirewallChainRule_ProtocolExclude, BBFDM_BOTH},*/ +{"DestPort", &DMWRITE, DMT_INT, get_FirewallChainRule_DestPort, set_FirewallChainRule_DestPort, BBFDM_BOTH}, +{"DestPortRangeMax", &DMWRITE, DMT_INT, get_FirewallChainRule_DestPortRangeMax, set_FirewallChainRule_DestPortRangeMax, BBFDM_BOTH}, +/*{"DestPortExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestPortExclude, set_FirewallChainRule_DestPortExclude, BBFDM_BOTH},*/ +{"SourcePort", &DMWRITE, DMT_INT, get_FirewallChainRule_SourcePort, set_FirewallChainRule_SourcePort, BBFDM_BOTH}, +{"SourcePortRangeMax", &DMWRITE, DMT_INT, get_FirewallChainRule_SourcePortRangeMax, set_FirewallChainRule_SourcePortRangeMax, BBFDM_BOTH}, +/*{"SourcePortExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourcePortExclude, set_FirewallChainRule_SourcePortExclude, BBFDM_BOTH},*/ +/*{"DSCP", &DMWRITE, DMT_INT, get_FirewallChainRule_DSCP, set_FirewallChainRule_DSCP, BBFDM_BOTH},*/ +/*{"DSCPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DSCPExclude, set_FirewallChainRule_DSCPExclude, BBFDM_BOTH},*/ +/*{"ConnectionState", &DMWRITE, DMT_STRING, get_FirewallChainRule_ConnectionState, set_FirewallChainRule_ConnectionState, BBFDM_BOTH},*/ +{"SourceMAC", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceMAC, set_FirewallChainRule_SourceMAC, BBFDM_BOTH}, +/*{"SourceMACExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceMACExclude, set_FirewallChainRule_SourceMACExclude, BBFDM_BOTH},*/ +{0} +}; + +DMLEAF tDeviceFirewallChainRuleParam[] = { +{"RuleNumberOfEntries", &DMREAD, DMT_UNINT, get_FirewallChain_RuleNumberOfEntries, NULL, BBFDM_BOTH}, +{0} +}; + +/* *** Device.Firewall.Chain.{i}. *** */ +DMOBJ tDeviceFirewallChainRuleObj[] = { +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */ +{"Rule", &DMWRITE, addObjFirewallChainRule, delObjFirewallChainRule, NULL, browseFirewallChainRuleInst, NULL, NULL, NULL, tFirewallChainRuleParams, NULL, BBFDM_BOTH, NULL}, +{0} +}; + +#if 0 +/* ********** DynamicObj ********** */ +DM_MAP_OBJ tDynamicObj[] = { +/* parentobj, nextobject, parameter */ +{"Device.Firewall.Chain.", tDeviceFirewallChainRuleObj, tDeviceFirewallChainRuleParam}, +{0} +}; +#endif diff --git a/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.c b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.c new file mode 100644 index 0000000000000000000000000000000000000000..82da3d694f40f537c4d352285e17faa84af20e98 --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.c @@ -0,0 +1,12 @@ + +#include "firewall_plugin.h" + +/* ********** DynamicObj ********** */ +DM_MAP_OBJ tDynamicObj[] = { +/* parentobj, nextobject, parameter */ +{"Device.Firewall.Chain.", tDeviceFirewallChainRuleObj, tDeviceFirewallChainRuleParam}, +{"Device.NAT.", tDeviceNATPortTriggerObj, tDeviceNATPortTriggerParams}, +{0} +}; + + diff --git a/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.h b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.h new file mode 100644 index 0000000000000000000000000000000000000000..6ffaa12f04e910399c353a120730df4fc0f233de --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/bbf_plugin/firewall_plugin.h @@ -0,0 +1,12 @@ + +#ifndef FIREWALL_PLUGIN__H +#define FIREWALL_PLUGIN__H + +#include <libbbfdm-api/dmcommon.h> + +extern DMLEAF tDeviceFirewallChainRuleParam[]; +extern DMOBJ tDeviceFirewallChainRuleObj[]; + +extern DMOBJ tDeviceNATPortTriggerObj[]; +extern DMLEAF tDeviceNATPortTriggerParams[]; +#endif diff --git a/src/firewallmngr_backend_firewallmngr/bbf_plugin/nat_porttrigger.c b/src/firewallmngr_backend_firewallmngr/bbf_plugin/nat_porttrigger.c new file mode 100644 index 0000000000000000000000000000000000000000..f7d8d351ad27f669a4245c797b3ba890e379c882 --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/bbf_plugin/nat_porttrigger.c @@ -0,0 +1,540 @@ +/* + * Copyright (C) 2024 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Amit Kumar <amit.kumar@iopsys.eu> + * + */ + +#include "libbbfdm-api/dmcommon.h" + +/************************************************************* +* ENTRY METHOD +**************************************************************/ + +/*#Device.NAT.PortTrigger.{i}.!UCI:port-trigger/port_trigger/dmmap_port_trigger*/ +static int browseNATPortTriggerInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + int inst = 0; + struct uci_section *p = NULL; + struct dm_data data = {0}; + char *name = NULL; + char *buf = NULL; + + uci_foreach_sections("port-trigger", "port_trigger", p) { + dmuci_get_section_name(section_name(p),&name); + if (name) { + sscanf(name, "port_trigger_%d",&inst); + if (inst == 0) { + continue; + } + dmasprintf(&buf, "%d", inst); + data.config_section = p; + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, buf) == DM_STOP) + break; + } + } + + return 0; +} + +static int browseNATPortTriggerRuleInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + struct uci_section *p = NULL; + struct dm_data data = {0}; + int inst = 0; + int ptg_inst = 0; + char *name = NULL; + char *buf = NULL; + int parent_inst = 0; + parent_inst = atoi(prev_instance); + + uci_foreach_sections("port-trigger", "rule", p) { + dmuci_get_section_name(section_name(p),&name); + if (name) { + sscanf(name, "port_trigger_%d_rule_%d",&ptg_inst,&inst); + if ((inst == 0) || (ptg_inst != parent_inst)) + continue; + dmasprintf(&buf, "%d", inst); + data.config_section = p; + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, buf) == DM_STOP) + break; + } + } + return 0; +} + +/************************************************************* +* ADD & DEL OBJ +**************************************************************/ +static int addObjNATPortTrigger(char *refparam, struct dmctx *ctx, void *data, char **instance) +{ + struct uci_section *s = NULL; + char port_trigger_name[16] = {0}; + char name[16] = {0}; + + snprintf(port_trigger_name, sizeof(port_trigger_name), "port_trigger_%s", *instance); + snprintf(name, sizeof(name), "trigger_%s", *instance); + + dmuci_add_section("port-trigger", "port_trigger", &s); + dmuci_rename_section_by_section(s, port_trigger_name); + dmuci_set_value_by_section(s, "name", name); + + return 0; +} + +static int delObjNATPortTrigger(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + struct uci_section *s = NULL, *stmp = NULL; + char *name; + + switch (del_action) { + case DEL_INST: + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name); + uci_foreach_option_eq_safe("port-trigger", "rule", "port_trigger", name, stmp, s) { + dmuci_delete_by_section(s, NULL, NULL); + } + + dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL); + break; + case DEL_ALL: + uci_foreach_sections_safe("port-trigger", "port_trigger", stmp, s) { + + dmuci_delete_by_section(s, NULL, NULL); + } + uci_foreach_sections_safe("port-trigger", "rule", stmp, s) { + + dmuci_delete_by_section(s, NULL, NULL); + } + break; + } + return 0; +} + +static int addObjNATPortTriggerRule(char *refparam, struct dmctx *ctx, void *data, char **instance) +{ + struct uci_section *port_trigger = ((struct dm_data *)data)->config_section; + struct uci_section *s = NULL; + char s_name[50] = {0}; + char *name = NULL; + + snprintf(s_name, sizeof(s_name), "%s_rule_%s", section_name(port_trigger),*instance); + + dmuci_add_section("port-trigger", "rule", &s); + dmuci_rename_section_by_section(s, s_name); + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name); + dmuci_set_value_by_section(s, "port_trigger", name); + + return 0; +} + +static int delObjNATPortTriggerRule(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + struct uci_section *s = NULL, *stmp = NULL; + char *name; + + switch (del_action) { + case DEL_INST: + dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL); + break; + case DEL_ALL: + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &name); + uci_foreach_option_eq_safe("port-trigger", "rule", "port_trigger", name, stmp, s) { + dmuci_delete_by_section(s, NULL, NULL); + } + break; + } + return 0; +} + +/************************************************************* +* GET & SET PARAM +**************************************************************/ +/*#Device.NAT.PortTriggerNumberOfEntries!UCI:port-trigger/port_trigger/*/ +static int get_NAT_PortTriggerNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + int cnt = get_number_of_entries(ctx, data, instance, browseNATPortTriggerInst); + dmasprintf(value, "%d", cnt); + return 0; +} + +static int get_NATPortTrigger_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_section_name(section_name(((struct dm_data *)data)->config_section),value); + return 0; +} + +static int get_NATPortTrigger_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0"); + *value = (**value == 'n' || **value == '0' ) ? "0" : "1"; + return 0; +} + +static int set_NATPortTrigger_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + bool b; + time_t now = time(NULL); + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_boolean(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + string_to_bool(value, &b); + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "enable", b ? "1" : "0"); + + if (b == 1) { + char activation_date[32] = {0}; + + strftime(activation_date, sizeof(activation_date), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "activation_date", activation_date); + } + break; + } + return 0; +} + +static int get_NATPortTrigger_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + /*return the admin state of port trigger rule + * running status to be updated in later changes*/ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0"); + *value = (**value == 'n' || **value == '0' ) ? "Disabled" : "Enabled"; + return 0; +} + +static int get_NATPortTrigger_Origin(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "origin", "Controller"); + return 0; +} + +static int set_NATPortTrigger_Origin(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *Origin[] = {"User", "System", "Controller", NULL}; + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, -1, Origin, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "origin", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "description", value); + return 0; +} + +static int set_NATPortTrigger_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "description", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + char *interf = NULL; + + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "src", &interf); + + adm_entry_get_reference_param(ctx, "Device.IP.Interface.*.Name", interf, value); + + return 0; +} + +static int set_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *allowed_objects[] = {"Device.IP.Interface.", NULL}; + struct dm_reference reference = {0}; + + bbf_get_reference_args(value, &reference); + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL)) + return FAULT_9007; + + if (dm_validate_allowed_objects(ctx, &reference, allowed_objects)) + return FAULT_9007; + + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "src", reference.value); + break; + } + return 0; +} + +static int get_NATPortTrigger_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port", "0"); + return 0; +} + +static int set_NATPortTrigger_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port_end_range", "0"); + return 0; +} + +static int set_NATPortTrigger_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *port; + uint16_t s_port, end_port; + + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "port", &port); + s_port = DM_STRTOL(port); + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1)) + return FAULT_9007; + end_port = DM_STRTOL(value); + if (s_port > end_port) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port_end_range", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_AutoDisableDuration(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "auto_disable_duration", value); + return 0; +} + +static int set_NATPortTrigger_AutoDisableDuration(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}}, 1)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "auto_disable_duration", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_ActivationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "activation_date", "0001-01-01T00:00:00Z"); + return 0; +} + +static int set_NATPortTrigger_ActivationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char activation_date[16] = {0}; + struct tm tm; + + switch (action) { + case VALUECHECK: + if (bbfdm_validate_dateTime(ctx, value)) + return FAULT_9007; + break; + case VALUESET: + strptime(value, "%Y-%m-%dT%H:%M:%SZ", &tm); + snprintf(activation_date, sizeof(activation_date), "%lld", (long long)timegm(&tm)); + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "activation_date", activation_date); + break; + } + return 0; +} + +static int get_NATPortTrigger_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "protocol", value); + return 0; +} + +static int set_NATPortTrigger_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, -1, NATProtocol, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "protocol", value); + break; + } + return 0; +} + +static int get_NATPortTrigger_RuleNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + int cnt = get_number_of_entries(ctx, data, instance, browseNATPortTriggerRuleInst); + dmasprintf(value, "%d", cnt); + return 0; +} + +static int get_NATPortTriggerRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_section_name(section_name(((struct dm_data *)data)->config_section),value); + return 0; +} + +static int get_NATPortTriggerRule_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port", "0"); + return 0; +} + +static int set_NATPortTriggerRule_Port(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port", value); + break; + } + return 0; +} + +static int get_NATPortTriggerRule_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "port_end_range", "0"); + return 0; +} + +static int set_NATPortTriggerRule_PortEndRange(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + + char *port; + uint16_t s_port, end_port; + + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "port", &port); + s_port = DM_STRTOL(port); + switch (action) { + case VALUECHECK: + if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1)) + return FAULT_9007; + end_port = DM_STRTOL(value); + if (s_port > end_port) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "port_end_range", value); + break; + } + return 0; +} + +static int get_NATPortTriggerRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "protocol", value); + return 0; +} + +static int set_NATPortTriggerRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (bbfdm_validate_string(ctx, value, -1, -1, NATProtocol, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section(((struct dm_data *)data)->config_section, "protocol", value); + break; + } + return 0; +} + +/********************************************************************************************************************************** +* OBJ & PARAM DEFINITION +***********************************************************************************************************************************/ + +DMLEAF tNATPortTriggerParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */ +{"Alias", &DMREAD, DMT_STRING, get_NATPortTrigger_Alias, NULL, BBFDM_BOTH}, +{"Enable", &DMWRITE, DMT_BOOL, get_NATPortTrigger_Enable, set_NATPortTrigger_Enable, BBFDM_BOTH}, +{"Status", &DMREAD, DMT_STRING, get_NATPortTrigger_Status, NULL, BBFDM_BOTH}, +{"Origin", &DMWRITE, DMT_STRING, get_NATPortTrigger_Origin, set_NATPortTrigger_Origin, BBFDM_BOTH}, +{"Description", &DMWRITE, DMT_STRING, get_NATPortTrigger_Description, set_NATPortTrigger_Description, BBFDM_BOTH}, +{"Interface", &DMWRITE, DMT_STRING, get_NATPortTrigger_Interface, set_NATPortTrigger_Interface, BBFDM_BOTH, DM_FLAG_REFERENCE}, +{"Port", &DMWRITE, DMT_UNINT, get_NATPortTrigger_Port, set_NATPortTrigger_Port, BBFDM_BOTH}, +{"PortEndRange", &DMWRITE, DMT_UNINT, get_NATPortTrigger_PortEndRange, set_NATPortTrigger_PortEndRange, BBFDM_BOTH}, +{"AutoDisableDuration", &DMWRITE, DMT_UNINT, get_NATPortTrigger_AutoDisableDuration, set_NATPortTrigger_AutoDisableDuration, BBFDM_BOTH}, +{"ActivationDate", &DMWRITE, DMT_TIME, get_NATPortTrigger_ActivationDate, set_NATPortTrigger_ActivationDate, BBFDM_BOTH}, +{"Protocol", &DMWRITE, DMT_STRING, get_NATPortTrigger_Protocol, set_NATPortTrigger_Protocol, BBFDM_BOTH}, +{"RuleNumberOfEntries", &DMREAD, DMT_UNINT, get_NATPortTrigger_RuleNumberOfEntries, NULL, BBFDM_BOTH}, +{0} +}; + +/* *** Device.NAT.PortTrigger.{i}.Rule.{i}. *** */ +DMLEAF tNATPortTriggerRuleParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */ +{"Alias", &DMREAD, DMT_STRING, get_NATPortTriggerRule_Alias, NULL, BBFDM_BOTH}, +{"Port", &DMWRITE, DMT_UNINT, get_NATPortTriggerRule_Port, set_NATPortTriggerRule_Port, BBFDM_BOTH}, +{"PortEndRange", &DMWRITE, DMT_UNINT, get_NATPortTriggerRule_PortEndRange, set_NATPortTriggerRule_PortEndRange, BBFDM_BOTH}, +{"Protocol", &DMWRITE, DMT_STRING, get_NATPortTriggerRule_Protocol, set_NATPortTriggerRule_Protocol, BBFDM_BOTH}, +{0} +}; + +DMLEAF tDeviceNATPortTriggerParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"PortTriggerNumberOfEntries", &DMREAD, DMT_UNINT, get_NAT_PortTriggerNumberOfEntries, NULL, BBFDM_BOTH}, +{0} +}; + +/* *** Device.NAT.PortTrigger.{i}. *** */ +DMOBJ tNATPortTriggerObj[] = { +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */ +{"Rule", &DMWRITE, addObjNATPortTriggerRule, delObjNATPortTriggerRule, NULL, browseNATPortTriggerRuleInst, NULL, NULL, NULL, tNATPortTriggerRuleParams, NULL, BBFDM_BOTH, NULL}, +{0} +}; + +/* *** Device.NAT. *** */ +DMOBJ tDeviceNATPortTriggerObj[] = { +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ +{"PortTrigger", &DMWRITE, addObjNATPortTrigger, delObjNATPortTrigger, NULL, browseNATPortTriggerInst, NULL, NULL, tNATPortTriggerObj, tNATPortTriggerParams, NULL, BBFDM_BOTH}, +{0} +}; + +#if 0 +/* *** Device.NAT.PortTrigger. *** */ +DM_MAP_OBJ tDynamicObj[] = { +/* parentobj, nextobject, parameter */ +{"Device.NAT.", tDeviceNATPortTriggerObj, tDeviceNATPortTriggerParams}, +{0} +}; +#endif diff --git a/src/firewallmngr_backend_firewallmngr/firewallmngrd.c b/src/firewallmngr_backend_firewallmngr/firewallmngrd.c new file mode 100644 index 0000000000000000000000000000000000000000..b01bd94763e8f803f5f548108d9815070bc7822e --- /dev/null +++ b/src/firewallmngr_backend_firewallmngr/firewallmngrd.c @@ -0,0 +1,394 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <syslog.h> +#include <libubox/blobmsg_json.h> +#include <libubus.h> +#include <uci.h> +#include <json-c/json.h> + + + +int nat_get_status(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); +int firewallmngr_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); + +const char *ubus_socket; +struct ubus_context *ctx = NULL; + +enum { + STATUS_POLICY_INSTANCE, + STATUS_POLICY_MAX +}; + +static const struct blobmsg_policy status_policy[STATUS_POLICY_MAX] = { + [STATUS_POLICY_INSTANCE] = { .name = "instance", .type = BLOBMSG_TYPE_STRING }, +}; + +static const struct ubus_method nat_methods[] = { + UBUS_METHOD("status", nat_get_status, status_policy), +}; + +static struct ubus_object_type nat_object_type = + UBUS_OBJECT_TYPE("nat", nat_methods); + +static struct ubus_object nat_object = { + .name = "nat", + .type = &nat_object_type, + .methods = nat_methods, + .n_methods = ARRAY_SIZE(nat_methods), +}; + +static const struct ubus_method firewallmngr_methods[] = { + { .name = "status", .handler = firewallmngr_get_status }, +}; + +static struct ubus_object_type firewallmngr_object_type = + UBUS_OBJECT_TYPE("firewallmngr", firewallmngr_methods); + +static struct ubus_object firewallmngr_object = { + .name = "firewallmngr", + .type = &firewallmngr_object_type, + .methods = firewallmngr_methods, + .n_methods = ARRAY_SIZE(firewallmngr_methods), +}; + + + +/** + * To expose the firewallmngr object on ubus i.e., firewallmngr or nat with method status + * @param context input parameter pointer to ubus context + * retrun integer value 0 on success and -1 on failure + */ +static int firewallmngr_publish_object(struct ubus_context *context, struct ubus_object *obj) +{ + int ret; + ret = ubus_add_object(context, obj); + if (ret) { + syslog(LOG_ERR, "Failed to add firewallmngr ubus object: %s\n", + ubus_strerror(ret)); + } + + return ret; +} + +static void nat_get_interfacesetting_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg) +{ + char *status = "Disabled"; + struct uci_element *uci_elmnt = NULL; + struct blob_attr *tb[STATUS_POLICY_MAX]; + char instance[20] = {0}; + + blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[STATUS_POLICY_INSTANCE]) + return; + + strncpy(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1); + + uci_foreach_element(&uci_pkg->sections, uci_elmnt) { + struct uci_section *uci_sec = uci_to_section(uci_elmnt); + + + if (uci_sec && !strcmp(uci_sec->type, "zone")) { + struct uci_element *e = NULL; + if (strcmp(instance, uci_sec->e.name)) + continue; + + blobmsg_add_string(buf, "name", uci_sec->e.name); + uci_foreach_element(&uci_sec->options, e) { + struct uci_option *uci_opn = uci_to_option(e); +syslog(LOG_INFO,"%s %d \n", __FUNCTION__, __LINE__); + if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) { + status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled"; + break; + } + } + blobmsg_add_string(buf, "Status", status); + } + + } +} + +static void nat_get_portmapping_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg) +{ + char *status = "Disabled"; + struct uci_element *uci_elmnt = NULL; + struct blob_attr *tb[STATUS_POLICY_MAX]; + char instance[20] = {0}; + + blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[STATUS_POLICY_INSTANCE]) + return; + + strncpy(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1); + + uci_foreach_element(&uci_pkg->sections, uci_elmnt) { + struct uci_section *uci_sec = uci_to_section(uci_elmnt); + + if (uci_sec && !strcmp(uci_sec->type, "redirect")) { + struct uci_element *e = NULL; + if (strcmp(instance, uci_sec->e.name)) + continue; + + blobmsg_add_string(buf, "name", uci_sec->e.name); + uci_foreach_element(&uci_sec->options, e) { + struct uci_option *uci_opn = uci_to_option(e); + if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) { + status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled"; + break; + } + } + blobmsg_add_string(buf, "Status", status); + } + + } +} + +/** + * nat_get_status function callback on ubus method nat_status + * @param ctx input parameter pointer to ubus context + * @param obj input parameter pointer to ubus object in out case nat + * @param req input parameter pointer to ubus requested data + * @param method input parameter pointer to char method i.e., nat_status + * @param msg input parameter pointer containing + * retrun integer value 0 on success and -1 on failure + */ +int nat_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + int ret = 0; + + struct blob_buf b = {0}; + struct uci_package *uci_pkg = NULL; + struct uci_context *uci_ctx = uci_alloc_context(); + + uci_load(uci_ctx, "firewall", &uci_pkg); + if (!uci_pkg) { + syslog(LOG_ERR, "nat Failed to load configuration\n"); + goto done; + } + + blob_buf_init(&b, 0); + + nat_get_interfacesetting_status(&b, uci_pkg, msg); + nat_get_portmapping_status(&b, uci_pkg, msg); + + ubus_send_reply(ctx_arg, req, b.head); + + blob_buf_free(&b); + uci_unload(uci_ctx, uci_pkg); +done: + uci_free_context(uci_ctx); + return ret; + +} + +static void firewallmngr_get_service_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg) +{ + char *status = "Disabled"; + struct uci_element *uci_elmnt = NULL; + struct blob_attr *tb[STATUS_POLICY_MAX]; + char instance[30] = {0}; + + blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[STATUS_POLICY_INSTANCE]) + return; + + strcpy(instance,"fwmngr_"); + strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1); + + + uci_foreach_element(&uci_pkg->sections, uci_elmnt) { + struct uci_section *uci_sec = uci_to_section(uci_elmnt); + + if (uci_sec && !strcmp(uci_sec->type, "service")) { + struct uci_element *e = NULL; + if (strcmp(instance, uci_sec->e.name)) + continue; + + blobmsg_add_string(buf, "name", uci_sec->e.name); + uci_foreach_element(&uci_sec->options, e) { + struct uci_option *uci_opn = uci_to_option(e); + if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) { + status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled"; + break; + } + } + blobmsg_add_string(buf, "Status", status); + } + + } +} + +static void firewallmngr_get_dmz_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg) +{ + char *status = "Disabled"; + struct uci_element *uci_elmnt = NULL; + struct blob_attr *tb[STATUS_POLICY_MAX]; + char instance[30] = {0}; + + blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[STATUS_POLICY_INSTANCE]) + return; + + strcpy(instance,"fwmngr_"); + strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1); + + + uci_foreach_element(&uci_pkg->sections, uci_elmnt) { + struct uci_section *uci_sec = uci_to_section(uci_elmnt); + + if (uci_sec && !strcmp(uci_sec->type, "redirect")) { + struct uci_element *e = NULL; + if (strcmp(instance, uci_sec->e.name)) + continue; + + blobmsg_add_string(buf, "name", uci_sec->e.name); + uci_foreach_element(&uci_sec->options, e) { + struct uci_option *uci_opn = uci_to_option(e); + if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) { + status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled"; + break; + } + } + blobmsg_add_string(buf, "Status", status); + } + + } +} + +static void firewallmngr_get_rule_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg) +{ + char *status = "Disabled"; + struct uci_element *uci_elmnt = NULL; + struct blob_attr *tb[STATUS_POLICY_MAX]; + char instance[30] = {0}; + + blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[STATUS_POLICY_INSTANCE]) + return; + + strcpy(instance,"fwmngr_"); + strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1); + + uci_foreach_element(&uci_pkg->sections, uci_elmnt) { + struct uci_section *uci_sec = uci_to_section(uci_elmnt); + + if (uci_sec && !strcmp(uci_sec->type, "rule")) { + struct uci_element *e = NULL; + if (strcmp(instance, uci_sec->e.name)) + continue; + + blobmsg_add_string(buf, "name", uci_sec->e.name); + uci_foreach_element(&uci_sec->options, e) { + struct uci_option *uci_opn = uci_to_option(e); + if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) { + status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled"; + break; + } + } + blobmsg_add_string(buf, "Status", status); + } + + } +} + +/** + * firewallmngr_get_status function callback on ubus method firewallmngr_status + * @param ctx input parameter pointer to ubus context + * @param obj input parameter pointer to ubus object in out case firewallmngr + * @param req input parameter pointer to ubus requested data + * @param method input parameter pointer to char method i.e., firewallmngr_status + * @param msg input parameter pointer containing + * retrun integer value 0 on success and -1 on failure + */ +int firewallmngr_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + int ret = 0; + + struct blob_buf b = {0}; + struct uci_package *uci_pkg = NULL; + struct uci_context *uci_ctx = uci_alloc_context(); + + blob_buf_init(&b, 0); + uci_load(uci_ctx, "firewall", &uci_pkg); + if (!uci_pkg) { + syslog(LOG_ERR, "firewallmngr Failed to load configuration\n"); + uci_free_context(uci_ctx); + return ret; + } + + firewallmngr_get_rule_status(&b, uci_pkg, msg); + firewallmngr_get_dmz_status(&b, uci_pkg, msg); + firewallmngr_get_service_status(&b, uci_pkg, msg); + + ubus_send_reply(ctx_arg, req, b.head); + + blob_buf_free(&b); + uci_unload(uci_ctx, uci_pkg); + uci_free_context(uci_ctx); + return ret; + +} + + +/** + * Main function for firewallmngr, everything starts here + * @param argc input number of input arguments + * @param argv input double pointer array of optional command line arguments + * retrun integer value 0 on success and -1 on failure + */ +int main(int argc, char **argv) +{ + int ret; + int ch; + + while ((ch = getopt(argc, argv, "s:e:")) != -1) { + switch (ch) { + case 's': + ubus_socket = optarg; + break; + default: + break; + } + } + + argc -= optind; + argv += optind; + + uloop_init(); + ctx = ubus_connect(ubus_socket); + if (!ctx) { + syslog(LOG_ERR, "nat Failed to connect to ubus\n"); + return -1; + } + + ubus_add_uloop(ctx); + ret = firewallmngr_publish_object(ctx, &nat_object); + if (ret) + goto out; + ret = firewallmngr_publish_object(ctx, &firewallmngr_object); + if (ret) + goto out; + + /* Main loop of firewallmngr */ + uloop_run(); + + out: + ubus_free(ctx); + uloop_done(); + + return 0; +} +