From 59aa2a1f40ebee65e48c7fd5d28d6c2706e60145 Mon Sep 17 00:00:00 2001 From: Derry Date: Sun, 7 Mar 2021 08:33:24 -0800 Subject: [PATCH] Support time-based control --- .../luasrc/model/cbi/appfilter/appfilter.lua | 29 +++- open-app-filter/files/appfilter.config | 5 + open-app-filter/src/appfilter_config.c | 150 +++++++++++++++++- open-app-filter/src/appfilter_config.h | 18 ++- open-app-filter/src/appfilter_ubus.c | 14 -- open-app-filter/src/main.c | 39 ++++- 6 files changed, 234 insertions(+), 21 deletions(-) diff --git a/luci-app-oaf/luasrc/model/cbi/appfilter/appfilter.lua b/luci-app-oaf/luasrc/model/cbi/appfilter/appfilter.lua index 6fbb1f0..036e5c6 100755 --- a/luci-app-oaf/luasrc/model/cbi/appfilter/appfilter.lua +++ b/luci-app-oaf/luasrc/model/cbi/appfilter/appfilter.lua @@ -44,7 +44,27 @@ s.anonymous = true um = s:option(DummyValue, "rule_data") um.template="cbi/oaf_dvalue" + +s=m:section(TypedSection,"time",translate("时间控制")) s.anonymous = true +hv = s:option(Value, "start_time", translate("开始时间")) hv.default="00:00" +hv.optional=false +hv = s:option(Value, "end_time", translate("结束时间")) hv.default="23:59" +hv.optional=false days = s:option(MultiValue, "days", "", translate("")) +days.widget="checkbox" days.size=10 +days:value("0", "周日"); +days:value("1", "周一"); +days:value("2", "周二"); +days:value("3", "周三"); +days:value("4", "周四"); +days:value("5", "周五"); +days:value("6", "周六"); + --um.value =rule_count .. " " .. translate("Records").. " "..version + + + + + s = m:section(TypedSection, "appfilter", translate("App Filter Rules")) s.anonymous = true s.addremove = false @@ -102,10 +122,7 @@ if class_fd then end -s=m:section(TypedSection,"user",translate("Select users")) -s.anonymous = true -users = s:option(MultiValue, "users", "", translate("Select at least one user, otherwise it will take effect for all users")) -users.widget="checkbox" + function get_hostname_by_mac(dst_mac) leasefile="/tmp/dhcp.leases" @@ -135,6 +152,10 @@ function get_cmd_result(command) fd:close() return result end + +s=m:section(TypedSection,"user",translate("Select users")) +s.anonymous = true +users = s:option(MultiValue, "users", "", translate("Select at least one user, otherwise it will take effect for all users")) users.widget="checkbox" --users.widget="select" users.size=1 diff --git a/open-app-filter/files/appfilter.config b/open-app-filter/files/appfilter.config index 17fd458..8253a74 100755 --- a/open-app-filter/files/appfilter.config +++ b/open-app-filter/files/appfilter.config @@ -3,3 +3,8 @@ config global global config appfilter appfilter config feature feature + +config time 'time' + option end_time '23:59' + option days '0 1 2 3 4 5 6' + option start_time '00:00' diff --git a/open-app-filter/src/appfilter_config.c b/open-app-filter/src/appfilter_config.c index 64af121..d6aefc1 100755 --- a/open-app-filter/src/appfilter_config.c +++ b/open-app-filter/src/appfilter_config.c @@ -23,12 +23,45 @@ #include #include #include "appfilter_config.h" +#include app_name_info_t app_name_table[MAX_SUPPORT_APP_NUM]; int g_app_count = 0; int g_cur_class_num = 0; char CLASS_NAME_TABLE[MAX_APP_TYPE][MAX_CLASS_NAME_LEN]; +const char *config_path = "./config"; +static struct uci_context *uci_ctx = NULL; +static struct uci_package *uci_appfilter; +// +static struct uci_package * +config_init_package(const char *config) +{ + struct uci_context *ctx = uci_ctx; + struct uci_package *p = NULL; + + if (!ctx) { + printf("alloc context\n"); + ctx = uci_alloc_context(); + uci_ctx = ctx; + + ctx->flags &= ~UCI_FLAG_STRICT; + //if (config_path) + // uci_set_confdir(ctx, config_path); + + } else { + + printf("find context\n"); + p = uci_lookup_package(ctx, config); + if (p) + uci_unload(ctx, p); + } + + if (uci_load(ctx, config, &p)) + return NULL; + + return p; +} char *get_app_name_by_id(int id){ int i; for (i = 0;i < g_app_count; i++){ @@ -85,4 +118,119 @@ void init_app_class_name_table(void){ g_cur_class_num++; } fclose(fp); -} \ No newline at end of file +} +//00:00 9:1 +int check_time_valid(char *t) +{ + if (!t) + return 0; + if (strlen(t) < 3 || strlen(t) > 5 || (!strstr(t, ":"))) + return 0; + else + return 1; +} + +void dump_af_time(af_ctl_time_t *t){ + int i; + printf("---------dump af time-------------\n"); + printf("%d:%d ---->%d:%d\n", t->start.hour, t->start.min, + t->end.hour, t->end.min); + for (i = 0; i < 7; i++){ + printf("%d ", t->days[i]); + } + printf("\n"); +} +af_ctl_time_t *load_appfilter_ctl_time_config(void){ + int ret = 0; + af_ctl_time_t *t = NULL; + + appfilter_config_alloc(); + printf("load time \n"); + struct uci_section *time_sec = uci_lookup_section( + uci_ctx, uci_appfilter, "time"); + if (!time_sec){ + printf("get time section failed\n"); + return NULL; + } + t = malloc(sizeof(af_ctl_time_t)); + if (!t){ + return NULL; + } + memset(t, 0x0, sizeof(af_ctl_time_t)); + char *start_time_str = uci_lookup_option_string(uci_ctx, time_sec, "start_time"); + + if (check_time_valid(start_time_str)){ + sscanf(start_time_str, "%d:%d", &t->start.hour, &t->start.min); + } + else{ + printf("start time check failed\n"); + free(t); + t = NULL; + goto EXIT1; + } + char *end_time_str = uci_lookup_option_string(uci_ctx, time_sec, "end_time"); + + if (check_time_valid(end_time_str)){ + sscanf(end_time_str, "%d:%d", &t->end.hour, &t->end.min); + } + else{ + printf("end time check failed\n"); + free(t); + t = NULL; + goto EXIT2; + } + + char *days_str = uci_lookup_option_string(uci_ctx, time_sec, "days"); + + char *p = strtok(days_str, " "); + do{ + int day = atoi(p); + if (day >= 0 && day <= 6) + t->days[day] = 1; + else + ret = 0; + } + while(p = strtok(NULL, " ")); + + //printf("start:%s, end:%s, days:%s\n", start_time_str, end_time_str, + // days_str); +EXIT3: + if (days_str) + free(days_str); +EXIT2: + if (end_time_str) + free(end_time_str); +EXIT1: + if (start_time_str) + free(start_time_str); + appfilter_config_free(); + //if (t) + // dump_af_time(t); + printf("load af time............ok\n"); + return t; +} + +int appfilter_config_alloc(void){ + char *err; + uci_appfilter = config_init_package("appfilter"); + if (!uci_appfilter) { + uci_get_errorstr(uci_ctx, &err, NULL); + printf("Failed to load appfilter config (%s)\n", err); + free(err); + return -1; + } + + return 0; +} + +int appfilter_config_free(void){ + if (uci_appfilter){ + uci_unload(uci_ctx, uci_appfilter); + uci_appfilter = NULL; + } + if (uci_ctx){ + uci_free_context(uci_ctx); + uci_ctx = NULL; + } + +} diff --git a/open-app-filter/src/appfilter_config.h b/open-app-filter/src/appfilter_config.h index 1264958..6c07a46 100755 --- a/open-app-filter/src/appfilter_config.h +++ b/open-app-filter/src/appfilter_config.h @@ -27,6 +27,15 @@ extern int g_cur_class_num; extern int g_app_count; extern char CLASS_NAME_TABLE[MAX_APP_TYPE][MAX_CLASS_NAME_LEN]; +typedef struct af_time{ + int hour; + int min; +}af_time_t; +typedef struct af_ctl_time{ + af_time_t start; + af_time_t end; + int days[7]; +}af_ctl_time_t; typedef struct app_name_info{ int id; @@ -35,4 +44,11 @@ typedef struct app_name_info{ void init_app_name_table(void); void init_app_class_name_table(void); char *get_app_name_by_id(int id); -#endif \ No newline at end of file + +int appfilter_config_alloc(void); + +int appfilter_config_free(void); +af_ctl_time_t *load_appfilter_ctl_time_config(void); + + +#endif diff --git a/open-app-filter/src/appfilter_ubus.c b/open-app-filter/src/appfilter_ubus.c index c9e2809..0ff24fa 100755 --- a/open-app-filter/src/appfilter_ubus.c +++ b/open-app-filter/src/appfilter_ubus.c @@ -274,23 +274,19 @@ appfilter_handle_dev_list(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *msg) { int i, j; - printf("%s %d\n", __func__, __LINE__); struct json_object * root_obj = json_object_new_object(); struct json_object * dev_array = json_object_new_array(); - printf("%s %d\n", __func__, __LINE__); for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){ dev_node_t *node = dev_hash_table[i]; while(node){ - printf("add mac:%s\n", node->mac); struct json_object * dev_obj = json_object_new_object(); struct json_object * app_array = json_object_new_array(); app_visit_time_info_t top5_app_list[5]; memset(top5_app_list, 0x0, sizeof(top5_app_list)); update_top5_app(node, top5_app_list); - printf("22 add mac:%s\n", node->mac); for (j = 0; j < 5; j++){ if (top5_app_list[j].app_id == 0) break; @@ -300,7 +296,6 @@ appfilter_handle_dev_list(struct ubus_context *ctx, struct ubus_object *obj, json_object_array_add(app_array, app_obj); } - printf("333 add mac:%s\n", node->mac); json_object_object_add(dev_obj, "applist", app_array); json_object_object_add(dev_obj, "mac", json_object_new_string(node->mac)); char hostname[32] = {0}; @@ -313,19 +308,10 @@ appfilter_handle_dev_list(struct ubus_context *ctx, struct ubus_object *obj, } } json_object_object_add(root_obj, "devlist", dev_array); - printf("%s %d\n", __func__, __LINE__); blob_buf_init(&b, 0); - - printf("%s %d\n", __func__, __LINE__); blobmsg_add_object(&b, root_obj); - - printf("%s %d\n", __func__, __LINE__); ubus_send_reply(ctx, req, b.head); - - printf("%s %d\n", __func__, __LINE__); json_object_put(root_obj); - - printf("%s %d\n", __func__, __LINE__); return 0; } diff --git a/open-app-filter/src/main.c b/open-app-filter/src/main.c index 7b1f668..4712e39 100755 --- a/open-app-filter/src/main.c +++ b/open-app-filter/src/main.c @@ -29,11 +29,48 @@ #include "appfilter_netlink.h" #include "appfilter_ubus.h" #include "appfilter_config.h" +#include +void check_appfilter_enable(void){ + int enable = 1; + struct tm *t; + time_t tt; + time(&tt); + af_ctl_time_t *af_t = load_appfilter_ctl_time_config(); + if (!af_t){ + enable = 0; + goto EXIT; + } + + t = localtime(&tt); + if (af_t->days[t->tm_wday] != 1){ + printf("cur weekday not match"); + enable = 0; + goto EXIT; + } + if (af_t->start.hour <= af_t->end.hour){ + int cur_mins = t->tm_hour * 60 + t->tm_min; + if ((af_t->start.hour * 60 + af_t->start.min > cur_mins ) + || (cur_mins > af_t->end.hour * 60 + af_t->end.min)){ + enable = 0; + printf(" not match hour and min\n"); + } + } + else + enable = 0; +EXIT: + if (enable){ + system("echo 1 >/proc/sys/oaf/enable "); + } + else + system("echo 0 >/proc/sys/oaf/enable "); + free(af_t); +} void dev_list_timeout_handler(struct uloop_timeout *t){ dump_dev_list(); dump_dev_visit_list(); - uloop_timeout_set(t, 5000); + check_appfilter_enable(); + uloop_timeout_set(t, 10000); } struct uloop_timeout dev_tm={