diff --git a/files/parental_control.config b/files/parental_control.config index 51a85d8..99aeaea 100755 --- a/files/parental_control.config +++ b/files/parental_control.config @@ -5,6 +5,8 @@ config global 'global' option update_time '04:00:00' option update_url 'http://192.168.99.211/test.txt' option enable_app '0' + list src_dev 'br-lan' + list src_dev 'br-guest' config rule 'drop' option name 'drop_all' diff --git a/files/parental_control.sh b/files/parental_control.sh index 338e956..d0550de 100755 --- a/files/parental_control.sh +++ b/files/parental_control.sh @@ -53,8 +53,9 @@ config_apply() load_base_config() { - local drop_anonymous + local drop_anonymous src_dev config_get drop_anonymous "global" "drop_anonymous" "0" + config_get src_dev "global" "src_dev" config_get UPDATE_TIME "global" "update_time" config_get UPDATE_URL "global" "update_url" config_get UPDATE_EN "global" "auto_update" "0" @@ -63,6 +64,7 @@ load_base_config() json_add_int "op" $SET_BASE json_add_object "data" json_add_int "drop_anonymous" $drop_anonymous + json_add_string "src_dev" "$src_dev" json_str=`json_dump` config_apply "$json_str" json_cleanup diff --git a/readme.md b/readme.md index e24ef71..058026f 100755 --- a/readme.md +++ b/readme.md @@ -81,8 +81,11 @@ When you see the **/proc/parents-control/** folder created, it means the program **/proc/parental-control/drop_anonymous** will show the Internet status of the anonymous device. +**/proc/parental-control/src_dev** will show the network interface to be matched. + ### use the app feature library **/proc/parental-control/app** show the currently loaded app feature library, which we can use in rule by id, for example + ``` uci add_list parental_control.myrule.apps='1001' uci add_list parental_control.myrule.apps='1002' @@ -109,6 +112,7 @@ Configure applications in the /etc/config/parental_contorl file. The configurati | enable | Y | Boolean; Whether to enable the application | | drop_anonymous | Y | Boolean; Whether to deny anonymous devices access to the Internet | | auto_update | Y | Boolean; Whether to automatically update the APP feature library | +| src_dev | N | List; By default, the packets sent from all network interfaces are matched. If **src_dev** is specified, only the packets sent from a specific network interface are matched | | update_time | N | String; Update time of APP feature library | | update_url | N | String; Get the update URL of APP feature library | | enable_app | N | Boolean; Use it for glinet UI | diff --git a/src/pc_config.c b/src/pc_config.c index 0662111..a959784 100755 --- a/src/pc_config.c +++ b/src/pc_config.c @@ -12,6 +12,7 @@ #define PC_DEV_NAME "parental_control" u8 pc_drop_anonymous = 0; +char pc_src_dev[MAX_SRC_DEVNAME_SIZE] = {0}; static struct mutex pc_cdev_mutex; @@ -58,24 +59,31 @@ static int mac_to_hex(u8 *mac, u8 *mac_hex) static int pc_set_base_config(cJSON *data_obj) { - cJSON *cfgobj = NULL; + cJSON *aouobj = NULL, *srcobj = NULL; if (!data_obj) { PC_ERROR("data obj is null\n"); return -1; } - cfgobj = cJSON_GetObjectItem(data_obj, "drop_anonymous"); - if (!cfgobj) { - PC_ERROR("cfgobj obj is null\n"); + aouobj = cJSON_GetObjectItem(data_obj, "drop_anonymous"); + if (!aouobj) { + PC_ERROR("aouobj obj is null\n"); return -1; } - pc_drop_anonymous = cfgobj->valueint; + pc_drop_anonymous = aouobj->valueint; + + srcobj = cJSON_GetObjectItem(data_obj, "src_dev"); + if (!srcobj) { + PC_ERROR("srcobj obj is null\n"); + return -1; + } + strncpy(pc_src_dev, srcobj->valuestring, MAX_SRC_DEVNAME_SIZE - 1); return 0; } static int pc_set_rule_config(cJSON *data_obj, char add) { - int i, j; + int i; cJSON *arr = NULL; if (!data_obj) { PC_ERROR("data obj is null\n"); diff --git a/src/pc_filter.c b/src/pc_filter.c index 06f6d84..33a6c4c 100755 --- a/src/pc_filter.c +++ b/src/pc_filter.c @@ -342,7 +342,6 @@ int pc_match_one(flow_info_t *flow, pc_app_t *node) static int app_in_rule(u_int32_t app, pc_rule_t *rule) { pc_app_index_t *node, *n; - int i; if (app < MAX_APP_IN_CLASS) { return PC_FALSE; } @@ -431,6 +430,32 @@ void pc_get_smac(struct sk_buff *skb, u8 smac[ETH_ALEN]) memcpy(smac, &skb->cb[40], ETH_ALEN);*/ } +static int check_source_net_dev(struct sk_buff *skb) +{ + char nstr[MAX_SRC_DEVNAME_SIZE] = {0}; + char *ptr; + char *item = NULL; + struct net_device *netdev = skb->dev; + + if (!netdev) + return PC_FALSE; + PC_LMT_DEBUG("get package from %s\n", netdev->name); + if (0 == strlen(pc_src_dev)) { + PC_LMT_DEBUG("match any netdev\n"); + return PC_TRUE; + } + strcpy(nstr, pc_src_dev); + ptr = nstr; + while (ptr) { + item = strsep(&ptr, " "); + if (0 == strcmp(item, netdev->name)) { + PC_LMT_DEBUG("match net dev %s\n", netdev->name); + return PC_TRUE; + } + } + return PC_FALSE; +} + u_int32_t pc_filter_hook_handle(struct sk_buff *skb, struct net_device *dev) { unsigned long long total_packets = 0; @@ -440,8 +465,10 @@ u_int32_t pc_filter_hook_handle(struct sk_buff *skb, struct net_device *dev) enum ip_conntrack_info ctinfo; struct nf_conn *ct = NULL; enum pc_action action; - - + if (!check_source_net_dev(skb)) { + ret = NF_ACCEPT; + goto EXIT; + } ct = nf_ct_get(skb, &ctinfo); /*if (ct) { PC_LMT_DEBUG("ctinfo %d\n", ctinfo); diff --git a/src/pc_policy.c b/src/pc_policy.c index 947539a..38c17eb 100755 --- a/src/pc_policy.c +++ b/src/pc_policy.c @@ -388,7 +388,6 @@ static int rule_proc_show(struct seq_file *s, void *v) { pc_rule_t *rule = NULL, *n; pc_app_index_t *index = NULL, *index_n; - int i = 0; seq_printf(s, "ID\tAction\tRefer_count\tAPPs\n"); pc_policy_read_lock(); if (!list_empty(&pc_rule_head)) { @@ -455,6 +454,17 @@ static int app_proc_open(struct inode *inode, struct file *file) return single_open(file, app_proc_show, NULL); } +static int src_dev_show(struct seq_file *s, void *v) +{ + seq_printf(s, "%s\n", pc_src_dev); + return 0; +} + +static int src_dev_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, src_dev_show, NULL); +} + #if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 5, 0) static const struct file_operations pc_app_fops = { .owner = THIS_MODULE, @@ -484,6 +494,13 @@ static const struct file_operations pc_drop_anonymous_fops = { .llseek = seq_lseek, .release = seq_release_private, }; +static const struct file_operations pc_src_dev_fops = { + .owner = THIS_MODULE, + .open = src_dev_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; #else static const struct proc_ops pc_app_fops = { .proc_flags = PROC_ENTRY_PERMANENT, @@ -513,6 +530,13 @@ static const struct proc_ops pc_drop_anonymous_fops = { .proc_lseek = seq_lseek, .proc_release = seq_release_private, }; +static const struct proc_ops pc_src_dev_fops = { + .proc_flags = PROC_ENTRY_PERMANENT, + .proc_read = seq_read, + .proc_open = src_dev_proc_open, + .proc_lseek = seq_lseek, + .proc_release = seq_release_private, +}; #endif @@ -529,6 +553,7 @@ int pc_init_procfs(void) proc_create("group", 0644, proc, &pc_group_fops); proc_create("app", 0644, proc, &pc_app_fops); proc_create("drop_anonymous", 0644, proc, &pc_drop_anonymous_fops); + proc_create("src_dev", 0644, proc, &pc_src_dev_fops); return 0; } diff --git a/src/pc_policy.h b/src/pc_policy.h index 4553320..143dc66 100755 --- a/src/pc_policy.h +++ b/src/pc_policy.h @@ -27,6 +27,7 @@ #define GROUP_ID_SIZE 32 #define MAX_PORT_RANGE_NUM 5 #define MAX_APP_IN_CLASS 1000 +#define MAX_SRC_DEVNAME_SIZE 129 #define PC_TRUE 1 #define PC_FALSE 0 @@ -47,6 +48,7 @@ extern u8 pc_drop_anonymous; +extern char pc_src_dev[129]; extern struct list_head pc_app_head; extern rwlock_t pc_app_lock; extern rwlock_t pc_policy_lock;