This commit is contained in:
commit
1c783bce41
@ -49,6 +49,6 @@ Unzip thie OAF package and then install ipks in order
|
||||
- luci-i18n-oaf-zh-cn(Chinese Language Pack, optional)
|
||||
|
||||
### Notice
|
||||
If there is no version you need, you need to compile and generate it yourself, and I will release more architecture ipks later.
|
||||
If there is no version you need, you need to compile and generate it yourself, and I will release more architecture ipks later.
|
||||
|
||||
|
||||
|
@ -148,9 +148,15 @@
|
||||
name: "<%:Visit Time%>",
|
||||
type: 'pie',
|
||||
center: ['35%', '50%'],
|
||||
radius: ['40%', '65%'],
|
||||
radius: ['58%', '70%'],
|
||||
clockwise: false,
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 2,
|
||||
borderColor: "#fff",
|
||||
borderWidth: 1,
|
||||
},
|
||||
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
@ -249,9 +255,14 @@
|
||||
name: "<%:Visit Time%>",
|
||||
type: 'pie',
|
||||
center: ['35%', '50%'],
|
||||
radius: ['40%', '65%'],
|
||||
radius: ['58%', '70%'],
|
||||
clockwise: false,
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 2,
|
||||
borderColor: "#fff",
|
||||
borderWidth: 1,
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
|
@ -11,7 +11,8 @@ int af_test_mode = 0;
|
||||
// todo: rename af_log.c
|
||||
int g_oaf_enable __read_mostly = 0;
|
||||
int af_work_mode = AF_MODE_GATEWAY;
|
||||
int af_lan_ip = 0;
|
||||
unsigned int af_lan_ip = 0;
|
||||
unsigned int af_lan_mask = 0;
|
||||
/*
|
||||
cat /proc/sys/oaf/debug
|
||||
*/
|
||||
@ -47,9 +48,16 @@ static struct ctl_table oaf_table[] = {
|
||||
{
|
||||
.procname = "lan_ip",
|
||||
.data = &af_lan_ip,
|
||||
.maxlen = sizeof(int),
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0666,
|
||||
.proc_handler = proc_dointvec,
|
||||
.proc_handler = proc_douintvec,
|
||||
},
|
||||
{
|
||||
.procname = "lan_mask",
|
||||
.data = &af_lan_mask,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0666,
|
||||
.proc_handler = proc_douintvec,
|
||||
},
|
||||
{
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
extern int af_log_lvl;
|
||||
extern int af_test_mode;
|
||||
extern int af_work_mode;
|
||||
extern int af_lan_ip;
|
||||
extern unsigned int af_lan_ip;
|
||||
extern unsigned int af_lan_mask;
|
||||
#define LOG(level, fmt, ...) do { \
|
||||
if ((level) <= af_log_lvl) { \
|
||||
printk(fmt, ##__VA_ARGS__); \
|
||||
|
@ -473,6 +473,8 @@ int parse_flow_proto(struct sk_buff *skb, flow_info_t *flow)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#define MAX_HOST_LEN 32
|
||||
#define MIN_HOST_LEN 4
|
||||
|
||||
int dpi_https_proto(flow_info_t *flow)
|
||||
{
|
||||
@ -500,12 +502,14 @@ int dpi_https_proto(flow_info_t *flow)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (p[i] == 0x0 && p[i + 1] == 0x0 && p[i + 2] == 0x0 && p[i + 3] != 0x0)
|
||||
{
|
||||
// 2 bytes
|
||||
memcpy(&url_len, p + i + HTTPS_LEN_OFFSET, 2);
|
||||
if (ntohs(url_len) <= 0 || ntohs(url_len) > data_len)
|
||||
|
||||
if (ntohs(url_len) <= MIN_HOST_LEN || ntohs(url_len) > data_len || ntohs(url_len) > MAX_HOST_LEN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -887,7 +891,29 @@ void af_get_smac(struct sk_buff *skb, u_int8_t *smac){
|
||||
else
|
||||
memcpy(smac, &skb->cb[40], ETH_ALEN);
|
||||
}
|
||||
int is_ipv4_broadcast(uint32_t ip) {
|
||||
|
||||
return (ip & 0x00FFFFFF) == 0x00FFFFFF;
|
||||
}
|
||||
|
||||
int is_ipv4_multicast(uint32_t ip) {
|
||||
return (ip & 0xF0000000) == 0xE0000000;
|
||||
}
|
||||
int af_check_bcast_ip(flow_info_t *f)
|
||||
{
|
||||
|
||||
if (0 == f->src || 0 == f->dst)
|
||||
return 1;
|
||||
if (is_ipv4_broadcast(ntohl(f->src)) || is_ipv4_broadcast(ntohl(f->dst))){
|
||||
return 1;
|
||||
}
|
||||
if (is_ipv4_multicast(ntohl(f->src)) || is_ipv4_multicast(ntohl(f->dst))){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||
u_int32_t app_filter_hook_bypass_handle(struct sk_buff *skb, struct net_device *dev){
|
||||
flow_info_t flow;
|
||||
u_int8_t smac[ETH_ALEN];
|
||||
@ -896,16 +922,24 @@ u_int32_t app_filter_hook_bypass_handle(struct sk_buff *skb, struct net_device *
|
||||
if (!skb || !dev)
|
||||
return NF_ACCEPT;
|
||||
|
||||
if (0 == af_lan_ip || 0 == af_lan_mask)
|
||||
return NF_ACCEPT;
|
||||
if (dev->name && strstr(dev->name, "docker"))
|
||||
return NF_ACCEPT;
|
||||
|
||||
memset((char *)&flow, 0x0, sizeof(flow_info_t));
|
||||
if (parse_flow_proto(skb, &flow) < 0)
|
||||
return NF_ACCEPT;
|
||||
if (af_match_bcast_packet(&flow) || af_match_local_packet(&flow))
|
||||
return NF_ACCEPT;
|
||||
|
||||
|
||||
if (af_lan_ip == flow.src || af_lan_ip == flow.dst){
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
if (af_check_bcast_ip(&flow) || af_match_local_packet(&flow))
|
||||
return NF_ACCEPT;
|
||||
|
||||
if ((flow.src & af_lan_mask) != (af_lan_ip & af_lan_mask)){
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
af_get_smac(skb, smac);
|
||||
|
||||
AF_CLIENT_LOCK_W();
|
||||
|
@ -1,4 +1,4 @@
|
||||
OBJS:=appfilter_user.o appfilter_netlink.o appfilter_ubus.o appfilter_config.o main.o
|
||||
OBJS:=appfilter_user.o appfilter_netlink.o appfilter_ubus.o appfilter_config.o utils.o main.o
|
||||
EXEC:=oafd
|
||||
all: $(OBJS)
|
||||
$(CC) -o $(EXEC) $(OBJS) $(LIBS)
|
||||
|
7
open-app-filter/src/appfilter.h
Executable file
7
open-app-filter/src/appfilter.h
Executable file
@ -0,0 +1,7 @@
|
||||
#ifndef __APPFILTER_H__
|
||||
#define __APPFILTER_H__
|
||||
#define MIN_INET_ADDR_LEN 7
|
||||
#define CMD_GET_LAN_IP "ifconfig br-lan | grep 'inet addr' | awk '{print $2}' | awk -F: '{print $2}'"
|
||||
#define CMD_GET_LAN_MASK "ifconfig br-lan | grep 'inet addr' | awk '{print $4}' | awk -F: '{print $2}'"
|
||||
|
||||
#endif
|
@ -1,342 +1,352 @@
|
||||
/*
|
||||
Copyright (C) 2020 Derry <destan19@126.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "appfilter_config.h"
|
||||
#include <uci.h>
|
||||
|
||||
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;
|
||||
|
||||
|
||||
int uci_get_int_value(struct uci_context *ctx, char *key)
|
||||
{
|
||||
struct uci_element *e;
|
||||
struct uci_ptr ptr;
|
||||
int ret = -1;
|
||||
int dummy;
|
||||
char *parameters ;
|
||||
char param_tmp[128] = {0};
|
||||
strcpy(param_tmp, key);
|
||||
if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) {
|
||||
ctx->err = UCI_ERR_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
e = ptr.last;
|
||||
switch(e->type) {
|
||||
case UCI_TYPE_SECTION:
|
||||
ret = -1;
|
||||
goto done;
|
||||
case UCI_TYPE_OPTION:
|
||||
ret = atoi(ptr.o->v.string);
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
done:
|
||||
|
||||
if (ptr.p)
|
||||
uci_unload(ctx, ptr.p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int uci_get_value(struct uci_context *ctx, char *key, char *output, int out_len)
|
||||
{
|
||||
struct uci_element *e;
|
||||
struct uci_ptr ptr;
|
||||
int ret = UCI_OK;
|
||||
int dummy;
|
||||
char *parameters ;
|
||||
char param_tmp[128] = {0};
|
||||
strcpy(param_tmp, key);
|
||||
if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) {
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) {
|
||||
ctx->err = UCI_ERR_NOTFOUND;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
e = ptr.last;
|
||||
switch(e->type) {
|
||||
case UCI_TYPE_SECTION:
|
||||
snprintf(output, out_len, "%s", ptr.s->type);
|
||||
break;
|
||||
case UCI_TYPE_OPTION:
|
||||
snprintf(output, out_len, "%s", ptr.o->v.string);
|
||||
break;
|
||||
default:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
done:
|
||||
if (ptr.p)
|
||||
uci_unload(ctx, ptr.p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
static struct uci_package *
|
||||
config_init_package(const char *config)
|
||||
{
|
||||
struct uci_context *ctx = uci_ctx;
|
||||
struct uci_package *p = NULL;
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
ctx = uci_alloc_context();
|
||||
uci_ctx = ctx;
|
||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||
//if (config_path)
|
||||
// uci_set_confdir(ctx, config_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
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++)
|
||||
{
|
||||
if (id == app_name_table[i].id)
|
||||
return app_name_table[i].name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void init_app_name_table(void)
|
||||
{
|
||||
int count = 0;
|
||||
char line_buf[2048] = {0};
|
||||
|
||||
FILE *fp = fopen("/tmp/feature.cfg", "r");
|
||||
if (!fp)
|
||||
{
|
||||
printf("open file failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line_buf, sizeof(line_buf), fp))
|
||||
{
|
||||
if (strstr(line_buf, "#"))
|
||||
continue;
|
||||
if (strlen(line_buf) < 10)
|
||||
continue;
|
||||
if (!strstr(line_buf, ":"))
|
||||
continue;
|
||||
char *pos1 = strstr(line_buf, ":");
|
||||
char app_info_buf[128] = {0};
|
||||
int app_id;
|
||||
char app_name[64] = {0};
|
||||
memset(app_name, 0x0, sizeof(app_name));
|
||||
strncpy(app_info_buf, line_buf, pos1 - line_buf);
|
||||
sscanf(app_info_buf, "%d %s", &app_id, app_name);
|
||||
app_name_table[g_app_count].id = app_id;
|
||||
strcpy(app_name_table[g_app_count].name, app_name);
|
||||
g_app_count++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void init_app_class_name_table(void)
|
||||
{
|
||||
char line_buf[2048] = {0};
|
||||
int class_id;
|
||||
char class_name[64] = {0};
|
||||
FILE *fp = fopen("/tmp/app_class.txt", "r");
|
||||
if (!fp)
|
||||
{
|
||||
printf("open file failed\n");
|
||||
return;
|
||||
}
|
||||
while (fgets(line_buf, sizeof(line_buf), fp))
|
||||
{
|
||||
sscanf(line_buf, "%d %*s %s", &class_id, class_name);
|
||||
printf("line buf = %s, class_name = %s\n", line_buf, class_name);
|
||||
strcpy(CLASS_NAME_TABLE[class_id - 1], class_name);
|
||||
g_cur_class_num++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
//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)
|
||||
{
|
||||
char start_time_str[64] = {0};
|
||||
char end_time_str[64] = {0};
|
||||
char start_time_str2[64] = {0};
|
||||
char end_time_str2[64] = {0};
|
||||
char days_str[64] = {0};
|
||||
int value = 0;
|
||||
int ret = 0;
|
||||
af_ctl_time_t *t = NULL;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
memset(start_time_str, 0x0, sizeof(start_time_str));
|
||||
memset(end_time_str, 0x0, sizeof(end_time_str));
|
||||
memset(start_time_str2, 0x0, sizeof(start_time_str2));
|
||||
memset(end_time_str2, 0x0, sizeof(end_time_str2));
|
||||
|
||||
uci_get_value(ctx, "appfilter.time.start_time", start_time_str, sizeof(start_time_str));
|
||||
uci_get_value(ctx, "appfilter.time.end_time", end_time_str, sizeof(end_time_str));
|
||||
uci_get_value(ctx, "appfilter.time.start_time2", start_time_str2, sizeof(start_time_str2));
|
||||
uci_get_value(ctx, "appfilter.time.end_time2", end_time_str2, sizeof(end_time_str2));
|
||||
uci_get_value(ctx, "appfilter.time.days", days_str, sizeof(days_str));
|
||||
|
||||
|
||||
t = malloc(sizeof(af_ctl_time_t));
|
||||
|
||||
value = uci_get_int_value(ctx, "appfilter.time.time_mode");
|
||||
if (value < 0)
|
||||
t->time_mode = 0;
|
||||
else
|
||||
t->time_mode = value;
|
||||
if (check_time_valid(start_time_str) && check_time_valid(end_time_str)){
|
||||
sscanf(start_time_str, "%d:%d", &t->start.hour, &t->start.min);
|
||||
sscanf(end_time_str, "%d:%d", &t->end.hour, &t->end.min);
|
||||
}
|
||||
if (check_time_valid(start_time_str2) && check_time_valid(end_time_str2)){
|
||||
sscanf(start_time_str2, "%d:%d", &t->start2.hour, &t->start2.min);
|
||||
sscanf(end_time_str2, "%d:%d", &t->end2.hour, &t->end2.min);
|
||||
}
|
||||
|
||||
char *p = strtok(days_str, " ");
|
||||
if (!p)
|
||||
goto EXIT;
|
||||
do
|
||||
{
|
||||
int day = atoi(p);
|
||||
if (day >= 0 && day <= 6)
|
||||
t->days[day] = 1;
|
||||
else
|
||||
ret = 0;
|
||||
} while (p = strtok(NULL, " "));
|
||||
EXIT:
|
||||
uci_free_context(ctx);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int config_get_appfilter_enable(void)
|
||||
{
|
||||
int enable = 0;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
enable = uci_get_int_value(ctx, "appfilter.global.enable");
|
||||
if (enable < 0)
|
||||
enable = 0;
|
||||
|
||||
uci_free_context(ctx);
|
||||
return enable;
|
||||
}
|
||||
|
||||
int config_get_lan_ip(char *lan_ip, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return -1;
|
||||
ret = uci_get_value(ctx, "network.lan.ipaddr", lan_ip, len);
|
||||
uci_free_context(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Copyright (C) 2020 Derry <destan19@126.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "appfilter_config.h"
|
||||
#include <uci.h>
|
||||
|
||||
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;
|
||||
|
||||
|
||||
int uci_get_int_value(struct uci_context *ctx, char *key)
|
||||
{
|
||||
struct uci_element *e;
|
||||
struct uci_ptr ptr;
|
||||
int ret = -1;
|
||||
int dummy;
|
||||
char *parameters ;
|
||||
char param_tmp[128] = {0};
|
||||
strcpy(param_tmp, key);
|
||||
if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) {
|
||||
ctx->err = UCI_ERR_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
e = ptr.last;
|
||||
switch(e->type) {
|
||||
case UCI_TYPE_SECTION:
|
||||
ret = -1;
|
||||
goto done;
|
||||
case UCI_TYPE_OPTION:
|
||||
ret = atoi(ptr.o->v.string);
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
done:
|
||||
|
||||
if (ptr.p)
|
||||
uci_unload(ctx, ptr.p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int uci_get_value(struct uci_context *ctx, char *key, char *output, int out_len)
|
||||
{
|
||||
struct uci_element *e;
|
||||
struct uci_ptr ptr;
|
||||
int ret = UCI_OK;
|
||||
int dummy;
|
||||
char *parameters ;
|
||||
char param_tmp[128] = {0};
|
||||
strcpy(param_tmp, key);
|
||||
if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) {
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) {
|
||||
ctx->err = UCI_ERR_NOTFOUND;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
e = ptr.last;
|
||||
switch(e->type) {
|
||||
case UCI_TYPE_SECTION:
|
||||
snprintf(output, out_len, "%s", ptr.s->type);
|
||||
break;
|
||||
case UCI_TYPE_OPTION:
|
||||
snprintf(output, out_len, "%s", ptr.o->v.string);
|
||||
break;
|
||||
default:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
done:
|
||||
if (ptr.p)
|
||||
uci_unload(ctx, ptr.p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
static struct uci_package *
|
||||
config_init_package(const char *config)
|
||||
{
|
||||
struct uci_context *ctx = uci_ctx;
|
||||
struct uci_package *p = NULL;
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
ctx = uci_alloc_context();
|
||||
uci_ctx = ctx;
|
||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||
//if (config_path)
|
||||
// uci_set_confdir(ctx, config_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
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++)
|
||||
{
|
||||
if (id == app_name_table[i].id)
|
||||
return app_name_table[i].name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void init_app_name_table(void)
|
||||
{
|
||||
int count = 0;
|
||||
char line_buf[2048] = {0};
|
||||
|
||||
FILE *fp = fopen("/tmp/feature.cfg", "r");
|
||||
if (!fp)
|
||||
{
|
||||
printf("open file failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line_buf, sizeof(line_buf), fp))
|
||||
{
|
||||
if (strstr(line_buf, "#"))
|
||||
continue;
|
||||
if (strlen(line_buf) < 10)
|
||||
continue;
|
||||
if (!strstr(line_buf, ":"))
|
||||
continue;
|
||||
char *pos1 = strstr(line_buf, ":");
|
||||
char app_info_buf[128] = {0};
|
||||
int app_id;
|
||||
char app_name[64] = {0};
|
||||
memset(app_name, 0x0, sizeof(app_name));
|
||||
strncpy(app_info_buf, line_buf, pos1 - line_buf);
|
||||
sscanf(app_info_buf, "%d %s", &app_id, app_name);
|
||||
app_name_table[g_app_count].id = app_id;
|
||||
strcpy(app_name_table[g_app_count].name, app_name);
|
||||
g_app_count++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void init_app_class_name_table(void)
|
||||
{
|
||||
char line_buf[2048] = {0};
|
||||
int class_id;
|
||||
char class_name[64] = {0};
|
||||
FILE *fp = fopen("/tmp/app_class.txt", "r");
|
||||
if (!fp)
|
||||
{
|
||||
printf("open file failed\n");
|
||||
return;
|
||||
}
|
||||
while (fgets(line_buf, sizeof(line_buf), fp))
|
||||
{
|
||||
sscanf(line_buf, "%d %*s %s", &class_id, class_name);
|
||||
strcpy(CLASS_NAME_TABLE[class_id - 1], class_name);
|
||||
g_cur_class_num++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
//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)
|
||||
{
|
||||
char start_time_str[64] = {0};
|
||||
char end_time_str[64] = {0};
|
||||
char start_time_str2[64] = {0};
|
||||
char end_time_str2[64] = {0};
|
||||
char days_str[64] = {0};
|
||||
int value = 0;
|
||||
int ret = 0;
|
||||
af_ctl_time_t *t = NULL;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
memset(start_time_str, 0x0, sizeof(start_time_str));
|
||||
memset(end_time_str, 0x0, sizeof(end_time_str));
|
||||
memset(start_time_str2, 0x0, sizeof(start_time_str2));
|
||||
memset(end_time_str2, 0x0, sizeof(end_time_str2));
|
||||
|
||||
uci_get_value(ctx, "appfilter.time.start_time", start_time_str, sizeof(start_time_str));
|
||||
uci_get_value(ctx, "appfilter.time.end_time", end_time_str, sizeof(end_time_str));
|
||||
uci_get_value(ctx, "appfilter.time.start_time2", start_time_str2, sizeof(start_time_str2));
|
||||
uci_get_value(ctx, "appfilter.time.end_time2", end_time_str2, sizeof(end_time_str2));
|
||||
uci_get_value(ctx, "appfilter.time.days", days_str, sizeof(days_str));
|
||||
|
||||
|
||||
t = malloc(sizeof(af_ctl_time_t));
|
||||
|
||||
value = uci_get_int_value(ctx, "appfilter.time.time_mode");
|
||||
if (value < 0)
|
||||
t->time_mode = 0;
|
||||
else
|
||||
t->time_mode = value;
|
||||
if (check_time_valid(start_time_str) && check_time_valid(end_time_str)){
|
||||
sscanf(start_time_str, "%d:%d", &t->start.hour, &t->start.min);
|
||||
sscanf(end_time_str, "%d:%d", &t->end.hour, &t->end.min);
|
||||
}
|
||||
if (check_time_valid(start_time_str2) && check_time_valid(end_time_str2)){
|
||||
sscanf(start_time_str2, "%d:%d", &t->start2.hour, &t->start2.min);
|
||||
sscanf(end_time_str2, "%d:%d", &t->end2.hour, &t->end2.min);
|
||||
}
|
||||
|
||||
char *p = strtok(days_str, " ");
|
||||
if (!p)
|
||||
goto EXIT;
|
||||
do
|
||||
{
|
||||
int day = atoi(p);
|
||||
if (day >= 0 && day <= 6)
|
||||
t->days[day] = 1;
|
||||
else
|
||||
ret = 0;
|
||||
} while (p = strtok(NULL, " "));
|
||||
EXIT:
|
||||
uci_free_context(ctx);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int config_get_appfilter_enable(void)
|
||||
{
|
||||
int enable = 0;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
enable = uci_get_int_value(ctx, "appfilter.global.enable");
|
||||
if (enable < 0)
|
||||
enable = 0;
|
||||
|
||||
uci_free_context(ctx);
|
||||
return enable;
|
||||
}
|
||||
|
||||
int config_get_lan_ip(char *lan_ip, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return -1;
|
||||
ret = uci_get_value(ctx, "network.lan.ipaddr", lan_ip, len);
|
||||
uci_free_context(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int config_get_lan_mask(char *lan_mask, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct uci_context *ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return -1;
|
||||
ret = uci_get_value(ctx, "network.lan.netmask", lan_mask, len);
|
||||
uci_free_context(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -57,5 +57,6 @@ int appfilter_config_free(void);
|
||||
af_ctl_time_t *load_appfilter_ctl_time_config(void);
|
||||
int config_get_appfilter_enable(void);
|
||||
int config_get_lan_ip(char *lan_ip, int len);
|
||||
int config_get_lan_mask(char *lan_mask, int len);
|
||||
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/socket.h>
|
||||
#include <sys/socket.h>
|
||||
#include "appfilter.h"
|
||||
#include "appfilter_user.h"
|
||||
|
||||
dev_node_t *dev_hash_table[MAX_DEV_NODE_HASH_SIZE];
|
||||
@ -190,7 +191,8 @@ void clean_dev_online_status(void)
|
||||
dev_node_t *node = dev_hash_table[i];
|
||||
while (node)
|
||||
{
|
||||
if (node->online){
|
||||
if (node->online)
|
||||
{
|
||||
node->offline_time = get_timestamp();
|
||||
node->online = 0;
|
||||
}
|
||||
@ -200,10 +202,10 @@ void clean_dev_online_status(void)
|
||||
}
|
||||
|
||||
/*
|
||||
Id Mac Ip
|
||||
1 10:bf:48:37:0c:94 192.168.66.244
|
||||
Id Mac Ip
|
||||
1 10:bf:48:37:0c:94 192.168.66.244
|
||||
*/
|
||||
void update_dev_online_status(void)
|
||||
void update_dev_from_oaf(void)
|
||||
{
|
||||
char line_buf[256] = {0};
|
||||
char mac_buf[32] = {0};
|
||||
@ -237,6 +239,59 @@ void update_dev_online_status(void)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void update_dev_from_arp(void)
|
||||
{
|
||||
char line_buf[256] = {0};
|
||||
char mac_buf[32] = {0};
|
||||
char ip_buf[32] = {0};
|
||||
char lan_ip[32] = {0};
|
||||
char lan_mask[32] = {0};
|
||||
|
||||
exec_with_result_line(CMD_GET_LAN_IP, lan_ip, sizeof(lan_ip));
|
||||
exec_with_result_line(CMD_GET_LAN_MASK, lan_mask, sizeof(lan_mask));
|
||||
if (strlen(lan_ip) < MIN_INET_ADDR_LEN || strlen(lan_mask) < MIN_INET_ADDR_LEN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = fopen("/proc/net/arp", "r");
|
||||
if (!fp)
|
||||
{
|
||||
printf("open dev file....failed\n");
|
||||
return;
|
||||
}
|
||||
fgets(line_buf, sizeof(line_buf), fp); // title
|
||||
while (fgets(line_buf, sizeof(line_buf), fp))
|
||||
{
|
||||
sscanf(line_buf, "%s %*s %*s %s", ip_buf, mac_buf);
|
||||
|
||||
if (strlen(mac_buf) < 17 || strlen(ip_buf) < MIN_INET_ADDR_LEN)
|
||||
{
|
||||
printf("invalid mac:%s or ip:%s\n", mac_buf, ip_buf);
|
||||
continue;
|
||||
}
|
||||
if (0 == strcmp(mac_buf, "00:00:00:00:00:00"))
|
||||
continue;
|
||||
if (!check_same_network(lan_ip, lan_mask, ip_buf) || 0 == strcmp(lan_ip, ip_buf))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dev_node_t *node = find_dev_node(mac_buf);
|
||||
if (!node)
|
||||
{
|
||||
node = add_dev_node(mac_buf);
|
||||
if (!node)
|
||||
continue;
|
||||
strncpy(node->ip, ip_buf, sizeof(node->ip));
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
void update_dev_online_status(void)
|
||||
{
|
||||
update_dev_from_oaf();
|
||||
update_dev_from_arp();
|
||||
}
|
||||
|
||||
#define DEV_OFFLINE_TIME (SECONDS_PER_DAY * 3)
|
||||
|
||||
@ -272,7 +327,7 @@ int check_dev_expire(void)
|
||||
}
|
||||
expire_count++;
|
||||
printf("dev:%s expired, offline time = %ds, count=%d, visit_count=%d\n",
|
||||
node->mac, offline_time, expire_count, visit_count);
|
||||
node->mac, offline_time, expire_count, visit_count);
|
||||
}
|
||||
NEXT:
|
||||
node = node->next;
|
||||
@ -389,10 +444,10 @@ EXIT:
|
||||
fclose(fp);
|
||||
}
|
||||
// 记录最大保存时间 todo: support config
|
||||
#define MAX_RECORD_TIME (7 * 24 * 60 * 60) // 7day
|
||||
#define MAX_RECORD_TIME (3 * 24 * 60 * 60) // 7day
|
||||
// 超过1天后清除短时间的记录
|
||||
#define RECORD_REMAIN_TIME (24 * 60 * 60) // 1day
|
||||
#define INVALID_RECORD_TIME (5 * 60) // 5min
|
||||
#define INVALID_RECORD_TIME (5 * 60) // 5min
|
||||
|
||||
void check_dev_visit_info_expire(void)
|
||||
{
|
||||
@ -410,11 +465,13 @@ void check_dev_visit_info_expire(void)
|
||||
while (p_info)
|
||||
{
|
||||
int total_time = p_info->latest_time - p_info->first_time;
|
||||
int interval_time = cur_time - p_info->first_time;
|
||||
if (interval_time > MAX_RECORD_TIME || interval_time < 0){
|
||||
int interval_time = cur_time - p_info->first_time;
|
||||
if (interval_time > MAX_RECORD_TIME || interval_time < 0)
|
||||
{
|
||||
p_info->expire = 1;
|
||||
}
|
||||
else if (interval_time > RECORD_REMAIN_TIME){
|
||||
else if (interval_time > RECORD_REMAIN_TIME)
|
||||
{
|
||||
if (total_time < INVALID_RECORD_TIME)
|
||||
p_info->expire = 1;
|
||||
}
|
||||
@ -442,24 +499,27 @@ void flush_expire_visit_info(void)
|
||||
prev = NULL;
|
||||
while (p_info)
|
||||
{
|
||||
if (p_info->expire){
|
||||
if (NULL == prev){
|
||||
if (p_info->expire)
|
||||
{
|
||||
if (NULL == prev)
|
||||
{
|
||||
node->visit_htable[j] = p_info->next;
|
||||
free(p_info);
|
||||
p_info = node->visit_htable[j];
|
||||
prev = NULL;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
prev->next = p_info->next;
|
||||
free(p_info);
|
||||
p_info = prev->next;
|
||||
}
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
prev = p_info;
|
||||
p_info = p_info->next;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
@ -467,9 +527,6 @@ void flush_expire_visit_info(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void dump_dev_visit_list(void)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -1,153 +1,175 @@
|
||||
/*
|
||||
Copyright (C) 2020 Derry <destan19@126.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <libubox/utils.h>
|
||||
#include <libubus.h>
|
||||
#include "appfilter_user.h"
|
||||
#include "appfilter_netlink.h"
|
||||
#include "appfilter_ubus.h"
|
||||
#include "appfilter_config.h"
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
void check_appfilter_enable(void)
|
||||
{
|
||||
int enable = 1;
|
||||
struct tm *t;
|
||||
af_ctl_time_t *af_t = NULL;
|
||||
time_t tt;
|
||||
time(&tt);
|
||||
enable = config_get_appfilter_enable();
|
||||
|
||||
if (0 == enable)
|
||||
goto EXIT;
|
||||
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)
|
||||
{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 0;
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
|| ((af_t->start2.hour * 60 + af_t->start2.min < cur_mins) && (cur_mins < af_t->end2.hour * 60 + af_t->end2.min))
|
||||
)
|
||||
{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 1;
|
||||
}
|
||||
else{
|
||||
enable = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 0;
|
||||
}
|
||||
else{
|
||||
enable = 1;
|
||||
}
|
||||
}
|
||||
EXIT:
|
||||
if (enable)
|
||||
{
|
||||
system("echo 1 >/proc/sys/oaf/enable ");
|
||||
}
|
||||
else
|
||||
system("echo 0 >/proc/sys/oaf/enable ");
|
||||
if (af_t)
|
||||
free(af_t);
|
||||
}
|
||||
|
||||
void update_lan_ip(void){
|
||||
char ip_str[32] = {0};
|
||||
struct in_addr addr;
|
||||
char cmd_buf[128] = {0};
|
||||
u_int32_t lan_ip = 0;
|
||||
|
||||
config_get_lan_ip(ip_str, sizeof(ip_str));
|
||||
inet_aton(ip_str, &addr);
|
||||
lan_ip =addr.s_addr;
|
||||
sprintf(cmd_buf, "echo %d >/proc/sys/oaf/lan_ip", lan_ip);
|
||||
system(cmd_buf);
|
||||
}
|
||||
|
||||
void dev_list_timeout_handler(struct uloop_timeout *t)
|
||||
{
|
||||
dump_dev_list();
|
||||
check_dev_visit_info_expire();
|
||||
flush_expire_visit_info();
|
||||
//dump_dev_visit_list();
|
||||
update_lan_ip();
|
||||
check_appfilter_enable();
|
||||
if (check_dev_expire()){
|
||||
flush_expire_visit_info();
|
||||
flush_dev_expire_node();
|
||||
}
|
||||
uloop_timeout_set(t, 10000);
|
||||
}
|
||||
|
||||
struct uloop_timeout dev_tm = {
|
||||
.cb = dev_list_timeout_handler};
|
||||
|
||||
static struct uloop_fd appfilter_nl_fd = {
|
||||
.cb = appfilter_nl_handler,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
uloop_init();
|
||||
printf("init appfilter\n");
|
||||
init_dev_node_htable();
|
||||
init_app_name_table();
|
||||
init_app_class_name_table();
|
||||
if (appfilter_ubus_init() < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to connect to ubus\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
appfilter_nl_fd.fd = appfilter_nl_init();
|
||||
uloop_fd_add(&appfilter_nl_fd, ULOOP_READ);
|
||||
af_msg_t msg;
|
||||
msg.action = AF_MSG_INIT;
|
||||
send_msg_to_kernel(appfilter_nl_fd.fd, (void *)&msg, sizeof(msg));
|
||||
uloop_timeout_set(&dev_tm, 5000);
|
||||
uloop_timeout_add(&dev_tm);
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
Copyright (C) 2020 Derry <destan19@126.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <libubox/utils.h>
|
||||
#include <libubus.h>
|
||||
#include "appfilter_user.h"
|
||||
#include "appfilter_netlink.h"
|
||||
#include "appfilter_ubus.h"
|
||||
#include "appfilter_config.h"
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "appfilter.h"
|
||||
|
||||
|
||||
void check_appfilter_enable(void)
|
||||
{
|
||||
int enable = 1;
|
||||
struct tm *t;
|
||||
af_ctl_time_t *af_t = NULL;
|
||||
time_t tt;
|
||||
time(&tt);
|
||||
enable = config_get_appfilter_enable();
|
||||
|
||||
if (0 == enable)
|
||||
goto EXIT;
|
||||
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)
|
||||
{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 0;
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
|| ((af_t->start2.hour * 60 + af_t->start2.min < cur_mins) && (cur_mins < af_t->end2.hour * 60 + af_t->end2.min))
|
||||
)
|
||||
{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 1;
|
||||
}
|
||||
else{
|
||||
enable = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (af_t->time_mode == 0){
|
||||
enable = 0;
|
||||
}
|
||||
else{
|
||||
enable = 1;
|
||||
}
|
||||
}
|
||||
EXIT:
|
||||
if (enable)
|
||||
{
|
||||
system("echo 1 >/proc/sys/oaf/enable ");
|
||||
}
|
||||
else
|
||||
system("echo 0 >/proc/sys/oaf/enable ");
|
||||
if (af_t)
|
||||
free(af_t);
|
||||
}
|
||||
|
||||
void update_lan_ip(void){
|
||||
char ip_str[32] = {0};
|
||||
char mask_str[32] = {0};
|
||||
struct in_addr addr;
|
||||
struct in_addr mask_addr;
|
||||
char cmd_buf[128] = {0};
|
||||
u_int32_t lan_ip = 0;
|
||||
u_int32_t lan_mask = 0;
|
||||
|
||||
exec_with_result_line(CMD_GET_LAN_IP, ip_str, sizeof(ip_str));
|
||||
if (strlen(ip_str) < MIN_INET_ADDR_LEN){
|
||||
sprintf(cmd_buf, "echo 0 >/proc/sys/oaf/lan_ip");
|
||||
}
|
||||
else{
|
||||
inet_aton(ip_str, &addr);
|
||||
lan_ip = addr.s_addr;
|
||||
sprintf(cmd_buf, "echo %u >/proc/sys/oaf/lan_ip", lan_ip);
|
||||
}
|
||||
system(cmd_buf);
|
||||
exec_with_result_line(CMD_GET_LAN_MASK, mask_str, sizeof(mask_str));
|
||||
|
||||
if (strlen(mask_str) < MIN_INET_ADDR_LEN){
|
||||
sprintf(cmd_buf, "echo 0 >/proc/sys/oaf/lan_mask");
|
||||
}
|
||||
else{
|
||||
inet_aton(mask_str, &mask_addr);
|
||||
lan_mask = mask_addr.s_addr;
|
||||
sprintf(cmd_buf, "echo %u >/proc/sys/oaf/lan_mask", lan_mask);
|
||||
}
|
||||
system(cmd_buf);
|
||||
}
|
||||
|
||||
void dev_list_timeout_handler(struct uloop_timeout *t)
|
||||
{
|
||||
dump_dev_list();
|
||||
check_dev_visit_info_expire();
|
||||
flush_expire_visit_info();
|
||||
//dump_dev_visit_list();
|
||||
update_lan_ip();
|
||||
check_appfilter_enable();
|
||||
if (check_dev_expire()){
|
||||
flush_expire_visit_info();
|
||||
flush_dev_expire_node();
|
||||
}
|
||||
uloop_timeout_set(t, 10000);
|
||||
}
|
||||
|
||||
struct uloop_timeout dev_tm = {
|
||||
.cb = dev_list_timeout_handler};
|
||||
|
||||
static struct uloop_fd appfilter_nl_fd = {
|
||||
.cb = appfilter_nl_handler,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
uloop_init();
|
||||
printf("init appfilter\n");
|
||||
init_dev_node_htable();
|
||||
init_app_name_table();
|
||||
init_app_class_name_table();
|
||||
if (appfilter_ubus_init() < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to connect to ubus\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
appfilter_nl_fd.fd = appfilter_nl_init();
|
||||
uloop_fd_add(&appfilter_nl_fd, ULOOP_READ);
|
||||
af_msg_t msg;
|
||||
msg.action = AF_MSG_INIT;
|
||||
send_msg_to_kernel(appfilter_nl_fd.fd, (void *)&msg, sizeof(msg));
|
||||
uloop_timeout_set(&dev_tm, 5000);
|
||||
uloop_timeout_add(&dev_tm);
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
return 0;
|
||||
}
|
||||
|
69
open-app-filter/src/utils.c
Executable file
69
open-app-filter/src/utils.c
Executable file
@ -0,0 +1,69 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
char *str_trim(char *s) {
|
||||
char *start, *last, *bk;
|
||||
int len;
|
||||
|
||||
start = s;
|
||||
while (isspace(*start))
|
||||
start++;
|
||||
|
||||
bk = last = s + strlen(s) - 1;
|
||||
while (last > start && isspace(*last))
|
||||
last--;
|
||||
|
||||
if ((s != start) || (bk != last)) {
|
||||
len = last - start + 1;
|
||||
strncpy(s, start, len);
|
||||
s[len] = '\0';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int exec_with_result_line(char *cmd, char *result, int len)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
if (!cmd || !result || !len)
|
||||
return -1;
|
||||
fp = popen(cmd, "r");
|
||||
if (!fp)
|
||||
return -1;
|
||||
fgets(result, len, fp);
|
||||
str_trim(result);
|
||||
pclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int check_same_network(char *ip1, char *netmask, char *ip2) {
|
||||
struct in_addr addr1, addr2, mask;
|
||||
|
||||
if (inet_pton(AF_INET, ip1, &addr1) != 1) {
|
||||
printf("Invalid IP address: %s\n", ip1);
|
||||
return -1;
|
||||
}
|
||||
if (inet_pton(AF_INET, netmask, &mask) != 1) {
|
||||
printf("Invalid netmask: %s\n", netmask);
|
||||
return -1;
|
||||
}
|
||||
if (inet_pton(AF_INET, ip2, &addr2) != 1) {
|
||||
printf("Invalid IP address: %s\n", ip2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((addr1.s_addr & mask.s_addr) == (addr2.s_addr & mask.s_addr)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
6
open-app-filter/src/utils.h
Executable file
6
open-app-filter/src/utils.h
Executable file
@ -0,0 +1,6 @@
|
||||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
char *str_trim(char *s);
|
||||
int exec_with_result_line(char *cmd, char *result, int len);
|
||||
int check_same_network(char *ip1, char *netmask, char *ip2);
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user