支持基于用户的过滤
This commit is contained in:
parent
5de87b953d
commit
11f3335fa0
@ -1,16 +1,3 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
]]--
|
||||
|
||||
local ds = require "luci.dispatcher"
|
||||
|
||||
@ -81,6 +68,57 @@ if class_fd then
|
||||
end
|
||||
class_fd:close()
|
||||
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"
|
||||
local fd = io.open(leasefile, "r")
|
||||
if not fd then return end
|
||||
while true do
|
||||
local ln = fd:read("*l")
|
||||
if not ln then
|
||||
break
|
||||
end
|
||||
local ts, mac, ip, name, duid = ln:match("^(%d+) (%S+) (%S+) (%S+) (%S+)")
|
||||
print(ln)
|
||||
if dst_mac == mac then
|
||||
fd:close()
|
||||
return name
|
||||
end
|
||||
end
|
||||
fd:close()
|
||||
return nil
|
||||
end
|
||||
|
||||
users.widget="checkbox"
|
||||
--users.widget="select"
|
||||
users.size=1
|
||||
|
||||
local fd = io.open("/proc/net/arp", "r")
|
||||
if not fd then return end
|
||||
while true do
|
||||
local line = fd:read("*l")
|
||||
if not line then
|
||||
break
|
||||
end
|
||||
if not line:match("Ip*") then
|
||||
local ip, hw_type, flags, mac, mask, device = line:match("(%S+) %s+ (%S+) %s+ (%S+) %s+ (%S+) %s+ (%S+) %s+ (%S+)")
|
||||
if device:match("lan") then
|
||||
local hostname=get_hostname_by_mac(mac)
|
||||
if not hostname then
|
||||
users:value(mac, mac);
|
||||
else
|
||||
users:value(mac, hostname);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
m:section(SimpleSection).template = "admin_network/user_status"
|
||||
|
||||
|
||||
|
@ -41,8 +41,13 @@ msgstr "基本设置"
|
||||
msgid "App Filter Rules"
|
||||
msgstr "应用过滤规则"
|
||||
|
||||
msgid "Select at least one user, otherwise it will take effect for all users"
|
||||
msgstr "至少选择一个用户,否则对所有用户生效"
|
||||
|
||||
msgid "Select users"
|
||||
msgstr "选择用户"
|
||||
|
||||
msgid "Enable App Filter"
|
||||
msgstr "开启应用过滤"
|
||||
|
||||
|
||||
|
||||
|
7
luci-app-oaf/root/etc/uci-defaults/92_add_user_section
Executable file
7
luci-app-oaf/root/etc/uci-defaults/92_add_user_section
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set appfilter.user=user
|
||||
commit appfilter
|
||||
EOF
|
||||
exit 0
|
@ -22,6 +22,7 @@
|
||||
#include "af_client_fs.h"
|
||||
#include "af_log.h"
|
||||
#include "af_utils.h"
|
||||
#include "app_filter.h"
|
||||
|
||||
DEFINE_RWLOCK(af_client_lock);
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef __AF_CLIENT_H__
|
||||
#define __AF_CLIENT_H__
|
||||
#include "app_filter.h"
|
||||
|
||||
extern rwlock_t af_client_lock;
|
||||
|
||||
extern u32 nfc_debug_level;
|
||||
|
||||
#define MAX_AF_CLIENT_HASH_SIZE 64
|
||||
#define MAC_ADDR_LEN 6
|
||||
#define NF_CLIENT_TIMER_EXPIRE 1
|
||||
#define MAX_CLIENT_ACTIVE_TIME 90
|
||||
|
||||
@ -53,8 +53,7 @@ typedef struct af_client_info {
|
||||
app_visit_info_t visit_info[MAX_RECORD_APP_NUM];
|
||||
}af_client_info_t;
|
||||
|
||||
#define MAC_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
|
||||
|
||||
|
||||
int af_client_init(void);
|
||||
|
@ -296,6 +296,7 @@ static int k_vsscanf(const char *buf, const char *fmt, va_list args)
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
int k_sscanf(const char *buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -681,27 +681,36 @@ int af_match_one(flow_info_t *flow, af_feature_node_t *node)
|
||||
int app_filter_match(flow_info_t *flow)
|
||||
{
|
||||
af_feature_node_t *n,*node;
|
||||
af_client_info_t *client = NULL;
|
||||
feature_list_read_lock();
|
||||
if(!list_empty(&af_feature_head)) {
|
||||
list_for_each_entry_safe(node, n, &af_feature_head, head) {
|
||||
if(af_match_one(flow, node))
|
||||
{
|
||||
flow->app_id = node->app_id;
|
||||
client = find_af_client_by_ip(flow->src);
|
||||
if (!client){
|
||||
goto EXIT;
|
||||
}
|
||||
// 如果开启了基于用户的过滤,但没有匹配到用户
|
||||
if (is_user_match_enable() && !find_af_mac(client->mac)){
|
||||
AF_ERROR("not match mac:"MAC_FMT"\n", MAC_ARRAY(client->mac));
|
||||
goto EXIT;
|
||||
}
|
||||
if (af_get_app_status(node->app_id)){
|
||||
flow->drop = AF_TRUE;
|
||||
feature_list_read_unlock();
|
||||
return AF_TRUE;
|
||||
}
|
||||
else {
|
||||
flow->drop = AF_FALSE;
|
||||
feature_list_read_unlock();
|
||||
return AF_FALSE;
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
EXIT:
|
||||
flow->drop = AF_FALSE;
|
||||
feature_list_read_unlock();
|
||||
return AF_FALSE;
|
||||
}
|
||||
@ -940,6 +949,7 @@ static int __init app_filter_init(void)
|
||||
AF_INFO("appfilter version:"AF_VERSION"\n");
|
||||
af_log_init();
|
||||
af_register_dev();
|
||||
af_mac_list_init();
|
||||
af_init_app_status();
|
||||
load_feature_config();
|
||||
init_af_client_procfs();
|
||||
@ -970,6 +980,7 @@ static void app_filter_fini(void)
|
||||
#endif
|
||||
|
||||
af_clean_feature_list();
|
||||
af_mac_list_clear();
|
||||
af_unregister_dev();
|
||||
af_log_exit();
|
||||
af_client_exit();
|
||||
|
@ -29,12 +29,15 @@
|
||||
((unsigned char *)&addr)[2], \
|
||||
((unsigned char *)&addr)[3]
|
||||
#define NIPQUAD_FMT "%u.%u.%u.%u"
|
||||
#define MAC_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
|
||||
#define AF_TRUE 1
|
||||
#define AF_FALSE 0
|
||||
|
||||
#define AF_APP_TYPE(a) (a) / 1000
|
||||
#define AF_APP_ID(a) (a) % 1000
|
||||
#define MAC_ADDR_LEN 6
|
||||
|
||||
#define HTTPS_URL_OFFSET 9
|
||||
#define HTTPS_LEN_OFFSET 7
|
||||
@ -105,13 +108,20 @@ typedef struct af_feature_node{
|
||||
af_pos_info_t pos_info[MAX_POS_INFO_PER_FEATURE];
|
||||
}af_feature_node_t;
|
||||
|
||||
typedef struct af_mac_info {
|
||||
struct list_head hlist;
|
||||
unsigned char mac[MAC_ADDR_LEN];
|
||||
}af_mac_info_t;
|
||||
|
||||
int af_register_dev(void);
|
||||
void af_unregister_dev(void);
|
||||
void af_init_app_status(void);
|
||||
int af_get_app_status(int appid);
|
||||
int regexp_match(char *reg, char *text);
|
||||
|
||||
void af_mac_list_init(void);
|
||||
void af_mac_list_clear(void);
|
||||
af_mac_info_t * find_af_mac(unsigned char *mac);
|
||||
int is_user_match_enable(void);
|
||||
extern int g_oaf_enable;
|
||||
|
||||
#endif
|
||||
|
@ -50,6 +50,7 @@ enum AF_CONFIG_CMD{
|
||||
AF_CMD_ADD_APPID = 1,
|
||||
AF_CMD_DEL_APPID,
|
||||
AF_CMD_CLEAN_APPID,
|
||||
AF_CMD_SET_MAC_LIST,
|
||||
};
|
||||
|
||||
char g_app_id_array[AF_MAX_APP_TYPE_NUM][AF_MAX_APP_NUM] = {0};
|
||||
@ -104,7 +105,147 @@ int af_change_app_status(cJSON * data_obj, int status)
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_RWLOCK(af_mac_lock);
|
||||
#define MAX_AF_MAC_HASH_SIZE 64
|
||||
#define AF_MAC_LOCK_R() read_lock_bh(&af_mac_lock);
|
||||
#define AF_MAC_UNLOCK_R() read_unlock_bh(&af_mac_lock);
|
||||
#define AF_MAC_LOCK_W() write_lock_bh(&af_mac_lock);
|
||||
#define AF_MAC_UNLOCK_W() write_unlock_bh(&af_mac_lock);
|
||||
|
||||
u32 total_mac = 0;
|
||||
struct list_head af_mac_list_table[MAX_AF_MAC_HASH_SIZE];
|
||||
|
||||
void
|
||||
af_mac_list_init(void)
|
||||
{
|
||||
int i;
|
||||
AF_MAC_LOCK_W();
|
||||
for(i = 0; i < MAX_AF_MAC_HASH_SIZE; i ++){
|
||||
INIT_LIST_HEAD(&af_mac_list_table[i]);
|
||||
}
|
||||
AF_MAC_UNLOCK_W();
|
||||
AF_INFO("client list init......ok\n");
|
||||
}
|
||||
|
||||
void
|
||||
af_mac_list_clear(void)
|
||||
{
|
||||
int i;
|
||||
af_mac_info_t * p = NULL;
|
||||
char mac_str[32] = {0};
|
||||
|
||||
AF_DEBUG("clean list\n");
|
||||
AF_MAC_LOCK_W();
|
||||
for (i = 0; i < MAX_AF_MAC_HASH_SIZE;i++){
|
||||
while(!list_empty(&af_mac_list_table[i])){
|
||||
p = list_first_entry(&af_mac_list_table[i], af_mac_info_t, hlist);
|
||||
memset(mac_str, 0x0, sizeof(mac_str));
|
||||
sprintf(mac_str, MAC_FMT, MAC_ARRAY(p->mac));
|
||||
AF_DEBUG("clean mac:%s\n", mac_str);
|
||||
list_del(&(p->hlist));
|
||||
kfree(p);
|
||||
}
|
||||
}
|
||||
total_mac = 0;
|
||||
AF_MAC_UNLOCK_W();
|
||||
}
|
||||
|
||||
|
||||
int hash_mac(unsigned char *mac)
|
||||
{
|
||||
if (!mac)
|
||||
return 0;
|
||||
else
|
||||
return mac[5] & (MAX_AF_MAC_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
af_mac_info_t * find_af_mac(unsigned char *mac)
|
||||
{
|
||||
af_mac_info_t *node;
|
||||
unsigned int index;
|
||||
|
||||
index = hash_mac(mac);
|
||||
list_for_each_entry(node, &af_mac_list_table[index], hlist){
|
||||
if (0 == memcmp(node->mac, mac, 6)){
|
||||
AF_ERROR("match mac:"MAC_FMT"\n", MAC_ARRAY(node->mac));
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static af_mac_info_t *
|
||||
af_mac_add(unsigned char *mac)
|
||||
{
|
||||
af_mac_info_t *node;
|
||||
int index = 0;
|
||||
|
||||
node = (af_mac_info_t *)kmalloc(sizeof(af_mac_info_t), GFP_ATOMIC);
|
||||
if (node == NULL) {
|
||||
AF_ERROR("kmalloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(node, 0, sizeof(af_mac_info_t));
|
||||
memcpy(node->mac, mac, MAC_ADDR_LEN);
|
||||
|
||||
index = hash_mac(mac);
|
||||
|
||||
AF_LMT_INFO("new client mac="MAC_FMT"\n", MAC_ARRAY(node->mac));
|
||||
total_mac++;
|
||||
list_add(&(node->hlist), &af_mac_list_table[index]);
|
||||
return node;
|
||||
}
|
||||
|
||||
int is_user_match_enable(void){
|
||||
return total_mac > 0;
|
||||
}
|
||||
int mac_to_hex(u8 *mac, u8 *mac_hex){
|
||||
u8 mac_tmp[MAC_ADDR_LEN];
|
||||
int ret = 0;
|
||||
ret = sscanf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned int *)&mac_tmp[0],
|
||||
(unsigned int *)&mac_tmp[1],
|
||||
(unsigned int *)&mac_tmp[2],
|
||||
(unsigned int *)&mac_tmp[3],
|
||||
(unsigned int *)&mac_tmp[4],
|
||||
(unsigned int *)&mac_tmp[5]);
|
||||
if (MAC_ADDR_LEN != ret)
|
||||
return -1;
|
||||
memcpy(mac_hex, mac_tmp, MAC_ADDR_LEN);
|
||||
return 0;
|
||||
}
|
||||
int af_set_mac_list(cJSON * data_obj)
|
||||
{
|
||||
int i;
|
||||
int id;
|
||||
int type;
|
||||
u8 mac_hex[MAC_ADDR_LEN] = {0};
|
||||
if (!data_obj) {
|
||||
AF_ERROR("data obj is null\n");
|
||||
return -1;
|
||||
}
|
||||
cJSON *mac_arr = cJSON_GetObjectItem(data_obj, "mac_list");
|
||||
if (!mac_arr){
|
||||
AF_ERROR("apps obj is null\n");
|
||||
return -1;
|
||||
}
|
||||
af_mac_list_clear();
|
||||
for (i = 0; i < cJSON_GetArraySize(mac_arr); i++) {
|
||||
cJSON *mac_obj = cJSON_GetArrayItem(mac_arr, i);
|
||||
if (!mac_obj){
|
||||
AF_ERROR("appid obj is null\n");
|
||||
return -1;
|
||||
}
|
||||
if (-1 == mac_to_hex(mac_obj->valuestring, mac_hex)){
|
||||
AF_ERROR("mac format error: %s\n", mac_obj->valuestring);
|
||||
continue;
|
||||
}
|
||||
af_mac_add(mac_hex);
|
||||
}
|
||||
printk("## mac num = %d\n", total_mac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void af_init_app_status(void)
|
||||
{
|
||||
@ -177,6 +318,9 @@ int af_config_handle(char *config, unsigned int len)
|
||||
case AF_CMD_CLEAN_APPID:
|
||||
af_init_app_status();
|
||||
break;
|
||||
case AF_CMD_SET_MAC_LIST:
|
||||
af_set_mac_list(data_obj);
|
||||
break;
|
||||
default:
|
||||
AF_ERROR("invalid cmd %d\n", cmd_obj->valueint);
|
||||
return -1;
|
||||
|
@ -64,6 +64,25 @@ load_rule()
|
||||
config_apply "$json_str"
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
load_mac_list()
|
||||
{
|
||||
json_init
|
||||
config_load appfilter
|
||||
json_add_int "op" 4
|
||||
json_add_object "data"
|
||||
json_add_array "mac_list"
|
||||
config_get appid_list "user" "users"
|
||||
echo "appid list=$appid_list"
|
||||
for appid in $appid_list:
|
||||
do
|
||||
echo "appid=$appid"
|
||||
json_add_string "" $appid
|
||||
done
|
||||
json_str=`json_dump`
|
||||
config_apply "$json_str"
|
||||
echo "json str=$json_str"
|
||||
json_cleanup
|
||||
}
|
||||
clean_rule
|
||||
load_rule
|
||||
load_mac_list
|
||||
|
Loading…
Reference in New Issue
Block a user