blob: fbe6fae9f2d9fa78d6c6401967ab2d01e25342a6 [file] [log] [blame]
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <libubox/blobmsg_json.h>
#include <libubox/blob.h>
#include "libubus.h"
#include <uci.h>
#include <include/log.h>
#include <sys/prctl.h>
#include "router_firewall.h"
#ifdef CONFIG_LOG_ENABLE
#define FW_DBG(format, args...) RDPRINTF("%s " format, __FUNCTION__, ##args);
#define FW_ERR(format, args...) RERRMSG("%s " format, __FUNCTION__, ##args);
#else
#define FW_DBG(format, args...) do {} while (0)
#define FW_ERR(format, args...) do {} while (0)
#endif
#ifndef FW_PACK
#define FW_PACK "firewall"
#endif
#ifndef DHCP_PACK
#define DHCP_PACK "dhcp"
#endif
#ifndef UNUSESET
#define UNUSESET(param) (void)(param)
#endif
static int fw_system(const char *cmd)
{
FILE *fp;
int res;
char buf[1024];
if (cmd == NULL) {
FW_ERR("my_system cmd is NULL!\n");
return -1;
}
if ((fp = popen(cmd, "r")) == NULL) {
FW_ERR("popen error: %s/n", strerror(errno));
return -1;
} else {
while (fgets(buf, sizeof(buf), fp)) {
FW_DBG("%s", buf);
}
if ((res = pclose(fp)) == -1) {
FW_ERR("close popen file pointer fp error!\n");
return res;
} else if (res == 0) {
return res;
} else {
FW_DBG("popen res is :%d\n", res);
return res;
}
}
}
static struct uci_context *uci_ctx_fw = NULL;
/*get uci_ctx*/
static struct uci_context *uci_fw_ctx_get(void)
{
if (uci_ctx_fw) {
return uci_ctx_fw;
}
uci_ctx_fw = uci_alloc_context();
if (!uci_ctx_fw) {
FW_ERR("%s, uci_ctx_api malloc failed", __FUNCTION__);
return NULL;
}
return uci_ctx_fw;
}
/*free uci_ctx*/
static void free_fw_uci_ctx(void)
{
if (uci_ctx_fw) {
uci_free_context(uci_ctx_fw);
uci_ctx_fw = NULL;
}
}
/*blob buf used in Firewall*/
static struct blob_buf fw_buf;
/*================================================
<firewall>
<disable/>
<ip_filter_disable/>
<dn_filter_disable/>
<dmz_disable/>
<upnp_disable/>
<port_trigger_disable/>
</firewall>
Note : add "option filter_type ip_filter/mac_filter" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
int fw_get_disable_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
UNUSESET(msg);
UNUSESET(method);
UNUSESET(obj);
FW_DBG("enter");
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (p) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "defaults") == 0) {
FW_DBG("get uci_sec defaults");
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "disable");
if (opt_val) {
FW_DBG("get fw disable %s", opt_val);
blobmsg_add_string(&fw_buf, "disable", opt_val);
} else {
blobmsg_add_string(&fw_buf, "disable", "1");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "ip_filter_disable");
if (opt_val) {
FW_DBG("get ip_filter disable %s", opt_val);
blobmsg_add_string(&fw_buf, "ip_filter_disable", opt_val);
} else {
blobmsg_add_string(&fw_buf, "ip_filter_disable", "1");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dn_filter_disable");
if (opt_val) {
FW_DBG("get dn_filter_disable disable %s", opt_val);
blobmsg_add_string(&fw_buf, "dn_filter_disable", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dn_filter_disable", "1");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dmz_disable");
if (opt_val) {
FW_DBG("get dmz_disable disable %s", opt_val);
blobmsg_add_string(&fw_buf, "dmz_disable", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dmz_disable", "1");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "upnp_disable");
if (opt_val) {
FW_DBG("get upnp_disable disable %s", opt_val);
blobmsg_add_string(&fw_buf, "upnp_disable", opt_val);
} else {
blobmsg_add_string(&fw_buf, "upnp_disable", "1");
}
}
}
} else {
blobmsg_add_string(&fw_buf, "disable", "1");
}
if (tb_fw) {
blobmsg_close_table(&fw_buf, tb_fw);
}
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
</firewall>
Note : add "option filter_type ip_filter/mac_filter" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
int fw_set_disable_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
struct blob_attr *fw_setting[ARRAY_SIZE(fw_setting_pol)];
int ret_val = 0;
int FW_set_type = 0;
const char *opt_val_2 = NULL;
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting, blob_data(msg), blob_len(msg)) != 0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
FW_ERR("get firewall failed");
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "defaults") == 0) {
break;
}
}
if (!uci_sec) {
FW_DBG("can't find defaults section");
goto EXIT;
}
if (fw_setting[DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "disable";
ptr.value = blobmsg_get_string(fw_setting[DISABLE]);
uci_set(local_ctx, &ptr);
if (strcmp(blobmsg_get_string(fw_setting[DISABLE]), "1") == 0) {
FW_set_type = UI_FW_DISABLE;
} else {
FW_set_type = UI_FW_ENABLE;
}
}
if (fw_setting[IP_FILTER_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[IP_FILTER_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ip_filter_disable";
ptr.value = blobmsg_get_string(fw_setting[IP_FILTER_DISABLE]);
uci_set(local_ctx, &ptr);
if (strcmp(blobmsg_get_string(fw_setting[IP_FILTER_DISABLE]), "1") == 0) {
FW_set_type = UI_IP_FILTER_DISABLE;
} else {
FW_set_type = UI_IP_FILTER_ENABLE;
}
}
if (fw_setting[DN_FILTER_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[DN_FILTER_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dn_filter_disable";
ptr.value = blobmsg_get_string(fw_setting[DN_FILTER_DISABLE]);
uci_set(local_ctx, &ptr);
if (strcmp(blobmsg_get_string(fw_setting[DN_FILTER_DISABLE]), "1") == 0) {
FW_set_type = UI_DN_FILTER_DISABLE;
} else {
FW_set_type = UI_DN_FILTER_ENABLE;
}
}
if (fw_setting[PORT_MAPPING_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[PORT_MAPPING_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "port_mapping_disable";
ptr.value = blobmsg_get_string(fw_setting[PORT_MAPPING_DISABLE]);
uci_set(local_ctx, &ptr);
}
if (fw_setting[DMZ_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[DMZ_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dmz_disable";
ptr.value = blobmsg_get_string(fw_setting[DMZ_DISABLE]);
uci_set(local_ctx, &ptr);
/*set redirect with fw_type:dmz start */
uci_foreach_element(&p->sections, e) {
if (!strcmp(uci_sec->type, "redirect")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
opt_val_2 = uci_lookup_option_string(local_ctx, uci_sec, "dest_ip");
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
if (strcmp(blobmsg_get_string(fw_setting[DMZ_DISABLE]), "1") == 0) {
ptr.value = "0";
} else {
ptr.value = "1";
}
uci_set(local_ctx, &ptr);
}
}
/*set redirect with fw_type:dmz end */
/*set rule with filter_type:dmz start */
if (opt_val_2 && !strcmp(uci_sec->type, "rule")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "src_ip");
if (opt_val && !strcmp(opt_val_2, opt_val)) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
if (strcmp(blobmsg_get_string(fw_setting[DMZ_DISABLE]), "1") == 0) {
ptr.value = "0";
} else {
ptr.value = "1";
}
uci_set(local_ctx, &ptr);
}
}
}
/*set rule with filter_type:dmz end */
}
}
if (fw_setting[UPNP_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[UPNP_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "upnp_fw_disable";
ptr.value = blobmsg_get_string(fw_setting[UPNP_DISABLE]);
uci_set(local_ctx, &ptr);
}
if (fw_setting[PORT_TRIGGER_DISABLE]) {
FW_DBG("disabe is %s", blobmsg_get_string(fw_setting[PORT_TRIGGER_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "port_trigger_disable";
ptr.value = blobmsg_get_string(fw_setting[PORT_TRIGGER_DISABLE]);
uci_set(local_ctx, &ptr);
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
switch (FW_set_type) {
case UI_FW_ENABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh FW_ENABLE");
fw_system("/etc/init.d/firewall restart");
break;
case UI_FW_DISABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh FW_DISABLE");
fw_system("/etc/init.d/firewall restart");
break;
case UI_IP_FILTER_ENABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh IP_ENABLE");
fw_system("/etc/init.d/firewall restart");
break;
case UI_IP_FILTER_DISABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh IP_DISABLE");
fw_system("/etc/init.d/firewall restart");
break;
case UI_DN_FILTER_DISABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh DN_DISABLE");
//fw_system("/etc/init.d/dhcp restart");
break;
case UI_DN_FILTER_ENABLE:
fw_system("/lib/router_fw/fw_ui_transfer.sh DN_ENABLE");
//fw_system("/etc/init.d/dhcp restart");
break;
}
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
if (tb_fw) {
blobmsg_close_table(&fw_buf, tb_fw);
}
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<ip_filter>
<default_policy>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<src_ip/>
<src_port/>
<dest_ip/>
<dest_port/>
<proto/>
<target/>
<enabled/>
</entry_index>
...
</entry_list>
</ip_filter>
</firewall>
Note : add "option filter_type ip_filter/mac_filter" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
int fw_get_ip_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
void *tb_ip_filter = NULL;
void *tb_entry_list = NULL;
void *tb_entry_one = NULL;
int index = 1;
char index_buf[10] = { 0 };
FW_DBG("enter");
UNUSESET(obj);
UNUSESET(method);
UNUSESET(msg);
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (p) {
tb_ip_filter = blobmsg_open_table(&fw_buf, "ip_filter");
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
#if 0
if (!strcmp(uci_sec->type, "zone")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "name");
if (opt_val && !strcmp(opt_val, "wan")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "output");
if (opt_val) {
FW_DBG("zone-->wan-->output is %s", opt_val);
blobmsg_add_string(&fw_buf, "default_policy", opt_val);
}
} else {
continue;
}
}
#endif
if (!strcmp(uci_sec->type, "defaults")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "ip_filter_policy");
if (opt_val) {
FW_DBG("defaults.ip_filter_policy %s", opt_val);
blobmsg_add_string(&fw_buf, "default_policy", opt_val);
} else {
/*set default policy as ACCEPT*/
blobmsg_add_string(&fw_buf, "default_policy", "ACCEPT");
}
}
if (strcmp(uci_sec->type, "rule") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val) {
FW_DBG("filter_type is %s", opt_val);
}
if (opt_val && !strcmp(opt_val, "ip_filter")) {
FW_DBG("filter_type is %s", opt_val);
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "last_rule");
if (opt_val && !strcmp(opt_val, "1")) {
/*suppress the last rule to webui*/
FW_DBG("last rule in ip filter");
continue;
}
if (!tb_entry_list) {
tb_entry_list = blobmsg_open_table(&fw_buf, "entry_list");
}
memset(index_buf, 0, 10);
snprintf(index_buf, 10, "entry_%d", index++);
FW_DBG("get one ip filter:%s", index_buf);
tb_entry_one = blobmsg_open_table(&fw_buf, index_buf);
/*start time */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "start_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "start_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "start_time", "none");
}
/*stop time */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "stop_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "stop_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "stop_time", "none");
}
/*src_ip */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "src_ip");
if (opt_val) {
blobmsg_add_string(&fw_buf, "src_ip", opt_val);
} else {
blobmsg_add_string(&fw_buf, "src_ip", "0");
}
/*src port */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "src_port");
if (opt_val) {
blobmsg_add_string(&fw_buf, "src_port", opt_val);
} else {
blobmsg_add_string(&fw_buf, "src_port", "none");
}
/*dest ip */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dest_ip");
if (opt_val) {
blobmsg_add_string(&fw_buf, "dest_ip", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dest_ip", "0");
}
/*dest port */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dest_port");
if (opt_val) {
blobmsg_add_string(&fw_buf, "dest_port", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dest_port", "none");
}
/*proto; tcp,udp,tcpudp,udplite,icmp,esp,ah,sctp */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "proto");
if (opt_val) {
blobmsg_add_string(&fw_buf, "proto", opt_val);
} else {
blobmsg_add_string(&fw_buf, "proto", "none");
}
/*target */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "target");
if (opt_val) {
blobmsg_add_string(&fw_buf, "target", opt_val);
} else {
blobmsg_add_string(&fw_buf, "target", "none");
}
/*enabled */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "enabled");
if (opt_val) {
blobmsg_add_string(&fw_buf, "enabled", opt_val);
} else {
blobmsg_add_string(&fw_buf, "enabled", "1");
}
blobmsg_close_table(&fw_buf, tb_entry_one);
}
}
}
if (tb_entry_list) {
blobmsg_close_table(&fw_buf, tb_entry_list);
}
blobmsg_close_table(&fw_buf, tb_ip_filter);
} else {
blobmsg_add_string(&fw_buf, "disable", "1");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<ip_filter>
<default_policy/>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<src_ip/>
<src_port/>
<dest_ip/>
<dest_port/>
<proto/>
<target/>
</entry_index>
...
</entry_list>
</ip_filter>
</firewall>
Note : add "option filter_type ip_filter/mac_filter" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
enum {
DEFAULT_IP_FILTER_POL,
IP_FILTER_ENTRY_LIST,
};
static const struct blobmsg_policy fw_set_ipfilter_pol[] = {
[DEFAULT_IP_FILTER_POL] = {
.name = "default_policy",
.type = BLOBMSG_TYPE_STRING,
},
[IP_FILTER_ENTRY_LIST] = {
.name = "entry_list",
.type = BLOBMSG_TYPE_TABLE,
},
};
enum {
START_TIME,
STOP_TIME,
SRC_IP,
SRC_PORT,
DEST_IP,
DEST_PORT,
PROTO,
TARGET,
ENABLED,
};
static const struct blobmsg_policy ipfilter_entry_pol[] = {
[START_TIME] = {
.name = "start_time",
.type = BLOBMSG_TYPE_STRING,
},
[STOP_TIME] = {
.name = "stop_time",
.type = BLOBMSG_TYPE_STRING,
},
[SRC_IP] = {
.name = "src_ip",
.type = BLOBMSG_TYPE_STRING,
},
[SRC_PORT] = {
.name = "src_port",
.type = BLOBMSG_TYPE_STRING,
},
[DEST_IP] = {
.name = "dest_ip",
.type = BLOBMSG_TYPE_STRING,
},
[DEST_PORT] = {
.name = "dest_port",
.type = BLOBMSG_TYPE_STRING,
},
[PROTO] = {
.name = "proto",
.type = BLOBMSG_TYPE_STRING,
},
[TARGET] = {
.name = "target",
.type = BLOBMSG_TYPE_STRING,
},
[ENABLED] = {
.name = "enabled",
.type = BLOBMSG_TYPE_STRING,
},
};
enum {
SET_ADD_IPFILTER_ENTRY,
EDIT_IPFILTER_ENTRY,
};
static int fw_set_ip_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg, int type)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
int ret_val = 0;
struct uci_ptr ptr;
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
int edit_index = 0;
int index = 0;
struct blob_attr *fw_setting[ARRAY_SIZE(fw_setting_pol)];
struct blob_attr *ipfilter_pol_arrt[ARRAY_SIZE(fw_set_ipfilter_pol)];
struct blob_attr *entry_pol[ARRAY_SIZE(ipfilter_entry_pol)];
struct blob_attr *attr_head = NULL;
int attr_len = 0;
bool default_policy_changed = false;
bool black_to_white = false;
bool last_rule_exist = false;
bool default_policy_first_set = false;
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting, blob_data(msg), blob_len(msg)) != 0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting[IP_FILTER]) {
goto EXIT;
}
if (blobmsg_parse
(fw_set_ipfilter_pol, ARRAY_SIZE(fw_set_ipfilter_pol), ipfilter_pol_arrt,
blobmsg_data(fw_setting[IP_FILTER]), blobmsg_data_len(fw_setting[IP_FILTER])) != 0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL] && !ipfilter_pol_arrt[IP_FILTER_ENTRY_LIST]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
/*SET DEFAULT POL */
if (ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
#if 0
if (strcmp(uci_sec->type, "zone") == 0) {
FW_DBG("zone->wan->output->%s", blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]));
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "name");
if (opt_val && !strcmp(opt_val, "wan")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "output");
if (!strcmp(opt_val, blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL])))
{
/*policy not changed*/
FW_DBG("policy %s not changed", blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]));
break;
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "output";
ptr.value = blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]);
uci_set(local_ctx, &ptr);
default_policy_changed = true;
break;
}
}
#endif
if (strcmp(uci_sec->type, "defaults") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "ip_filter_policy");
if (opt_val ) {
if ( !strcmp(opt_val, blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]))) {
/*policy not changed*/
FW_DBG("policy %s not changed", blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]));
break;
} else {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ip_filter_policy";
ptr.value = blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]);
uci_set(local_ctx, &ptr);
default_policy_changed = true;
}
} else {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ip_filter_policy";
ptr.value = blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]);
uci_set(local_ctx, &ptr);
default_policy_first_set = true;
/*ACCEPT->REJECT*/
if (!strcmp( blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]), "REJECT"))
default_policy_changed = true;
}
break;
}
}
}
/*add new ipfilter entry */
if (ipfilter_pol_arrt[IP_FILTER_ENTRY_LIST]) {
attr_head = blobmsg_data(ipfilter_pol_arrt[IP_FILTER_ENTRY_LIST]);
attr_len = blobmsg_data_len(ipfilter_pol_arrt[IP_FILTER_ENTRY_LIST]);
__blob_for_each_attr(attr, attr_head, attr_len) {
hdr = blob_data(attr);
/*name as entry_index,entry_1, entry_2,eg. */
if (hdr->name) {
FW_DBG("add new ipfiter -- %s", hdr->name);
}
if (!strstr((char *)hdr->name, "entry")) {
continue;
}
if (type == EDIT_IPFILTER_ENTRY) {
if (sscanf((char *)hdr->name, "%*5s_%d", &edit_index) == 1) {
FW_DBG("get edit index -- %d", edit_index);
} else {
FW_DBG("get edit index fail");
ret_val = 1;
goto EXIT;
}
}
/*type should be table */
if (blob_id(attr) != BLOBMSG_TYPE_TABLE) {
continue;
}
FW_DBG("GOT ONE NEW ENTRY");
if (blobmsg_parse
(ipfilter_entry_pol, ARRAY_SIZE(ipfilter_entry_pol), entry_pol, blobmsg_data(attr),
blobmsg_data_len(attr)) == 0) {
if (type == SET_ADD_IPFILTER_ENTRY) {
/*add one section with type :rule */
uci_add_section(local_ctx, p, "rule", &uci_sec);
} else if (type == EDIT_IPFILTER_ENTRY) {
index = 0;
/*find the rule */
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "rule")) {
opt_val =
uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "ip_filter")) {
index++;
FW_DBG("index : %d, edit_index : %d", index,
edit_index);
if (index == edit_index) {
break;
}
}
}
}
}
if (uci_sec) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src";
ptr.value = "lan";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest";
ptr.value = "wan";
uci_set(local_ctx, &ptr);
if (entry_pol[START_TIME]) {
FW_DBG("start_time is %s", blobmsg_get_string(entry_pol[START_TIME]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "start_time";
ptr.value = blobmsg_get_string(entry_pol[START_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[STOP_TIME]) {
FW_DBG("STOP_TIME is %s", blobmsg_get_string(entry_pol[STOP_TIME]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "stop_time";
ptr.value = blobmsg_get_string(entry_pol[STOP_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[SRC_IP]) {
FW_DBG("SRC_IP is %s", blobmsg_get_string(entry_pol[SRC_IP]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src_ip";
ptr.value = blobmsg_get_string(entry_pol[SRC_IP]);
if (!strcmp(ptr.value, "0"))
uci_delete(local_ctx, &ptr);
else
uci_set(local_ctx, &ptr);
}
if (entry_pol[SRC_PORT]) {
FW_DBG("SRC_PORT is %s", blobmsg_get_string(entry_pol[SRC_PORT]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src_port";
ptr.value = blobmsg_get_string(entry_pol[SRC_PORT]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[DEST_IP]) {
FW_DBG("DEST_IP is %s", blobmsg_get_string(entry_pol[DEST_IP]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest_ip";
ptr.value = blobmsg_get_string(entry_pol[DEST_IP]);
if (!strcmp(ptr.value, "0"))
uci_delete(local_ctx, &ptr);
else
uci_set(local_ctx, &ptr);
}
if (entry_pol[DEST_PORT]) {
FW_DBG("DEST_PORT is %s", blobmsg_get_string(entry_pol[DEST_PORT]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest_port";
ptr.value = blobmsg_get_string(entry_pol[DEST_PORT]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[PROTO]) {
FW_DBG("PROTO is %s", blobmsg_get_string(entry_pol[PROTO]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "proto";
ptr.value = blobmsg_get_string(entry_pol[PROTO]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[TARGET]) {
FW_DBG("TARGET is %s", blobmsg_get_string(entry_pol[TARGET]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "target";
ptr.value = blobmsg_get_string(entry_pol[TARGET]);
uci_set(local_ctx, &ptr);
}
if (entry_pol[ENABLED]) {
FW_DBG("ENABLED is %s", blobmsg_get_string(entry_pol[ENABLED]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ui_enabled";
ptr.value = blobmsg_get_string(entry_pol[ENABLED]);
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
ptr.value = blobmsg_get_string(entry_pol[ENABLED]);
uci_set(local_ctx, &ptr);
}
if (type == SET_ADD_IPFILTER_ENTRY) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "filter_type";
ptr.value = "ip_filter";
uci_set(local_ctx, &ptr);
}
}
}
}
}
/*add/reorder last rule*/
if (type == SET_ADD_IPFILTER_ENTRY || default_policy_first_set) {
/*check whether exist*/
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "rule")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "ip_filter")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "last_rule");
if (opt_val && !strcmp(opt_val, "1")) {
FW_DBG("find rule.last_rule for ip filter type, reorder target %s to tail", blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]));
/*reorder the section to tail, make the position enough large*/
uci_reorder_section(local_ctx, uci_sec, 1000);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "target";
ptr.value = blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]);
uci_set(local_ctx, &ptr);
last_rule_exist = true;
break;
}
}
}
}
if (!last_rule_exist) {
uci_add_section(local_ctx, p, "rule", &uci_sec);
/*add last rule in tail*/
if (uci_sec) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src";
ptr.value = "lan";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest";
ptr.value = "wan";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src_ip";
ptr.value = "any";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "proto";
ptr.value = "all";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "target";
ptr.value = blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]);
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ui_enable";
ptr.value = "1";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enable";
ptr.value = "1";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "filter_type";
ptr.value = "ip_filter";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "last_rule";
ptr.value = "1";
uci_set(local_ctx, &ptr);
last_rule_exist = true;
}
}
}
if (default_policy_changed) {
/*white-list change to black-list*/
if (!strcmp(blobmsg_get_string(ipfilter_pol_arrt[DEFAULT_IP_FILTER_POL]), "REJECT"))
black_to_white = true;
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
/*change target for every rule*/
if (strcmp(uci_sec->type, "rule") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "ip_filter")) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "target";
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "last_rule");
if (opt_val && !strcmp(opt_val, "1")) {
/*the last rule*/
if (black_to_white)
ptr.value = "REJECT";
else
ptr.value = "ACCEPT";
} else {
if (black_to_white)
ptr.value = "ACCEPT";
else
ptr.value = "REJECT";
}
uci_set(local_ctx, &ptr);
}
}
}
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
if (default_policy_changed || default_policy_first_set
|| ipfilter_pol_arrt[IP_FILTER_ENTRY_LIST])
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<ip_filter>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<src_ip/>
<src_port/>
<dest_ip/>
<dest_port/>
<proto/>
<target/>
</entry_index>
...
</entry_list>
</ip_filter>
</firewall>
Note : add "option filter_type ip_filter/mac_filter" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
int fw_set_add_ip_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_ip_filter_info_cb(ctx, obj, req, method, msg, SET_ADD_IPFILTER_ENTRY);
}
int fw_update_ip_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_ip_filter_info_cb(ctx, obj, req, method, msg, EDIT_IPFILTER_ENTRY);
}
/*================================================
<firewall>
<delete_ipfilter_index>
</firewall>
seperate by ','
================================================*/
int fw_delete_ip_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
int ret_val = 0;
struct uci_section **delete_uci_array = NULL;
int delete_num = 0;
char *begin = NULL;
char *end = NULL;
int *del_index_array = NULL;
char tmp_buf[5] = { 0 };
int cur_index = 0;
int tmp_index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
FW_DBG("enter");
UNUSESET(obj);
UNUSESET(method);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_DBG("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DELETE_IP_FILTER]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
FW_DBG("delete index is %s", blobmsg_get_string(fw_setting_attr[DELETE_IP_FILTER]));
if (fw_setting_attr[DELETE_IP_FILTER]) {
begin = blobmsg_get_string(fw_setting_attr[DELETE_IP_FILTER]);
/*to get the number of delete index */
while ((begin = strchr(begin, ','))) {
delete_num++;
begin++;
}
FW_DBG(" delete total is %d", delete_num);
if (delete_num == 0) {
ret_val = 2;
goto EXIT;
}
/*malloc memory */
delete_uci_array = (struct uci_section **)malloc(delete_num * sizeof(struct uci_section *));
memset(delete_uci_array, 0, delete_num * sizeof(struct uci_section *));
del_index_array = (int *)malloc(delete_num * sizeof(int));
memset(del_index_array, 0, delete_num * sizeof(int));
/*get the index, storing into del_index_array */
cur_index = 0;
begin = blobmsg_get_string(fw_setting_attr[DELETE_IP_FILTER]);
while ((end = strchr(begin, ','))) {
memset(tmp_buf, 0, 5);
if (end - begin < 5) {
memcpy(tmp_buf, begin, end - begin);
FW_DBG("tmp_buf is %s", tmp_buf);
} else {
FW_DBG("parse deleting index wrong");
break;;
}
if (cur_index > delete_num) {
break;
}
del_index_array[cur_index++] = atoi(tmp_buf);
begin = end + 1;
}
/*Print the delete index */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
FW_DBG("delete index %d", del_index_array[tmp_index]);
}
/*travel the sections ,and storing the deleting uci_sec to delete_uci_array */
cur_index = 0;
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "rule") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "ip_filter")) {
cur_index++;
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
if (del_index_array[tmp_index] == 0) {
continue;
}
if (cur_index == del_index_array[tmp_index]) {
FW_DBG("find uci_sec with index %d", cur_index);
delete_uci_array[tmp_index] = uci_sec;
break;
}
}
}
}
}
}
/*delete the section */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = (struct uci_section *)delete_uci_array[tmp_index];
uci_delete(local_ctx, &ptr);
}
EXIT:
if (del_index_array) {
free(del_index_array);
del_index_array = NULL;
}
if (delete_uci_array) {
free(delete_uci_array);
delete_uci_array = NULL;
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<port_mapping>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<src_dport/>
<dest_ip/>
<proto/>
<enabled>
</entry_index>
...
</entry_list>
</port_mapping>
</firewall>
Note : add "option fw_type mapping/trigger" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
int fw_get_port_mapping_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
void *tb_port_mapping = NULL;
void *tb_entry_list = NULL;
void *tb_entry_one = NULL;
int index = 1;
char index_buf[10] = { 0 };
UNUSESET(method);
UNUSESET(obj);
UNUSESET(msg);
FW_DBG("enter");
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (!strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (p) {
tb_port_mapping = blobmsg_open_table(&fw_buf, "port_mapping");
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "redirect") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "mapping")) {
FW_DBG("fw_type is %s", opt_val);
if (!tb_entry_list) {
tb_entry_list = blobmsg_open_table(&fw_buf, "entry_list");
}
memset(index_buf, 0, 10);
snprintf(index_buf, 10, "entry_%d", index++);
FW_DBG("get one port_fw mapping %s", index_buf);
tb_entry_one = blobmsg_open_table(&fw_buf, index_buf);
/*start time */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "start_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "start_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "start_time", "none");
}
/*stop time */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "stop_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "stop_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "stop_time", "none");
}
/*src dport */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "src_dport");
if (opt_val) {
blobmsg_add_string(&fw_buf, "src_dport", opt_val);
} else {
blobmsg_add_string(&fw_buf, "src_dport", "none");
}
/*dest ip */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dest_ip");
if (opt_val) {
blobmsg_add_string(&fw_buf, "dest_ip", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dest_ip", "none");
}
/*proto; tcp,udp,tcpudp,udplite,icmp,esp,ah,sctp */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "proto");
if (opt_val) {
blobmsg_add_string(&fw_buf, "proto", opt_val);
} else {
blobmsg_add_string(&fw_buf, "proto", "none");
}
/*enabled */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "enabled");
if (opt_val) {
blobmsg_add_string(&fw_buf, "enabled", opt_val);
} else {
blobmsg_add_string(&fw_buf, "enabled", "1");
}
blobmsg_close_table(&fw_buf, tb_entry_one);
}
}
}
if (tb_entry_list) {
blobmsg_close_table(&fw_buf, tb_entry_list);
}
blobmsg_close_table(&fw_buf, tb_port_mapping);
} else {
blobmsg_add_string(&fw_buf, "disable", "1");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<port_mapping>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<src_dport/>
<dest_ip/>
<proto/>
</entry_index>
...
</entry_list>
</port_mapping>
</firewall>
Note : add "option fw_type mapping/trigger" under "config rule" to
distinguish between IP filter and mac filter
================================================*/
enum {
ADD_PORT_MAPPING_ENTRY,
EDIT_PORT_MAPPING_ENTRY,
};
enum {
MAPPING_START_TIME,
MAPPING_STOP_TIME,
MAPPING_SRC_DPORT,
MAPPING_DEST_IP,
MAPPING_PROTO,
MAPPING_ENABLED,
};
static const struct blobmsg_policy port_mapping_entry_pol[] = {
[MAPPING_START_TIME] = {
.name = "start_time",
.type = BLOBMSG_TYPE_STRING,
},
[MAPPING_STOP_TIME] = {
.name = "stop_time",
.type = BLOBMSG_TYPE_STRING,
},
[MAPPING_SRC_DPORT] = {
.name = "src_dport",
.type = BLOBMSG_TYPE_STRING,
},
[MAPPING_DEST_IP] = {
.name = "dest_ip",
.type = BLOBMSG_TYPE_STRING,
},
[MAPPING_PROTO] = {
.name = "proto",
.type = BLOBMSG_TYPE_STRING,
},
[MAPPING_ENABLED] = {
.name = "enabled",
.type = BLOBMSG_TYPE_STRING,
},
};
enum {
PORT_MAPPING_ENTRY_LIST,
};
static const struct blobmsg_policy fw_set_port_mapping_pol[] = {
[PORT_MAPPING_ENTRY_LIST] = {
.name = "entry_list",
.type = BLOBMSG_TYPE_TABLE,
},
};
static int fw_set_port_mapping_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg, long type)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
int ret_val = 0;
struct uci_ptr ptr;
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
int edit_index = 0;
int index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
struct blob_attr *port_mapping_attr[ARRAY_SIZE(fw_set_port_mapping_pol)];
struct blob_attr *entry_attr[ARRAY_SIZE(port_mapping_entry_pol)];
struct blob_attr *attr_head = NULL;
int attr_len = 0;
UNUSESET(method);
UNUSESET(obj);
FW_DBG("enter");
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[PORT_MAPPING]) {
goto EXIT;
}
if (blobmsg_parse
(fw_set_port_mapping_pol, ARRAY_SIZE(fw_set_port_mapping_pol), port_mapping_attr,
blobmsg_data(fw_setting_attr[PORT_MAPPING]), blobmsg_data_len(fw_setting_attr[PORT_MAPPING])) != 0) {
FW_DBG("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!port_mapping_attr[PORT_MAPPING_ENTRY_LIST]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
/*add new port mapping entry */
if (port_mapping_attr[PORT_MAPPING_ENTRY_LIST]) {
FW_DBG("add new port mapping");
attr_head = blobmsg_data(port_mapping_attr[PORT_MAPPING_ENTRY_LIST]);
attr_len = blobmsg_data_len(port_mapping_attr[PORT_MAPPING_ENTRY_LIST]);
__blob_for_each_attr(attr, attr_head, attr_len) {
hdr = blob_data(attr);
/*name as entry_index,entry_1, entry_2,eg. */
if (hdr->name) {
FW_DBG("add new ipfiter -- %s", hdr->name);
}
if (!strstr((char *)hdr->name, "entry")) {
continue;
}
if (type == EDIT_PORT_MAPPING_ENTRY) {
if (sscanf((char *)hdr->name, "%*5s_%d", &edit_index) == 1) {
FW_DBG("get edit index -- %d", edit_index);
} else {
FW_DBG("get edit index fail");
ret_val = 1;
goto EXIT;
}
}
/*type should be table */
if (blob_id(attr) != BLOBMSG_TYPE_TABLE) {
continue;
}
FW_DBG("GOT ONE NEW ENTRY");
if (blobmsg_parse
(port_mapping_entry_pol, ARRAY_SIZE(port_mapping_entry_pol), entry_attr, blobmsg_data(attr),
blobmsg_data_len(attr)) == 0) {
if (type == ADD_PORT_MAPPING_ENTRY) {
/*add one section with type :rule */
uci_add_section(local_ctx, p, "redirect", &uci_sec);
} else if (type == EDIT_PORT_MAPPING_ENTRY) {
index = 0;
/*find the rule */
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "redirect")) {
opt_val =
uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "mapping")) {
index++;
if (index == edit_index) {
FW_DBG("find edit index %d", index);
break;
}
}
}
}
}
if (uci_sec) {
FW_DBG("uci_sec OK!");
if (entry_attr[MAPPING_START_TIME]) {
FW_DBG("start_time is %s",
blobmsg_get_string(entry_attr[MAPPING_START_TIME]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "start_time";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_START_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_STOP_TIME]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "stop_time";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_STOP_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_SRC_DPORT]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src_dport";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_SRC_DPORT]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_DEST_IP]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest_ip";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_DEST_IP]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_PROTO]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "proto";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_PROTO]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_ENABLED]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_ENABLED]);
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "ui_enabled";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_ENABLED]);
uci_set(local_ctx, &ptr);
}
if (type == ADD_PORT_MAPPING_ENTRY) {
/*add fw type */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "fw_type";
ptr.value = "mapping";
uci_set(local_ctx, &ptr);
/*add src */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "src";
ptr.value = "wan";
uci_set(local_ctx, &ptr);
/*add dest */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dest";
ptr.value = "lan";
uci_set(local_ctx, &ptr);
}
} else {
FW_DBG("uci_sec is NULL");
}
}
}
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
FW_DBG("ret_val : %d", ret_val);
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
int fw_add_port_mapping_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_port_mapping_cb(ctx, obj, req, method, msg, ADD_PORT_MAPPING_ENTRY);
}
int fw_update_port_mapping_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_port_mapping_cb(ctx, obj, req, method, msg, EDIT_PORT_MAPPING_ENTRY);
}
/*================================================
<firewall>
<del_port_mapping_index>
</firewall>
seperate by ','
================================================*/
int fw_delete_port_mapping_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
int ret_val = 0;
struct uci_section **delete_uci_array = NULL;
int delete_num = 0;
char *begin = NULL;
char *end = NULL;
int *del_index_array = NULL;
char tmp_buf[5] = { 0 };
int cur_index = 0;
int tmp_index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DELETE_PORT_MAPPING]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
FW_DBG("delete index is %s", blobmsg_get_string(fw_setting_attr[DELETE_PORT_MAPPING]));
if (fw_setting_attr[DELETE_PORT_MAPPING]) {
begin = blobmsg_get_string(fw_setting_attr[DELETE_PORT_MAPPING]);
/*to get the number of delete index */
while ((begin = strchr(begin, ','))) {
delete_num++;
begin++;
}
FW_DBG(" delete total is %d", delete_num);
if (delete_num == 0) {
ret_val = 2;
goto EXIT;
}
/*malloc memory */
delete_uci_array = (struct uci_section **)malloc(delete_num * sizeof(struct uci_section *));
memset(delete_uci_array, 0, delete_num * sizeof(struct uci_section *));
del_index_array = (int *)malloc(delete_num * sizeof(int));
memset(del_index_array, 0, delete_num * sizeof(int));
/*get the index, storing into del_index_array */
cur_index = 0;
begin = blobmsg_get_string(fw_setting_attr[DELETE_PORT_MAPPING]);
while ((end = strchr(begin, ','))) {
memset(tmp_buf, 0, 5);
if (end - begin < 5) {
memcpy(tmp_buf, begin, end - begin);
} else {
continue;
}
if (cur_index > delete_num) {
break;
}
del_index_array[cur_index++] = atoi(tmp_buf);
begin = end + 1;
}
/*Print the delete index */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
FW_DBG("delete index %d", del_index_array[tmp_index]);
}
/*travel the sections ,and storing the deleting uci_sec to delete_uci_array */
cur_index = 0;
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "redirect") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "mapping")) {
cur_index++;
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
if (del_index_array[tmp_index] == 0) {
continue;
}
if (cur_index == del_index_array[tmp_index]) {
FW_DBG("find uci_sec with index %d", cur_index);
delete_uci_array[tmp_index] = uci_sec;
break;
}
}
}
}
}
}
/*delete the section */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = delete_uci_array[tmp_index];
uci_delete(local_ctx, &ptr);
}
EXIT:
if (del_index_array) {
free(del_index_array);
del_index_array = NULL;
}
if (delete_uci_array) {
free(delete_uci_array);
delete_uci_array = NULL;
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<dmz>
<entry_list>
<entry_index>
<dest_ip/>
</entry_index>
...
</entry_list>
</dmz>
</firewall>
Note : add "option fw_type mapping/trigger/dmz" under "config redirect"
================================================*/
int fw_get_dmz_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
UNUSESET(method);
UNUSESET(obj);
UNUSESET(msg);
FW_DBG("enter");
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (p) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "redirect") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
FW_DBG("fw_type is %s", opt_val);
/*dest ip */
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dest_ip");
if (opt_val) {
blobmsg_add_string(&fw_buf, "dmz_dest_ip", opt_val);
} else {
blobmsg_add_string(&fw_buf, "dmz_dest_ip", "none");
}
break;
}
}
}
} else {
blobmsg_add_string(&fw_buf, "disable", "1");
}
if (tb_fw) {
blobmsg_close_table(&fw_buf, tb_fw);
}
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<dmz>
<entry_list>
<entry_index>
<dest_ip/>
</entry_index>
...
</entry_list>
</dmz>
</firewall>
Note : add "option fw_type mapping/trigger/dmz" under "config redirect"
================================================*/
enum {
ADD_DMZ_ENTRY,
EDIT_DMZ_ENTRY,
};
static int fw_set_dmz_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg, long type)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
struct uci_section *uci_dmz = NULL;
struct uci_section *uci_rule_sec = NULL;
const char *opt_val = NULL;
const char *opt_val_2 = NULL;
void *tb_fw = NULL;
int ret_val = 0;
struct uci_ptr ptr;
char *malloc_ptr = NULL;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
UNUSESET(method);
UNUSESET(obj);
FW_DBG("enter");
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DMZ_HOST]) {
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
/*add new ipfilter entry */
if (fw_setting_attr[DMZ_HOST]) {
if (type == ADD_DMZ_ENTRY) {
/*add one section with type :rule */
uci_add_section(local_ctx, p, "redirect", &uci_dmz);
} else if (type == EDIT_DMZ_ENTRY) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "redirect")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
opt_val_2 = uci_lookup_option_string(local_ctx, uci_sec, "dest_ip");
uci_dmz = uci_sec;
FW_DBG("find the edit redirect section");
}
}
if (opt_val_2 && !strcmp(uci_sec->type, "rule")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "src_ip");
if (opt_val && !strcmp(opt_val_2, opt_val)) {
FW_DBG("find the dmz rule");
uci_rule_sec = uci_sec;
}
}
}
}
}
if (uci_dmz) {
if (fw_setting_attr[DMZ_HOST]) {
FW_DBG("DMZ_DEST_IP is %s", blobmsg_get_string(fw_setting_attr[DMZ_HOST]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz;
ptr.option = "dest_ip";
ptr.value = blobmsg_get_string(fw_setting_attr[DMZ_HOST]);
uci_set(local_ctx, &ptr);
if (type == ADD_PORT_MAPPING_ENTRY) {
/*add fw type */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz;
ptr.option = "fw_type";
ptr.value = "dmz";
uci_set(local_ctx, &ptr);
/*add src */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz;
ptr.option = "src";
ptr.value = "wan";
uci_set(local_ctx, &ptr);
/*add dest */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz;
ptr.option = "proto";
ptr.value = "all";
uci_set(local_ctx, &ptr);
/*add enabled */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz;
ptr.option = "enabled";
ptr.value = "1";
uci_set(local_ctx, &ptr);
/*add another rule to block this ip to access anthor IP in lan */
uci_add_section(local_ctx, p, "rule", &uci_rule_sec); /*need rule to block this IP to another client in lan */
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "src";
ptr.value = "lan";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "dest";
ptr.value = "lan";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "src_ip";
ptr.value = blobmsg_get_string(fw_setting_attr[DMZ_HOST]);
uci_set(local_ctx, &ptr);
malloc_ptr = malloc(strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5);
if (malloc_ptr) {
memset(malloc_ptr, 0,
strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5);
snprintf(malloc_ptr,
strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5,
"!%s", blobmsg_get_string(fw_setting_attr[DMZ_HOST]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "dest_ip";
ptr.value = malloc_ptr;
uci_set(local_ctx, &ptr);
free(malloc_ptr);
malloc_ptr = NULL;
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "proto";
ptr.value = "all";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "target";
ptr.value = "reject";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "filter_type";
ptr.value = "dmz";
uci_set(local_ctx, &ptr);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "enabled";
ptr.value = "1";
uci_set(local_ctx, &ptr);
} else if (type == EDIT_PORT_MAPPING_ENTRY) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "src_ip";
ptr.value = blobmsg_get_string(fw_setting_attr[DMZ_HOST]);
uci_set(local_ctx, &ptr);
malloc_ptr = malloc(strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5);
if (malloc_ptr) {
memset(malloc_ptr, 0,
strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5);
snprintf(malloc_ptr,
strlen(blobmsg_get_string(fw_setting_attr[DMZ_HOST])) + 5,
"!%s", blobmsg_get_string(fw_setting_attr[DMZ_HOST]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_rule_sec;
ptr.option = "dest_ip";
ptr.value = malloc_ptr;
uci_set(local_ctx, &ptr);
free(malloc_ptr);
malloc_ptr = NULL;
}
}
}
}
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
int fw_add_dmz_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_dmz_cb(ctx, obj, req, method, msg, ADD_DMZ_ENTRY);
}
int fw_edit_dmz_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_dmz_cb(ctx, obj, req, method, msg, EDIT_DMZ_ENTRY);
}
/*================================================
<firewall>
<del_port_mapping_index>
</firewall>
seperate by ','
================================================*/
int fw_delete_dmz_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
struct uci_section *uci_dmz_sec = NULL;
const char *opt_val = NULL;
const char *opt_val_2 = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
int ret_val = 0;
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
UNUSESET(msg);
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
if (local_ctx) {
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "redirect") == 0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "fw_type");
if (opt_val && !strcmp(opt_val, "dmz")) {
uci_dmz_sec = uci_sec;
break;
}
}
}
/*delete the section */
if (uci_dmz_sec) {
opt_val = uci_lookup_option_string(local_ctx, uci_dmz_sec, "dest_ip");
/*delete the rule */
if (opt_val) {
FW_DBG("going to delet the rule--filter_type--dmz with ip: %s", opt_val);
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "rule") == 0) {
opt_val_2 = uci_lookup_option_string(local_ctx, uci_sec, "filter_type");
if (opt_val_2 && !strcmp(opt_val_2, "dmz")) {
opt_val_2 = uci_lookup_option_string(local_ctx, uci_sec, "src_ip");
if (opt_val_2) {
FW_DBG("rule->dmz->src_ip : %s", opt_val_2);
}
if (opt_val_2 && !strcmp(opt_val, opt_val_2)) {
FW_DBG("find the rule--filter_type--dmz with: %s", opt_val_2);
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
uci_delete(local_ctx, &ptr);
break;
}
}
}
}
}
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_dmz_sec;
uci_delete(local_ctx, &ptr);
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/etc/init.d/firewall restart");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return 0;
}
/*================================================
<firewall>
<dn_filter>
<entry_list>
<entry_index>
<start_time/>
<stop_time/>
<domain_name/>
<enabled/>
</entry_index>
...
</entry_list>
</dn_filter>
</firewall>
================================================*/
int fw_get_dns_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
void *tb_dn_filter = NULL;
void *tb_entry_list = NULL;
int index = 1;
char index_buf[10] = { 0 };
void *tb_entry_one = NULL;
UNUSESET(method);
UNUSESET(obj);
UNUSESET(msg);
FW_DBG("enter");
/*load /etc/config/dhcp */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (p) {
tb_dn_filter = blobmsg_open_table(&fw_buf, "dn_filter");
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "dnsblacklist") == 0) {
FW_DBG("get one blacklist");
if (!tb_entry_list) {
tb_entry_list = blobmsg_open_table(&fw_buf, "entry_list");
}
memset(index_buf, 0, 10);
snprintf(index_buf, 10, "entry_%d", index++);
FW_DBG("get one port_fw mapping %s", index_buf);
tb_entry_one = blobmsg_open_table(&fw_buf, index_buf);
if (tb_entry_one) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "start_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "start_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "start_time", "00:00");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "stop_time");
if (opt_val) {
blobmsg_add_string(&fw_buf, "stop_time", opt_val);
} else {
blobmsg_add_string(&fw_buf, "stop_time", "00:00");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "domain_name");
if (opt_val) {
blobmsg_add_string(&fw_buf, "domain_name", opt_val);
} else {
blobmsg_add_string(&fw_buf, "domain_name", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "enabled");
if (opt_val) {
blobmsg_add_string(&fw_buf, "enabled", opt_val);
} else {
blobmsg_add_string(&fw_buf, "enabled", "NA");
}
blobmsg_close_table(&fw_buf, tb_entry_one);
}
}
}
if (tb_entry_list) {
blobmsg_close_table(&fw_buf, tb_entry_list);
}
} else {
blobmsg_add_string(&fw_buf, "dn_filter_disable", "1");
}
if (tb_dn_filter) {
blobmsg_close_table(&fw_buf, tb_dn_filter);
}
if (tb_fw) {
blobmsg_close_table(&fw_buf, tb_fw);
}
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
return 0;
FW_DBG("leave");
}
enum {
ADD_DNS_FILTER_ENTRY,
EDIT_DNS_FILTER_ENTRY,
};
enum {
DNS_START_TIME,
DNS_STOP_TIME,
DNS_DOMAIN_NAME,
DNS_ENABLED,
};
const struct blobmsg_policy dns_filter_entry_pol[] = {
[DNS_START_TIME] = {
.name = "start_time",
.type = BLOBMSG_TYPE_STRING,
},
[DNS_STOP_TIME] = {
.name = "stop_time",
.type = BLOBMSG_TYPE_STRING,
},
[DNS_DOMAIN_NAME] = {
.name = "domain_name",
.type = BLOBMSG_TYPE_STRING,
},
[DNS_ENABLED] = {
.name = "enabled",
.type = BLOBMSG_TYPE_STRING,
},
};
enum {
DNS_FILTER_ENTRY_LIST,
};
const struct blobmsg_policy fw_set_dns_filter_pol[] = {
[DNS_FILTER_ENTRY_LIST] = {
.name = "entry_list",
.type = BLOBMSG_TYPE_TABLE,
},
};
static int fw_set_dns_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg, int type)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
void *tb_fw = NULL;
int ret_val = 0;
struct uci_ptr ptr;
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
int edit_index = 0;
int index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
struct blob_attr *dns_filter_attr[ARRAY_SIZE(fw_set_dns_filter_pol)];
struct blob_attr *entry_attr[ARRAY_SIZE(dns_filter_entry_pol)];
struct blob_attr *attr_head = NULL;
int attr_len = 0;
int dns_filter_enable = 0;
const char *opt_val = NULL;
UNUSESET(method);
UNUSESET(obj);
FW_DBG("enter");
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DN_FILTER]) {
goto EXIT;
}
if (blobmsg_parse
(fw_set_dns_filter_pol, ARRAY_SIZE(fw_set_dns_filter_pol), dns_filter_attr,
blobmsg_data(fw_setting_attr[DN_FILTER]), blobmsg_data_len(fw_setting_attr[DN_FILTER])) != 0) {
FW_DBG("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!dns_filter_attr[DNS_FILTER_ENTRY_LIST]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
if (fw_setting_attr[DN_FILTER_DISABLE]) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "defaults")) {
break;
}
}
FW_DBG("dns disabe is %s", blobmsg_get_string(fw_setting_attr[DN_FILTER_DISABLE]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "dn_filter_disable";
ptr.value = blobmsg_get_string(fw_setting_attr[DN_FILTER_DISABLE]);
uci_set(local_ctx, &ptr);
if (strcmp(blobmsg_get_string(fw_setting_attr[DN_FILTER_DISABLE]), "0") == 0) {
dns_filter_enable = 1;
}
}
else{
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "defaults")==0) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dn_filter_disable");
if (opt_val) {
FW_DBG("dn_filter_disable string %s", opt_val);
if (strcmp(opt_val, "0") == 0){
dns_filter_enable = 1;
}else{
dns_filter_enable = 0;
}
} else {
dns_filter_enable = 0;
}
FW_DBG("dn_filter_disable is %d", dns_filter_enable);
break;
}
}
}
if (dns_filter_attr[DNS_FILTER_ENTRY_LIST]) {
FW_DBG("add new dns filter");
attr_head = blobmsg_data(dns_filter_attr[DNS_FILTER_ENTRY_LIST]);
attr_len = blobmsg_data_len(dns_filter_attr[DNS_FILTER_ENTRY_LIST]);
__blob_for_each_attr(attr, attr_head, attr_len) {
hdr = blob_data(attr);
/*name as entry_index,entry_1, entry_2,eg. */
if (hdr->name) {
FW_DBG("add new ipfiter -- %s", hdr->name);
}
if (!strstr((char *)hdr->name, "entry")) {
continue;
}
if (type == EDIT_DNS_FILTER_ENTRY) {
if (sscanf((char *)hdr->name, "%*5s_%d", &edit_index) == 1) {
FW_DBG("get edit index -- %d", edit_index);
} else {
FW_DBG("get edit index fail");
ret_val = 1;
goto EXIT;
}
}
/*type should be table */
if (blob_id(attr) != BLOBMSG_TYPE_TABLE) {
continue;
}
FW_DBG("GOT ONE NEW ENTRY");
if (blobmsg_parse
(dns_filter_entry_pol, ARRAY_SIZE(dns_filter_entry_pol), entry_attr, blobmsg_data(attr),
blobmsg_data_len(attr)) == 0) {
if (type == ADD_DNS_FILTER_ENTRY) {
/*add one section with type :dnsbacklist */
uci_add_section(local_ctx, p, "dnsblacklist", &uci_sec);
} else if (type == EDIT_DNS_FILTER_ENTRY) {
index = 0;
/*find the rule */
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "dnsblacklist")) {
index++;
if (index == edit_index) {
FW_DBG("find edit index %d", index);
break;
}
}
}
}
if (uci_sec) {
FW_DBG("uci_sec OK!");
if (entry_attr[DNS_START_TIME]) {
FW_DBG("start_time is %s",
blobmsg_get_string(entry_attr[DNS_START_TIME]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "start_time";
ptr.value = blobmsg_get_string(entry_attr[DNS_START_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[DNS_STOP_TIME]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "stop_time";
ptr.value = blobmsg_get_string(entry_attr[DNS_STOP_TIME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[DNS_DOMAIN_NAME]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "domain_name";
ptr.value = blobmsg_get_string(entry_attr[DNS_DOMAIN_NAME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[DNS_ENABLED]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
ptr.value = blobmsg_get_string(entry_attr[DNS_ENABLED]);
uci_set(local_ctx, &ptr);
}
} else {
FW_DBG("uci_sec is NULL");
}
}
}
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
if (dns_filter_enable == 1) {
FW_DBG("exec fw_ui_transfer.sh ");
fw_system("/lib/router_fw/fw_ui_transfer.sh DN_RESET");
//fw_system("/etc/init.d/dnsmasq restart");
}
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return ret_val;
}
int fw_add_dns_filter_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_dns_filter_info_cb(ctx, obj, req, method, msg, ADD_DNS_FILTER_ENTRY);
}
int fw_update_dns_filter_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_dns_filter_info_cb(ctx, obj, req, method, msg, EDIT_DNS_FILTER_ENTRY);
}
int fw_delete_dns_filter_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
int ret_val = 0;
struct uci_section **delete_uci_array = NULL;
int delete_num = 0;
char *begin = NULL;
char *end = NULL;
int *del_index_array = NULL;
char tmp_buf[5] = { 0 };
int cur_index = 0;
int tmp_index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
int dns_filter_enable = 0;
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_DBG("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DELETE_DNS_ENTRY]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
FW_DBG("delete index is %s", blobmsg_get_string(fw_setting_attr[DELETE_DNS_ENTRY]));
if (fw_setting_attr[DELETE_DNS_ENTRY]) {
begin = blobmsg_get_string(fw_setting_attr[DELETE_DNS_ENTRY]);
/*to get the number of delete index */
while ((begin = strchr(begin, ','))) {
delete_num++;
begin++;
}
FW_DBG(" delete total is %d", delete_num);
if (delete_num == 0) {
ret_val = 2;
goto EXIT;
}
/*malloc memory */
delete_uci_array = (struct uci_section **)malloc(delete_num * sizeof(struct uci_section *));
memset(delete_uci_array, 0, delete_num * sizeof(struct uci_section *));
del_index_array = (int *)malloc(delete_num * sizeof(int));
memset(del_index_array, 0, delete_num * sizeof(int));
/*get the index, storing into del_index_array */
cur_index = 0;
begin = blobmsg_get_string(fw_setting_attr[DELETE_DNS_ENTRY]);
while ((end = strchr(begin, ','))) {
memset(tmp_buf, 0, 5);
if (end - begin < 5) {
memcpy(tmp_buf, begin, end - begin);
} else {
continue;
}
if (cur_index > delete_num) {
break;
}
del_index_array[cur_index++] = atoi(tmp_buf);
begin = end + 1;
}
/*Print the delete index */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
FW_DBG("delete index %d", del_index_array[tmp_index]);
}
/*travel the sections ,and storing the deleting uci_sec to delete_uci_array */
cur_index = 0;
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "dnsblacklist") == 0) {
cur_index++;
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
if (del_index_array[tmp_index] == 0) {
continue;
}
if (cur_index == del_index_array[tmp_index]) {
FW_DBG("find uci_sec with index %d", cur_index);
delete_uci_array[tmp_index] = uci_sec;
break;
}
}
}
}
}
/*delete the section */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = delete_uci_array[tmp_index];
uci_delete(local_ctx, &ptr);
}
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "defaults")) {
break;
}
}
if (uci_sec) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "dn_filter_disable");
if (opt_val && strcmp(opt_val, "0") == 0) {
dns_filter_enable = 1;
}
}
EXIT:
if (del_index_array) {
free(del_index_array);
del_index_array = NULL;
}
if (delete_uci_array) {
free(delete_uci_array);
delete_uci_array = NULL;
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
if (dns_filter_enable == 1) {
fw_system("/lib/router_fw/fw_ui_transfer.sh DN_RESET");
//fw_system("/etc/init.d/dnsmasq restart");
}
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return ret_val;
}
/*================================================
<firewall>
<port_trigger>
<entry_list>
<entry_index>
<rule_name/>
<trigger_proto/>
<out_port/>
<in_port/>
<enabled/>
</entry_index>
...
</entry_list>
</port_trigger>
</firewall>
================================================*/
int fw_get_port_trigger_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
const char *opt_val = NULL;
void *tb_fw = NULL;
void *tb_port_trigger = NULL;
void *tb_entry_list = NULL;
int index = 1;
char index_buf[10] = { 0 };
void *tb_entry_one = NULL;
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
UNUSESET(msg);
/*load /etc/config/dhcp */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (tb_fw) {
tb_port_trigger = blobmsg_open_table(&fw_buf, "port_trigger");
if (tb_port_trigger) {
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "port_trigger_rule") == 0) {
FW_DBG("get one port_trigger entry");
if (!tb_entry_list) {
tb_entry_list = blobmsg_open_table(&fw_buf, "entry_list");
}
memset(index_buf, 0, 10);
snprintf(index_buf, 10, "entry_%d", index++);
FW_DBG("get one port_trigger %s", index_buf);
tb_entry_one = blobmsg_open_table(&fw_buf, index_buf);
if (tb_entry_one) {
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "rule_name");
if (opt_val) {
blobmsg_add_string(&fw_buf, "rule_name", opt_val);
} else {
blobmsg_add_string(&fw_buf, "rule_name", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "out_proto");
if (opt_val) {
blobmsg_add_string(&fw_buf, "out_proto", opt_val);
} else {
blobmsg_add_string(&fw_buf, "out_proto", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "in_proto");
if (opt_val) {
blobmsg_add_string(&fw_buf, "in_proto", opt_val);
} else {
blobmsg_add_string(&fw_buf, "in_proto", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "out_port");
if (opt_val) {
blobmsg_add_string(&fw_buf, "out_port", opt_val);
} else {
blobmsg_add_string(&fw_buf, "out_port", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "in_port");
if (opt_val) {
blobmsg_add_string(&fw_buf, "in_port", opt_val);
} else {
blobmsg_add_string(&fw_buf, "in_port", "NA");
}
opt_val = uci_lookup_option_string(local_ctx, uci_sec, "enabled");
if (opt_val) {
blobmsg_add_string(&fw_buf, "enabled", opt_val);
} else {
blobmsg_add_string(&fw_buf, "enabled", "NA");
}
blobmsg_close_table(&fw_buf, tb_entry_one);
}
}
}
if (tb_entry_list) {
blobmsg_close_table(&fw_buf, tb_entry_list);
}
blobmsg_close_table(&fw_buf, tb_port_trigger);
}
} else {
//blobmsg_add_string(&fw_buf, "disable", "1");
}
if (tb_fw) {
blobmsg_close_table(&fw_buf, tb_fw);
}
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
return 0;
FW_DBG("leave");
}
enum {
ADD_PORT_TRIGGER_ENTRY,
EDIT_PORT_TRIGGER_ENTRY,
};
enum {
TRIGGER_RULE_NAME,
TRIGGER_OUT_PORT,
TRIGGER_IN_PORT,
TRIGGER_OUT_PROTO,
TRIGGER_IN_PROTO,
TRIGGER_ENABLED,
};
static const struct blobmsg_policy port_trigger_entry_pol[] = {
[TRIGGER_RULE_NAME] = {
.name = "rule_name",
.type = BLOBMSG_TYPE_STRING,
},
[TRIGGER_OUT_PORT] = {
.name = "out_port",
.type = BLOBMSG_TYPE_STRING,
},
[TRIGGER_IN_PORT] = {
.name = "in_port",
.type = BLOBMSG_TYPE_STRING,
},
[TRIGGER_OUT_PROTO] = {
.name = "out_proto",
.type = BLOBMSG_TYPE_STRING,
},
[TRIGGER_IN_PROTO] = {
.name = "in_proto",
.type = BLOBMSG_TYPE_STRING,
},
[TRIGGER_ENABLED] = {
.name = "enabled",
.type = BLOBMSG_TYPE_STRING,
},
};
enum {
PORT_TRIGGER_ENTRY_LIST,
};
const struct blobmsg_policy fw_set_port_trigger_pol[] = {
[PORT_TRIGGER_ENTRY_LIST] = {
.name = "entry_list",
.type = BLOBMSG_TYPE_TABLE,
},
};
static int fw_set_port_trigger_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg, int type)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
void *tb_fw = NULL;
int ret_val = 0;
struct uci_ptr ptr;
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
int edit_index = 0;
int index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
struct blob_attr *port_trigger_attr[ARRAY_SIZE(fw_set_port_mapping_pol)];
struct blob_attr *entry_attr[ARRAY_SIZE(port_trigger_entry_pol)];
struct blob_attr *attr_head = NULL;
int attr_len = 0;
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[PORT_TRIGGER]) {
goto EXIT;
}
if (blobmsg_parse
(fw_set_port_trigger_pol, ARRAY_SIZE(fw_set_port_trigger_pol), port_trigger_attr,
blobmsg_data(fw_setting_attr[PORT_TRIGGER]), blobmsg_data_len(fw_setting_attr[PORT_TRIGGER])) != 0) {
FW_ERR("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!port_trigger_attr[PORT_TRIGGER_ENTRY_LIST]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = (struct uci_context *)uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
/*add new port trigger entry */
if (port_trigger_attr[PORT_MAPPING_ENTRY_LIST]) {
FW_DBG("add/edit new port trigger");
attr_head = blobmsg_data(port_trigger_attr[PORT_TRIGGER_ENTRY_LIST]);
attr_len = blobmsg_data_len(port_trigger_attr[PORT_TRIGGER_ENTRY_LIST]);
__blob_for_each_attr(attr, attr_head, attr_len) {
hdr = blob_data(attr);
/*name as entry_index,entry_1, entry_2,eg. */
if (hdr->name) {
FW_DBG("add new ipfiter -- %s", hdr->name);
}
if (!strstr((char *)hdr->name, "entry")) {
continue;
}
if (type == EDIT_PORT_TRIGGER_ENTRY) {
if (sscanf((char *)hdr->name, "%*5s_%d", &edit_index) == 1) {
FW_DBG("get edit index -- %d", edit_index);
} else {
FW_DBG("get edit index fail");
ret_val = 1;
goto EXIT;
}
}
/*type should be table */
if (blob_id(attr) != BLOBMSG_TYPE_TABLE) {
continue;
}
FW_DBG("GOT ONE NEW ENTRY");
if (blobmsg_parse
(port_trigger_entry_pol, ARRAY_SIZE(port_trigger_entry_pol), entry_attr, blobmsg_data(attr),
blobmsg_data_len(attr)) == 0) {
if (type == ADD_PORT_TRIGGER_ENTRY) {
/*add one section with type :port_trigger */
uci_add_section(local_ctx, p, "port_trigger_rule", &uci_sec);
} else if (type == EDIT_PORT_TRIGGER_ENTRY) {
index = 0;
/*find the rule */
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (!strcmp(uci_sec->type, "port_trigger_rule")) {
index++;
if (index == edit_index) {
FW_DBG("find edit index %d", index);
break;
}
}
}
}
if (uci_sec) {
FW_DBG("uci_sec OK!");
if (entry_attr[TRIGGER_RULE_NAME]) {
FW_DBG("TRIGGER_RULE_NAME is %s",
blobmsg_get_string(entry_attr[TRIGGER_RULE_NAME]));
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "rule_name";
ptr.value = blobmsg_get_string(entry_attr[TRIGGER_RULE_NAME]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[TRIGGER_OUT_PORT]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "out_port";
ptr.value = blobmsg_get_string(entry_attr[TRIGGER_OUT_PORT]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[TRIGGER_IN_PORT]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "in_port";
ptr.value = blobmsg_get_string(entry_attr[TRIGGER_IN_PORT]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[TRIGGER_OUT_PROTO]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "out_proto";
ptr.value = blobmsg_get_string(entry_attr[TRIGGER_OUT_PROTO]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[TRIGGER_IN_PROTO]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "in_proto";
ptr.value = blobmsg_get_string(entry_attr[TRIGGER_IN_PROTO]);
uci_set(local_ctx, &ptr);
}
if (entry_attr[MAPPING_ENABLED]) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = uci_sec;
ptr.option = "enabled";
ptr.value = blobmsg_get_string(entry_attr[MAPPING_ENABLED]);
uci_set(local_ctx, &ptr);
}
} else {
FW_DBG("uci_sec is NULL");
}
}
}
}
EXIT:
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
FW_DBG("ret_val : %d", ret_val);
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/lib/router_fw/fw_ui_transfer.sh PORT_TRIGGER_RESET");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return ret_val;
FW_DBG("leave");
}
int fw_add_port_trigger_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_port_trigger_info_cb(ctx, obj, req, method, msg, ADD_PORT_TRIGGER_ENTRY);
}
int fw_update_port_trigger_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
return fw_set_port_trigger_info_cb(ctx, obj, req, method, msg, EDIT_PORT_TRIGGER_ENTRY);
}
/*================================================
<firewall>
<del_port_trigger_index>
</firewall>
seperate by ','
================================================*/
int fw_delete_port_trigger_info_cb(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct blob_attr *msg)
{
struct uci_context *local_ctx = NULL;
struct uci_element *e = NULL;
struct uci_package *p = NULL;
struct uci_section *uci_sec = NULL;
void *tb_fw = NULL;
struct uci_ptr ptr;
int ret_val = 0;
struct uci_section **delete_uci_array = NULL;
int delete_num = 0;
char *begin = NULL;
char *end = NULL;
int *del_index_array = NULL;
char tmp_buf[5] = { 0 };
int cur_index = 0;
int tmp_index = 0;
struct blob_attr *fw_setting_attr[ARRAY_SIZE(fw_setting_pol)];
FW_DBG("enter");
UNUSESET(method);
UNUSESET(obj);
if (blobmsg_parse(fw_setting_pol, ARRAY_SIZE(fw_setting_pol), fw_setting_attr, blob_data(msg), blob_len(msg)) !=
0) {
FW_DBG("Parse failed\n");
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
if (!fw_setting_attr[DELETE_PORT_TRIGGER]) {
ret_val = UBUS_STATUS_INVALID_ARGUMENT;
goto EXIT;
}
/*load /etc/config/firewall */
local_ctx = uci_fw_ctx_get();
if (!local_ctx) {
assert(0);
}
FW_DBG("get uci ctx OK\r\n");
{
uci_foreach_element(&local_ctx->root, e) {
if (strcmp(e->name, FW_PACK) != 0)
continue;
p = uci_to_package(e); //have found
}
}
if (!p) {
uci_load(local_ctx, FW_PACK, &p);
}
if (!p) {
ret_val = UBUS_STATUS_NO_DATA;
goto EXIT;
}
FW_DBG("delete index is %s", blobmsg_get_string(fw_setting_attr[DELETE_PORT_TRIGGER]));
if (fw_setting_attr[DELETE_PORT_TRIGGER]) {
begin = blobmsg_get_string(fw_setting_attr[DELETE_PORT_TRIGGER]);
/*to get the number of delete index */
while ((begin = strchr(begin, ','))) {
delete_num++;
begin++;
}
FW_DBG(" delete total is %d", delete_num);
if (delete_num == 0) {
ret_val = 2;
goto EXIT;
}
/*malloc memory */
delete_uci_array = (struct uci_section **)malloc(delete_num * sizeof(struct uci_section *));
memset(delete_uci_array, 0, delete_num * sizeof(struct uci_section *));
del_index_array = (int *)malloc(delete_num * sizeof(int));
memset(del_index_array, 0, delete_num * sizeof(int));
/*get the index, storing into del_index_array */
cur_index = 0;
begin = blobmsg_get_string(fw_setting_attr[DELETE_PORT_TRIGGER]);
while ((end = strchr(begin, ','))) {
memset(tmp_buf, 0, 5);
if (end - begin < 5) {
memcpy(tmp_buf, begin, end - begin);
} else {
continue;
}
if (cur_index > delete_num) {
break;
}
del_index_array[cur_index++] = atoi(tmp_buf);
begin = end + 1;
}
/*Print the delete index */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
FW_DBG("delete index %d", del_index_array[tmp_index]);
}
/*travel the sections ,and storing the deleting uci_sec to delete_uci_array */
cur_index = 0;
uci_foreach_element(&p->sections, e) {
uci_sec = uci_to_section(e);
if (strcmp(uci_sec->type, "port_trigger_rule") == 0) {
cur_index++;
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
if (del_index_array[tmp_index] == 0) {
continue;
}
if (cur_index == del_index_array[tmp_index]) {
FW_DBG("find uci_sec with index %d", cur_index);
delete_uci_array[tmp_index] = uci_sec;
break;
}
}
}
}
}
/*delete the section */
for (tmp_index = 0; tmp_index < delete_num; tmp_index++) {
memset(&ptr, 0, sizeof(struct uci_ptr));
ptr.p = p;
ptr.s = delete_uci_array[tmp_index];
uci_delete(local_ctx, &ptr);
}
EXIT:
if (del_index_array) {
free(del_index_array);
del_index_array = NULL;
}
if (delete_uci_array) {
free(delete_uci_array);
delete_uci_array = NULL;
}
blobmsg_buf_init(&fw_buf);
tb_fw = blobmsg_open_table(&fw_buf, "firewall");
if (ret_val == 0) {
blobmsg_add_string(&fw_buf, "setting_response", "OK");
if (p) {
uci_commit(local_ctx, &p, false);
fw_system("/lib/router_fw/fw_ui_transfer.sh PORT_TRIGGER_RESET");
}
} else {
blobmsg_add_string(&fw_buf, "setting_response", "ERROR");
}
blobmsg_close_table(&fw_buf, tb_fw);
ubus_send_reply(ctx, req, fw_buf.head);
blob_buf_free(&fw_buf);
free_fw_uci_ctx();
FW_DBG("leave");
return ret_val;
}
#if 0
static struct ubus_context *fw_ubus_ctx = NULL;
static const struct ubus_method fw_methods[] = {
UBUS_METHOD_NOARG("fw_get_disable_info", fw_get_disable_info_cb),
UBUS_METHOD("fw_set_disable_info", fw_set_disable_cb, fw_setting_pol),
UBUS_METHOD_NOARG("fw_get_ip_filter_info", fw_get_ip_filter_info_cb),
UBUS_METHOD("set_ip_filter_default_pol", fw_set_add_ip_filter_info_cb, fw_setting_pol),
UBUS_METHOD("add_ip_filter_entry", fw_set_add_ip_filter_info_cb, fw_setting_pol),
UBUS_METHOD("edit_ip_filter_entry", fw_update_ip_filter_info_cb, fw_setting_pol),
UBUS_METHOD("delete_ip_filter_entry", fw_delete_ip_filter_info_cb, fw_setting_pol),
UBUS_METHOD_NOARG("fw_get_port_mapping_info", fw_get_port_mapping_cb),
UBUS_METHOD("add_port_mapping_entry", fw_add_port_mapping_info_cb, fw_setting_pol),
UBUS_METHOD("edit_port_mapping_entry", fw_update_port_mapping_info_cb, fw_setting_pol),
UBUS_METHOD("delete_port_mapping_entry", fw_delete_port_mapping_info_cb, fw_setting_pol),
UBUS_METHOD_NOARG("fw_get_dmz_info", fw_get_dmz_cb),
UBUS_METHOD("fw_add_dmz_entry", fw_add_dmz_cb, fw_setting_pol),
UBUS_METHOD("fw_edit_dmz_entry", fw_edit_dmz_cb, fw_setting_pol),
UBUS_METHOD_NOARG("delete_dmz", fw_delete_dmz_cb),
UBUS_METHOD_NOARG("fw_get_port_trigger_info", fw_get_port_trigger_info_cb),
UBUS_METHOD("add_port_trigger_entry", fw_add_port_trigger_info_cb, fw_setting_pol),
UBUS_METHOD("edit_port_trigger_entry", fw_update_port_trigger_info_cb, fw_setting_pol),
UBUS_METHOD("delete_port_trigger_entry", fw_delete_port_trigger_info_cb, fw_setting_pol),
UBUS_METHOD_NOARG("fw_get_dn_filter_info", fw_get_dns_filter_info_cb),
UBUS_METHOD("add_dn_filter_entry", fw_add_dns_filter_cb, fw_setting_pol),
UBUS_METHOD("edit_dn_filter_entry", fw_update_dns_filter_cb, fw_setting_pol),
UBUS_METHOD("delete_dn_filter_entry", fw_delete_dns_filter_info_cb, fw_setting_pol),
};
static struct ubus_object_type fw_object_type = UBUS_OBJECT_TYPE("firewall", fw_methods);
static struct ubus_object fw_service_object = {
.name = "firewall",
.type = &fw_object_type,
.methods = fw_methods,
.n_methods = ARRAY_SIZE(fw_methods),
};
static void fw_server_main(void)
{
int ret;
FW_DBG("enter");
ret = ubus_add_object(fw_ubus_ctx, &fw_service_object);
if (ret)
fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
uloop_run();
}
int main(int argc, char **argv)
{
const char *ubus_socket = NULL;
int ch;
set_service_log_tag("router_fw");
prctl(PR_SET_NAME, "router_firewall");
while ((ch = getopt(argc, argv, "cs:")) != -1) {
switch (ch) {
case 's':
ubus_socket = optarg;
break;
default:
break;
}
}
argc -= optind;
argv += optind;
uloop_init();
signal(SIGPIPE, SIG_IGN);
fw_ubus_ctx = ubus_connect(ubus_socket);
if (!fw_ubus_ctx) {
fprintf(stderr, "Failed to connect to ubus\n");
return -1;
}
fw_system("/lib/router_fw/fw_ui_transfer.sh DN_RESET");
//fw_system("/lib/router_fw/fw_ui_transfer.sh PORT_TRIGGER_RESET");
ubus_add_uloop(fw_ubus_ctx);
fw_server_main();
ubus_free(fw_ubus_ctx);
uloop_done();
return 0;
}
#endif