Format code

This commit is contained in:
Derry 2021-04-13 02:31:15 -07:00
parent b0c763a45f
commit 29f297997f
8 changed files with 1229 additions and 1095 deletions

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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>
@ -35,228 +35,243 @@ 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);
config_init_package(const char *config)
{
struct uci_context *ctx = uci_ctx;
struct uci_package *p = NULL;
} 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;
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 "";
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};
void init_app_name_table(void)
{
int count = 0;
char line_buf[2048] = {0};
FILE * fp = fopen("/etc/appfilter/feature.cfg", "r");
if (!fp){
printf("open file failed\n");
return;
}
FILE *fp = fopen("/etc/appfilter/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);
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("/etc/appfilter/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", &class_id, class_name);
strcpy(CLASS_NAME_TABLE[class_id - 1], class_name);
g_cur_class_num++;
}
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("/etc/appfilter/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", &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;
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");
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;
af_ctl_time_t *load_appfilter_ctl_time_config(void)
{
int ret = 0;
af_ctl_time_t *t = NULL;
appfilter_config_alloc();
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");
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(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;
}
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 *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, " "));
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);
//printf("start:%s, end:%s, days:%s\n", start_time_str, end_time_str,
// days_str);
EXIT3:
if (days_str)
free(days_str);
if (days_str)
free(days_str);
EXIT2:
if (end_time_str)
free(end_time_str);
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;
if (start_time_str)
free(start_time_str);
appfilter_config_free();
//if (t)
// dump_af_time(t);
return t;
}
int config_get_appfilter_enable(void){
int ret = 0;
int config_get_appfilter_enable(void)
{
int ret = 0;
int enable = 0;
af_ctl_time_t *t = NULL;
af_ctl_time_t *t = NULL;
appfilter_config_alloc();
struct uci_section *global_sec = uci_lookup_section(uci_ctx, uci_appfilter, "global");
if (!global_sec){
printf("get time section failed\n");
return NULL;
}
appfilter_config_alloc();
struct uci_section *global_sec = uci_lookup_section(uci_ctx, uci_appfilter, "global");
if (!global_sec)
{
printf("get time section failed\n");
return NULL;
}
char *enable_opt = uci_lookup_option_string(uci_ctx, global_sec, "enable");
if (!enable_opt){
char *enable_opt = uci_lookup_option_string(uci_ctx, global_sec, "enable");
if (!enable_opt)
{
return 0;
}
enable = atoi(enable_opt);
printf("enable str = %s, enable = %d\n", enable_opt, enable);
free(enable_opt);
appfilter_config_free();
return enable;
enable = atoi(enable_opt);
free(enable_opt);
appfilter_config_free();
return enable;
}
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;
}
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;
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;
}
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;
}
}

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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.
*/
#ifndef __APPFILTER_CONFIG_H__
#define __APPFILTER_CONFIG_H__
@ -27,20 +27,23 @@
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 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;
char name[64];
}app_name_info_t;
typedef struct app_name_info
{
int id;
char name[64];
} app_name_info_t;
void init_app_name_table(void);
void init_app_class_name_table(void);
char *get_app_name_by_id(int id);
@ -51,5 +54,4 @@ int appfilter_config_free(void);
af_ctl_time_t *load_appfilter_ctl_time_config(void);
int config_get_appfilter_enable(void);
#endif

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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>
@ -39,178 +39,191 @@
void appfilter_nl_handler(struct uloop_fd *u, unsigned int ev)
{
int ret;
int i;
char buf[MAX_NL_RCV_BUF_SIZE];
struct sockaddr_nl nladdr;
struct iovec iov = {buf, sizeof(buf)};
struct nlmsghdr *h;
int i;
char buf[MAX_NL_RCV_BUF_SIZE];
struct sockaddr_nl nladdr;
struct iovec iov = {buf, sizeof(buf)};
struct nlmsghdr *h;
char *mac = NULL;
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
do{
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
do
{
ret = recvmsg(u->fd, &msg, 0);
} while ((-1 == ret) && (EINTR == errno));
if (ret < 0) {
printf("recv msg error\n");
return;
}
else if (0 == ret) {
return;
}
h = (struct nlmsghdr *)buf;
if (ret < 0)
{
printf("recv msg error\n");
return;
}
else if (0 == ret)
{
return;
}
h = (struct nlmsghdr *)buf;
char *kmsg = (char *)NLMSG_DATA(h);
struct af_msg_hdr *af_hdr = (struct af_msg_hdr *)kmsg;
if (af_hdr->magic != 0xa0b0c0d0){
if (af_hdr->magic != 0xa0b0c0d0)
{
printf("magic error %x\n", af_hdr->magic);
return;
return;
}
if (af_hdr->len <= 0 || af_hdr->len >= MAX_OAF_NETLINK_MSG_LEN){
if (af_hdr->len <= 0 || af_hdr->len >= MAX_OAF_NETLINK_MSG_LEN)
{
printf("data len error\n");
return;
}
char *kdata = kmsg + sizeof(struct af_msg_hdr);
struct json_object *root = json_tokener_parse(kdata);
if (!root){
printf("parse json failed:%s", kdata);
return;
}
struct json_object *mac_obj = json_object_object_get(root,"mac");
if (!mac_obj){
printf("parse mac obj failed\n");
json_object_put(root);
struct json_object *root = json_tokener_parse(kdata);
if (!root)
{
printf("parse json failed:%s", kdata);
return;
}
mac = json_object_get_string(mac_obj);
dev_node_t *node = find_dev_node(mac);
if (!node){
node = add_dev_node(mac);
if (!node){
printf("add dev node failed\n");
json_object_put(root);
return;
}
struct json_object *mac_obj = json_object_object_get(root, "mac");
if (!mac_obj)
{
printf("parse mac obj failed\n");
json_object_put(root);
return;
}
mac = json_object_get_string(mac_obj);
dev_node_t *node = find_dev_node(mac);
if (!node)
{
node = add_dev_node(mac);
if (!node)
{
printf("add dev node failed\n");
json_object_put(root);
return;
}
}
struct json_object *ip_obj = json_object_object_get(root, "ip");
if (ip_obj)
strncpy(node->ip, json_object_get_string(ip_obj), sizeof(node->ip));
struct json_object *visit_array = json_object_object_get(root, "visit_info");
if (!visit_array){
json_object_put(root);
return;
}
for (i = 0; i < json_object_array_length(visit_array); i++){
struct json_object *visit_obj = json_object_array_get_idx(visit_array, i);
struct json_object *appid_obj = json_object_object_get(visit_obj, "appid");
if (!visit_array)
{
json_object_put(root);
return;
}
for (i = 0; i < json_object_array_length(visit_array); i++)
{
struct json_object *visit_obj = json_object_array_get_idx(visit_array, i);
struct json_object *appid_obj = json_object_object_get(visit_obj, "appid");
struct json_object *action_obj = json_object_object_get(visit_obj, "latest_action");
struct json_object *up_obj = json_object_object_get(visit_obj, "up_bytes");
struct json_object *up_obj = json_object_object_get(visit_obj, "up_bytes");
struct json_object *down_obj = json_object_object_get(visit_obj, "down_bytes");
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
int appid = json_object_get_int(appid_obj);
int action = json_object_get_int(action_obj);
int type = appid / 1000;
int id = appid % 1000;
node->stat[type - 1][id - 1].total_time += REPORT_INTERVAL_SECS;
// node->stat[type - 1][id - 1].total_down_bytes += json_object_get_int(down_obj);
// node->stat[type - 1][id - 1].total_up_bytes += json_object_get_int(up_obj);
int type = appid / 1000;
int id = appid % 1000;
int hash = hash_appid(appid);
visit_info_t *head = node->visit_htable[hash];
if (head && (cur_time.tv_sec - head->latest_time) < 300){
printf("update visit info curtime=%d, last time=%d\n", cur_time.tv_sec, head->latest_time);
head->latest_time = cur_time.tv_sec;
}
else{
visit_info_t *visit_node = (visit_info_t *)calloc(1, sizeof(visit_info_t));
visit_node->action = action;
visit_node->appid = appid;
visit_node->latest_time = cur_time.tv_sec;
visit_node->first_time = cur_time.tv_sec - MIN_VISIT_TIME;
visit_node->next = NULL;
add_visit_info_node(&node->visit_htable[hash], visit_node);
//printf("add visit info curtime=%d\n", cur_time.tv_sec);
}
}
json_object_put(root);
node->stat[type - 1][id - 1].total_time += REPORT_INTERVAL_SECS;
// node->stat[type - 1][id - 1].total_down_bytes += json_object_get_int(down_obj);
// node->stat[type - 1][id - 1].total_up_bytes += json_object_get_int(up_obj);
int hash = hash_appid(appid);
visit_info_t *head = node->visit_htable[hash];
if (head && (cur_time.tv_sec - head->latest_time) < 300)
{
printf("update visit info curtime=%d, last time=%d\n", cur_time.tv_sec, head->latest_time);
head->latest_time = cur_time.tv_sec;
}
else
{
visit_info_t *visit_node = (visit_info_t *)calloc(1, sizeof(visit_info_t));
visit_node->action = action;
visit_node->appid = appid;
visit_node->latest_time = cur_time.tv_sec;
visit_node->first_time = cur_time.tv_sec - MIN_VISIT_TIME;
visit_node->next = NULL;
add_visit_info_node(&node->visit_htable[hash], visit_node);
//printf("add visit info curtime=%d\n", cur_time.tv_sec);
}
}
json_object_put(root);
}
#define MAX_NL_MSG_LEN 1024
int send_msg_to_kernel(int fd, void *msg, int len){
struct sockaddr_nl saddr, daddr;
memset(&daddr, 0, sizeof(daddr));
int send_msg_to_kernel(int fd, void *msg, int len)
{
struct sockaddr_nl saddr, daddr;
memset(&daddr, 0, sizeof(daddr));
daddr.nl_family = AF_NETLINK;
daddr.nl_pid = 0; // to kernel
daddr.nl_pid = 0; // to kernel
daddr.nl_groups = 0;
int ret = 0;
struct nlmsghdr *nlh = NULL;
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_NL_MSG_LEN));
int ret = 0;
struct nlmsghdr *nlh = NULL;
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_NL_MSG_LEN));
nlh->nlmsg_len = NLMSG_SPACE(MAX_NL_MSG_LEN);
nlh->nlmsg_flags = 0;
nlh->nlmsg_type = 0;
nlh->nlmsg_seq = 0;
nlh->nlmsg_pid = DEFAULT_USR_NL_PID;
nlh->nlmsg_pid = DEFAULT_USR_NL_PID;
char msg_buf[MAX_NL_MSG_LEN] = {0};
struct af_msg_hdr *hdr = (struct af_msg_hdr *)msg_buf;
hdr->magic = 0xa0b0c0d0;
hdr->len = len;
char *p_data = msg_buf + sizeof(struct af_msg_hdr);
memcpy(p_data, msg, len);
char msg_buf[MAX_NL_MSG_LEN] = {0};
struct af_msg_hdr *hdr = (struct af_msg_hdr *)msg_buf;
hdr->magic = 0xa0b0c0d0;
hdr->len = len;
char *p_data = msg_buf + sizeof(struct af_msg_hdr);
memcpy(p_data, msg, len);
// memset(nlh, 0, sizeof(struct nlmsghdr));
// memset(nlh, 0, sizeof(struct nlmsghdr));
memcpy(NLMSG_DATA(nlh), msg_buf, len + sizeof(struct af_msg_hdr));
ret = sendto(fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
if(!ret)
if (!ret)
{
perror("sendto error\n");
return -1;
return -1;
}
return 0;
return 0;
}
int appfilter_nl_init(void)
{
int fd;
struct sockaddr_nl nls;
struct sockaddr_nl nls;
fd = socket(AF_NETLINK, SOCK_RAW, OAF_NETLINK_ID);
if(fd < 0)
if (fd < 0)
{
printf("Connect netlink %d failed %s", OAF_NETLINK_ID, strerror(errno));
exit(1);
}
exit(1);
}
memset(&nls, 0, sizeof(struct sockaddr_nl));
nls.nl_pid = DEFAULT_USR_NL_PID;
nls.nl_groups = 0;
nls.nl_family = AF_NETLINK;
if (bind(fd, (void *)&nls, sizeof(struct sockaddr_nl))) {
if (bind(fd, (void *)&nls, sizeof(struct sockaddr_nl)))
{
printf("Bind failed %s\n", strerror(errno));
exit(1);
}
}
return fd;
}

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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.
*/
#ifndef __APPFILTER_NETLINK_H__
#define __APPFILTER_NETLINK_H__
@ -25,20 +25,23 @@
#define OAF_NETLINK_ID 29
#define MAX_OAF_NETLINK_MSG_LEN 1024
struct af_msg_hdr{
struct af_msg_hdr
{
int magic;
int len;
};
enum E_MSG_TYPE{
AF_MSG_INIT,
AF_MSG_MAX
enum E_MSG_TYPE
{
AF_MSG_INIT,
AF_MSG_MAX
};
typedef struct af_msg{
int action;
void *data;
}af_msg_t;
typedef struct af_msg
{
int action;
void *data;
} af_msg_t;
int appfilter_nl_init(void);
void appfilter_nl_handler(struct uloop_fd *u, unsigned int ev);
int send_msg_to_kernel(int fd, void *msg, int len);

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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>
@ -39,449 +39,484 @@
struct ubus_context *ubus_ctx = NULL;
static struct blob_buf b;
extern char * format_time(int timetamp);
extern char *format_time(int timetamp);
void get_hostname_by_mac(char *mac, char *hostname){
if (!mac || !hostname)
return;
FILE *fp = fopen("/tmp/dhcp.leases", "r");
if (!fp){
printf("open dhcp lease file....failed\n");
return;
}
char line_buf[256] = {0};
while(fgets(line_buf, sizeof(line_buf), fp)){
char hostname_buf[128] = {0};
char mac_buf[32] = {0};
sscanf(line_buf, "%*s %s %*s %s", mac_buf, hostname_buf);
if (0 == strcmp(mac, mac_buf)){
strcpy(hostname, hostname_buf);
}
}
fclose(fp);
}
void ubus_dump_visit_list(struct blob_buf *b, char *mac){
int i, j;
void *c, *array;
void *t;
void *s;
array = blobmsg_open_array(b, "dev_list");
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
dev_node_t *node = dev_hash_table[i];
while(node){
if (mac && strcmp(mac, node->mac)){
node = node->next;
continue;
}
t = blobmsg_open_table(b, NULL);
blobmsg_add_string(b, "hostname", "unknown");
blobmsg_add_string(b, "mac", node->mac);
blobmsg_add_string(b, "ip", node->ip);
void *visit_array;
visit_array = blobmsg_open_array(b, "visit_info");
for (j = 0; j < MAX_VISIT_HASH_SIZE; j++){
visit_info_t *p_info = node->visit_htable[j];
while(p_info){
char *first_time_str = format_time(p_info->first_time);
char *latest_time_str = format_time(p_info->latest_time);
int total_time = p_info->latest_time - p_info->first_time;
s = blobmsg_open_table(b, NULL);
blobmsg_add_string(b, "appname", "unknown");
blobmsg_add_u32(b, "appid", p_info->appid);
blobmsg_add_u32(b, "latest_action", p_info->action);
blobmsg_add_u32(b, "first_time", p_info->first_time);
blobmsg_add_u32(b, "latest_time", p_info->latest_time);
blobmsg_close_table(b, s);
if (first_time_str)
free(first_time_str);
if (latest_time_str)
free(latest_time_str);
p_info = p_info->next;
}
}
blobmsg_close_array(b, visit_array);
blobmsg_close_table(b, t);
node = node->next;
void get_hostname_by_mac(char *mac, char *hostname)
{
if (!mac || !hostname)
return;
FILE *fp = fopen("/tmp/dhcp.leases", "r");
if (!fp)
{
printf("open dhcp lease file....failed\n");
return;
}
char line_buf[256] = {0};
while (fgets(line_buf, sizeof(line_buf), fp))
{
char hostname_buf[128] = {0};
char mac_buf[32] = {0};
sscanf(line_buf, "%*s %s %*s %s", mac_buf, hostname_buf);
if (0 == strcmp(mac, mac_buf))
{
strcpy(hostname, hostname_buf);
}
}
blobmsg_close_array(b, array);
fclose(fp);
}
void update_app_visit_time_list(char *mac, struct app_visit_stat_info *visit_info){
int i, j, s;
int num = 0;
dev_node_t *node = find_dev_node(mac);
if (!node){
printf("not found mac:%s\n", mac);
return;
}
for (i = 0; i < MAX_APP_TYPE; i++){
for (j = 0; j < MAX_APP_ID_NUM; j++){
unsigned long long min = visit_info->visit_list[0].total_time;
int min_index = 0;
if (node->stat[i][j].total_time == 0)
continue;
if (num < MAX_APP_STAT_NUM){
min_index = num;
}
else{
for (s = 0; s < MAX_APP_STAT_NUM; s++){
if (visit_info->visit_list[s].total_time < min){
min_index = s;
break;
}
}
}
num++;
if (node->stat[i][j].total_time > visit_info->visit_list[min_index].total_time){
visit_info->visit_list[min_index].total_time = node->stat[i][j].total_time;
visit_info->visit_list[min_index].app_id = (i + 1) * 1000 + j + 1;
}
}
}
if (num < MAX_APP_STAT_NUM)
visit_info->num = num;
else
visit_info->num = MAX_APP_STAT_NUM;
}
void update_app_class_visit_time_list(char *mac, int *visit_time){
int i, j, s;
int num = 0;
dev_node_t *node = find_dev_node(mac);
if (!node){
printf("not found mac:%s\n", mac);
return;
}
for (i = 0; i < MAX_APP_TYPE; i++){
for (j = 0; j < MAX_APP_ID_NUM; j++){
if (node->stat[i][j].total_time == 0)
continue;
visit_time[i] += node->stat[i][j].total_time;
}
}
}
void ubus_get_dev_visit_time_info(char *mac, struct blob_buf *b){
void ubus_dump_visit_list(struct blob_buf *b, char *mac)
{
int i, j;
void *c, *array;
void *t;
void *s;
struct app_visit_stat_info info;
memset((char *)&info, 0x0, sizeof(info));
update_app_visit_time_list(mac, &info);
void *c, *array;
void *t;
void *s;
array = blobmsg_open_array(b, "dev_list");
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while (node)
{
if (mac && strcmp(mac, node->mac))
{
node = node->next;
continue;
}
t = blobmsg_open_table(b, NULL);
blobmsg_add_string(b, "hostname", "unknown");
blobmsg_add_string(b, "mac", node->mac);
blobmsg_add_string(b, "ip", node->ip);
void *visit_array;
visit_array = blobmsg_open_array(b, "visit_info");
for (j = 0; j < MAX_VISIT_HASH_SIZE; j++)
{
visit_info_t *p_info = node->visit_htable[j];
while (p_info)
{
char *first_time_str = format_time(p_info->first_time);
char *latest_time_str = format_time(p_info->latest_time);
int total_time = p_info->latest_time - p_info->first_time;
s = blobmsg_open_table(b, NULL);
blobmsg_add_string(b, "appname", "unknown");
blobmsg_add_u32(b, "appid", p_info->appid);
blobmsg_add_u32(b, "latest_action", p_info->action);
blobmsg_add_u32(b, "first_time", p_info->first_time);
blobmsg_add_u32(b, "latest_time", p_info->latest_time);
blobmsg_close_table(b, s);
if (first_time_str)
free(first_time_str);
if (latest_time_str)
free(latest_time_str);
p_info = p_info->next;
}
}
blobmsg_close_array(b, visit_array);
blobmsg_close_table(b, t);
node = node->next;
}
}
blobmsg_close_array(b, array);
}
void update_app_visit_time_list(char *mac, struct app_visit_stat_info *visit_info)
{
int i, j, s;
int num = 0;
dev_node_t *node = find_dev_node(mac);
if (!node)
{
printf("not found mac:%s\n", mac);
return;
}
for (i = 0; i < MAX_APP_TYPE; i++)
{
for (j = 0; j < MAX_APP_ID_NUM; j++)
{
unsigned long long min = visit_info->visit_list[0].total_time;
int min_index = 0;
if (node->stat[i][j].total_time == 0)
continue;
if (num < MAX_APP_STAT_NUM)
{
min_index = num;
}
else
{
for (s = 0; s < MAX_APP_STAT_NUM; s++)
{
if (visit_info->visit_list[s].total_time < min)
{
min_index = s;
break;
}
}
}
num++;
if (node->stat[i][j].total_time > visit_info->visit_list[min_index].total_time)
{
visit_info->visit_list[min_index].total_time = node->stat[i][j].total_time;
visit_info->visit_list[min_index].app_id = (i + 1) * 1000 + j + 1;
}
}
}
if (num < MAX_APP_STAT_NUM)
visit_info->num = num;
else
visit_info->num = MAX_APP_STAT_NUM;
}
void update_app_class_visit_time_list(char *mac, int *visit_time)
{
int i, j, s;
int num = 0;
dev_node_t *node = find_dev_node(mac);
if (!node)
{
printf("not found mac:%s\n", mac);
return;
}
for (i = 0; i < MAX_APP_TYPE; i++)
{
for (j = 0; j < MAX_APP_ID_NUM; j++)
{
if (node->stat[i][j].total_time == 0)
continue;
visit_time[i] += node->stat[i][j].total_time;
}
}
}
void ubus_get_dev_visit_time_info(char *mac, struct blob_buf *b)
{
int i, j;
void *c, *array;
void *t;
void *s;
struct app_visit_stat_info info;
memset((char *)&info, 0x0, sizeof(info));
update_app_visit_time_list(mac, &info);
}
static int
appfilter_handle_visit_list(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret;
blob_buf_init(&b, 0);
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str){
printf("format json failed\n");
return 0;
}
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if(!mac_obj){
ubus_dump_visit_list(&b, NULL);
}
else
ubus_dump_visit_list(&b, json_object_get_string(mac_obj));
ubus_send_reply(ctx, req, b.head);
return 0;
int ret;
blob_buf_init(&b, 0);
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str)
{
printf("format json failed\n");
return 0;
}
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if (!mac_obj)
{
ubus_dump_visit_list(&b, NULL);
}
else
ubus_dump_visit_list(&b, json_object_get_string(mac_obj));
ubus_send_reply(ctx, req, b.head);
return 0;
}
typedef struct app_visit_time_info
{
int app_id;
unsigned long long total_time;
} app_visit_time_info_t;
typedef struct app_visit_time_info{
int app_id;
unsigned long long total_time;
}app_visit_time_info_t;
int visit_time_compare(const void *a, const void *b){
app_visit_time_info_t *p1 = (app_visit_time_info_t *)a;
app_visit_time_info_t *p2 = (app_visit_time_info_t *)b;
return p1->total_time < p2->total_time ? 1: -1;
int visit_time_compare(const void *a, const void *b)
{
app_visit_time_info_t *p1 = (app_visit_time_info_t *)a;
app_visit_time_info_t *p2 = (app_visit_time_info_t *)b;
return p1->total_time < p2->total_time ? 1 : -1;
}
#define MAX_STAT_APP_NUM 128
void update_top5_app(dev_node_t *node, app_visit_time_info_t top5_app_list[]){
int i, j;
//memset(app_array, 0x0, sizeof(int) *size);
app_visit_time_info_t app_visit_array[MAX_STAT_APP_NUM];
memset(app_visit_array, 0x0, sizeof(app_visit_array));
int app_visit_num = 0;
void update_top5_app(dev_node_t *node, app_visit_time_info_t top5_app_list[])
{
int i, j;
//memset(app_array, 0x0, sizeof(int) *size);
app_visit_time_info_t app_visit_array[MAX_STAT_APP_NUM];
memset(app_visit_array, 0x0, sizeof(app_visit_array));
int app_visit_num = 0;
for (i = 0; i < MAX_APP_TYPE; i++){
for (j = 0; j < MAX_APP_ID_NUM; j++){
if (node->stat[i][j].total_time == 0)
continue;
app_visit_array[app_visit_num].app_id = (i + 1) * 1000 + j + 1;
app_visit_array[app_visit_num].total_time = node->stat[i][j].total_time;
app_visit_num++;
}
}
for (i = 0; i < MAX_APP_TYPE; i++)
{
for (j = 0; j < MAX_APP_ID_NUM; j++)
{
if (node->stat[i][j].total_time == 0)
continue;
app_visit_array[app_visit_num].app_id = (i + 1) * 1000 + j + 1;
app_visit_array[app_visit_num].total_time = node->stat[i][j].total_time;
app_visit_num++;
}
}
qsort((void *)app_visit_array, app_visit_num, sizeof(app_visit_time_info_t), visit_time_compare);
#if 0
for (i = 0; i < app_visit_num; i++){
printf("appid %d-----------total time %llu\n", app_visit_array[i].app_id,
app_visit_array[i].total_time);
}
#endif
for (i = 0; i < 5; i++){
top5_app_list[i] = app_visit_array[i];
//printf("appid %d-----------total time %llu\n", app_visit_array[i].app_id,
// app_visit_array[i].total_time);
}
qsort((void *)app_visit_array, app_visit_num, sizeof(app_visit_time_info_t), visit_time_compare);
#if 0
for (i = 0; i < app_visit_num; i++){
printf("appid %d-----------total time %llu\n", app_visit_array[i].app_id,
app_visit_array[i].total_time);
}
#endif
for (i = 0; i < 5; i++)
{
top5_app_list[i] = app_visit_array[i];
//printf("appid %d-----------total time %llu\n", app_visit_array[i].app_id,
// app_visit_array[i].total_time);
}
}
static int
appfilter_handle_dev_list(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int i, j;
struct json_object * root_obj = json_object_new_object();
struct json_object * dev_array = json_object_new_array();
int count = 0;
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
dev_node_t *node = dev_hash_table[i];
while(node){
if (node->online == 0){
node = node->next;
continue;
}
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);
for (j = 0; j < 5; j++){
if (top5_app_list[j].app_id == 0)
break;
struct json_object * app_obj = json_object_new_object();
json_object_object_add(app_obj, "id", json_object_new_int(top5_app_list[j].app_id));
json_object_object_add(app_obj, "name", json_object_new_string(get_app_name_by_id(top5_app_list[j].app_id)));
json_object_array_add(app_array, app_obj);
}
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};
get_hostname_by_mac(node->mac, hostname);
json_object_object_add(dev_obj, "ip", json_object_new_string(node->ip));
json_object_object_add(dev_obj, "online", json_object_new_int(1));
json_object_object_add(dev_obj, "hostname", json_object_new_string(hostname));
json_object_object_add(dev_obj, "latest_app", json_object_new_string("test"));
json_object_array_add(dev_array, dev_obj);
int i, j;
struct json_object *root_obj = json_object_new_object();
node = node->next;
count++;
if (count >= MAX_SUPPORT_DEV_NUM)
goto END;
struct json_object *dev_array = json_object_new_array();
int count = 0;
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while (node)
{
if (node->online == 0)
{
node = node->next;
continue;
}
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);
for (j = 0; j < 5; j++)
{
if (top5_app_list[j].app_id == 0)
break;
struct json_object *app_obj = json_object_new_object();
json_object_object_add(app_obj, "id", json_object_new_int(top5_app_list[j].app_id));
json_object_object_add(app_obj, "name", json_object_new_string(get_app_name_by_id(top5_app_list[j].app_id)));
json_object_array_add(app_array, app_obj);
}
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};
get_hostname_by_mac(node->mac, hostname);
json_object_object_add(dev_obj, "ip", json_object_new_string(node->ip));
json_object_object_add(dev_obj, "online", json_object_new_int(1));
json_object_object_add(dev_obj, "hostname", json_object_new_string(hostname));
json_object_object_add(dev_obj, "latest_app", json_object_new_string("test"));
json_object_array_add(dev_array, dev_obj);
node = node->next;
count++;
if (count >= MAX_SUPPORT_DEV_NUM)
goto END;
}
}
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
dev_node_t *node = dev_hash_table[i];
while(node){
if (node->online != 0){
node = node->next;
continue;
}
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);
for (j = 0; j < 5; j++){
if (top5_app_list[j].app_id == 0)
break;
struct json_object * app_obj = json_object_new_object();
json_object_object_add(app_obj, "id", json_object_new_int(top5_app_list[j].app_id));
json_object_object_add(app_obj, "name", json_object_new_string(get_app_name_by_id(top5_app_list[j].app_id)));
json_object_array_add(app_array, app_obj);
}
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};
get_hostname_by_mac(node->mac, hostname);
json_object_object_add(dev_obj, "ip", json_object_new_string(node->ip));
json_object_object_add(dev_obj, "online", json_object_new_int(0));
json_object_object_add(dev_obj, "hostname", json_object_new_string(hostname));
json_object_object_add(dev_obj, "latest_app", json_object_new_string("test"));
json_object_array_add(dev_array, dev_obj);
node = node->next;
count++;
if (count >= MAX_SUPPORT_DEV_NUM)
goto END;
}
}
END:
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while (node)
{
if (node->online != 0)
{
json_object_object_add(root_obj, "devlist", dev_array);
blob_buf_init(&b, 0);
blobmsg_add_object(&b, root_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(root_obj);
return 0;
node = node->next;
continue;
}
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);
for (j = 0; j < 5; j++)
{
if (top5_app_list[j].app_id == 0)
break;
struct json_object *app_obj = json_object_new_object();
json_object_object_add(app_obj, "id", json_object_new_int(top5_app_list[j].app_id));
json_object_object_add(app_obj, "name", json_object_new_string(get_app_name_by_id(top5_app_list[j].app_id)));
json_object_array_add(app_array, app_obj);
}
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};
get_hostname_by_mac(node->mac, hostname);
json_object_object_add(dev_obj, "ip", json_object_new_string(node->ip));
json_object_object_add(dev_obj, "online", json_object_new_int(0));
json_object_object_add(dev_obj, "hostname", json_object_new_string(hostname));
json_object_object_add(dev_obj, "latest_app", json_object_new_string("test"));
json_object_array_add(dev_array, dev_obj);
node = node->next;
count++;
if (count >= MAX_SUPPORT_DEV_NUM)
goto END;
}
}
END:
json_object_object_add(root_obj, "devlist", dev_array);
blob_buf_init(&b, 0);
blobmsg_add_object(&b, root_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(root_obj);
return 0;
}
static int
appfilter_handle_visit_time(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret;
struct app_visit_stat_info info;
blob_buf_init(&b, 0);
memset((char *)&info, 0x0, sizeof(info));
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str){
printf("format json failed\n");
return 0;
}
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if(!mac_obj){
printf("mac is NULL\n");
return 0;
}
update_app_visit_time_list(json_object_get_string(mac_obj), &info);
int ret;
struct app_visit_stat_info info;
blob_buf_init(&b, 0);
memset((char *)&info, 0x0, sizeof(info));
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str)
{
printf("format json failed\n");
return 0;
}
struct json_object *resp_obj = json_object_new_object();
struct json_object *app_info_array = json_object_new_array();
json_object_object_add(resp_obj,"app_list", app_info_array);
int i;
for (i = 0; i < info.num; i++){
struct json_object *app_info_obj = json_object_new_object();
json_object_object_add(app_info_obj, "app_id",
json_object_new_string(get_app_name_by_id(info.visit_list[i].app_id)));
json_object_object_add(app_info_obj, "visit_time",
json_object_new_int(info.visit_list[i].total_time));
json_object_array_add(app_info_array, app_info_obj);
}
blobmsg_add_object(&b, resp_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(resp_obj);
json_object_put(req_obj);
return 0;
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if (!mac_obj)
{
printf("mac is NULL\n");
return 0;
}
update_app_visit_time_list(json_object_get_string(mac_obj), &info);
struct json_object *resp_obj = json_object_new_object();
struct json_object *app_info_array = json_object_new_array();
json_object_object_add(resp_obj, "app_list", app_info_array);
int i;
for (i = 0; i < info.num; i++)
{
struct json_object *app_info_obj = json_object_new_object();
json_object_object_add(app_info_obj, "app_id",
json_object_new_string(get_app_name_by_id(info.visit_list[i].app_id)));
json_object_object_add(app_info_obj, "visit_time",
json_object_new_int(info.visit_list[i].total_time));
json_object_array_add(app_info_array, app_info_obj);
}
blobmsg_add_object(&b, resp_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(resp_obj);
json_object_put(req_obj);
return 0;
}
static int
handle_app_class_visit_time(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret;
int i;
blob_buf_init(&b, 0);
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str){
printf("format json failed\n");
return 0;
}
int ret;
int i;
blob_buf_init(&b, 0);
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str)
{
printf("format json failed\n");
return 0;
}
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if(!mac_obj){
printf("mac is NULL\n");
return 0;
}
int app_class_visit_time[MAX_APP_TYPE];
memset(app_class_visit_time, 0x0, sizeof(app_class_visit_time));
update_app_class_visit_time_list(json_object_get_string(mac_obj), app_class_visit_time);
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *mac_obj = json_object_object_get(req_obj, "mac");
if (!mac_obj)
{
printf("mac is NULL\n");
return 0;
}
int app_class_visit_time[MAX_APP_TYPE];
memset(app_class_visit_time, 0x0, sizeof(app_class_visit_time));
update_app_class_visit_time_list(json_object_get_string(mac_obj), app_class_visit_time);
struct json_object *resp_obj = json_object_new_object();
struct json_object *app_class_array = json_object_new_array();
json_object_object_add(resp_obj,"class_list", app_class_array);
for (i = 0; i < MAX_APP_TYPE; i++){
if (i >= g_cur_class_num)
break;
struct json_object *app_class_obj = json_object_new_object();
json_object_object_add(app_class_obj, "type", json_object_new_int(i));
json_object_object_add(app_class_obj, "name", json_object_new_string(CLASS_NAME_TABLE[i]));
json_object_object_add(app_class_obj, "visit_time", json_object_new_int(app_class_visit_time[i]));
json_object_array_add(app_class_array, app_class_obj);
}
blobmsg_add_object(&b, resp_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(resp_obj);
json_object_put(req_obj);
return 0;
struct json_object *resp_obj = json_object_new_object();
struct json_object *app_class_array = json_object_new_array();
json_object_object_add(resp_obj, "class_list", app_class_array);
for (i = 0; i < MAX_APP_TYPE; i++)
{
if (i >= g_cur_class_num)
break;
struct json_object *app_class_obj = json_object_new_object();
json_object_object_add(app_class_obj, "type", json_object_new_int(i));
json_object_object_add(app_class_obj, "name", json_object_new_string(CLASS_NAME_TABLE[i]));
json_object_object_add(app_class_obj, "visit_time", json_object_new_int(app_class_visit_time[i]));
json_object_array_add(app_class_array, app_class_obj);
}
blobmsg_add_object(&b, resp_obj);
ubus_send_reply(ctx, req, b.head);
json_object_put(resp_obj);
json_object_put(req_obj);
return 0;
}
static const struct blobmsg_policy empty_policy[1] = {
//[DEV_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
//[DEV_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
};
static struct ubus_method appfilter_object_methods[] = {
UBUS_METHOD("visit_list", appfilter_handle_visit_list, empty_policy),
UBUS_METHOD("dev_visit_time", appfilter_handle_visit_time, empty_policy),
UBUS_METHOD("app_class_visit_time", handle_app_class_visit_time, empty_policy),
UBUS_METHOD("dev_list", appfilter_handle_dev_list, empty_policy),
UBUS_METHOD("visit_list", appfilter_handle_visit_list, empty_policy),
UBUS_METHOD("dev_visit_time", appfilter_handle_visit_time, empty_policy),
UBUS_METHOD("app_class_visit_time", handle_app_class_visit_time, empty_policy),
UBUS_METHOD("dev_list", appfilter_handle_dev_list, empty_policy),
};
static struct ubus_object_type main_object_type =
UBUS_OBJECT_TYPE("appfilter", appfilter_object_methods);
UBUS_OBJECT_TYPE("appfilter", appfilter_object_methods);
static struct ubus_object main_object = {
.name = "appfilter",
.type = &main_object_type,
.methods = appfilter_object_methods,
.n_methods = ARRAY_SIZE(appfilter_object_methods),
.name = "appfilter",
.type = &main_object_type,
.methods = appfilter_object_methods,
.n_methods = ARRAY_SIZE(appfilter_object_methods),
};
static void appfilter_add_object(struct ubus_object *obj)
{
int ret = ubus_add_object(ubus_ctx, obj);
int ret = ubus_add_object(ubus_ctx, obj);
if (ret != 0)
fprintf(stderr, "Failed to publish object '%s': %s\n", obj->name, ubus_strerror(ret));
if (ret != 0)
fprintf(stderr, "Failed to publish object '%s': %s\n", obj->name, ubus_strerror(ret));
}
int appfilter_ubus_init(void)
{
ubus_ctx = ubus_connect("/var/run/ubus.sock");
if (!ubus_ctx)
return -EIO;
ubus_ctx = ubus_connect("/var/run/ubus.sock");
if (!ubus_ctx)
return -EIO;
appfilter_add_object(&main_object);
ubus_add_uloop(ubus_ctx);
return 0;
appfilter_add_object(&main_object);
ubus_add_uloop(ubus_ctx);
return 0;
}

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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>
@ -35,48 +35,56 @@ dev_node_t *dev_hash_table[MAX_DEV_NODE_HASH_SIZE];
int g_cur_user_num = 0;
unsigned int hash_mac(unsigned char *mac)
{
if (!mac)
return 0;
else
return mac[0] & (MAX_DEV_NODE_HASH_SIZE - 1);
if (!mac)
return 0;
else
return mac[0] & (MAX_DEV_NODE_HASH_SIZE - 1);
}
int get_timestamp(void){
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
return cur_time.tv_sec;
int get_timestamp(void)
{
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
return cur_time.tv_sec;
}
int hash_appid(int appid){
return appid % (MAX_VISIT_HASH_SIZE - 1);
int hash_appid(int appid)
{
return appid % (MAX_VISIT_HASH_SIZE - 1);
}
void add_visit_info_node(visit_info_t **head, visit_info_t *node){
if (*head == NULL){
*head = node;
}
else{
node->next = *head;
*head = node;
}
void add_visit_info_node(visit_info_t **head, visit_info_t *node)
{
if (*head == NULL)
{
*head = node;
}
else
{
node->next = *head;
*head = node;
}
}
void init_dev_node_htable(){
void init_dev_node_htable()
{
int i;
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++){
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_hash_table[i] = NULL;
}
}
dev_node_t *add_dev_node(char *mac){
dev_node_t *add_dev_node(char *mac)
{
unsigned int hash = 0;
if (g_cur_user_num >= MAX_SUPPORT_USER_NUM){
printf("error, user num reach max %d\n", g_cur_user_num);
return NULL;
}
if (g_cur_user_num >= MAX_SUPPORT_USER_NUM)
{
printf("error, user num reach max %d\n", g_cur_user_num);
return NULL;
}
hash = hash_mac(mac);
if (hash >= MAX_DEV_NODE_HASH_SIZE){
if (hash >= MAX_DEV_NODE_HASH_SIZE)
{
printf("hash code error %d\n", hash);
return NULL;
}
@ -84,30 +92,35 @@ dev_node_t *add_dev_node(char *mac){
if (!node)
return NULL;
strncpy(node->mac, mac, sizeof(node->mac));
node->online = 1;
node->online_time = get_timestamp();
node->online = 1;
node->online_time = get_timestamp();
if (dev_hash_table[hash] == NULL)
dev_hash_table[hash] = node;
else{
else
{
node->next = dev_hash_table[hash];
dev_hash_table[hash] = node;
}
g_cur_user_num++;
g_cur_user_num++;
printf("add mac:%s to htable[%d]....success\n", mac, hash);
return node;
}
dev_node_t *find_dev_node(char *mac){
dev_node_t *find_dev_node(char *mac)
{
unsigned int hash = 0;
dev_node_t *p = NULL;
hash = hash_mac(mac);
if (hash >= MAX_DEV_NODE_HASH_SIZE){
if (hash >= MAX_DEV_NODE_HASH_SIZE)
{
printf("hash code error %d\n", hash);
return NULL;
}
p = dev_hash_table[hash];
while(p){
if (0 == strncmp(p->mac, mac, sizeof(p->mac))){
while (p)
{
if (0 == strncmp(p->mac, mac, sizeof(p->mac)))
{
return p;
}
p = p->next;
@ -115,181 +128,224 @@ dev_node_t *find_dev_node(char *mac){
return NULL;
}
void dev_foreach(void *arg, iter_func iter){
int i, j;
dev_node_t *node = NULL;
void dev_foreach(void *arg, iter_func iter)
{
int i, j;
dev_node_t *node = NULL;
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while(node){
while (node)
{
iter(arg, node);
node = node->next;
}
node = node->next;
}
}
}
char * format_time(int timetamp){
char time_buf[64] = {0};
time_t seconds = timetamp;
struct tm *auth_tm = localtime(&seconds);
strftime(time_buf, sizeof(time_buf), "%Y %m %d %H:%M:%S", auth_tm);
return strdup(time_buf);
char *format_time(int timetamp)
{
char time_buf[64] = {0};
time_t seconds = timetamp;
struct tm *auth_tm = localtime(&seconds);
strftime(time_buf, sizeof(time_buf), "%Y %m %d %H:%M:%S", auth_tm);
return strdup(time_buf);
}
void update_dev_hostname(void){
void update_dev_hostname(void)
{
char line_buf[256] = {0};
char hostname_buf[128] = {0};
char mac_buf[32] = {0};
char ip_buf[32] = {0};
char ip_buf[32] = {0};
FILE *fp = fopen("/tmp/dhcp.leases", "r");
if (!fp){
printf("open dhcp lease file....failed\n");
return;
}
while(fgets(line_buf, sizeof(line_buf), fp)){
if (strlen(line_buf) <= 16)
continue;
if (!fp)
{
printf("open dhcp lease file....failed\n");
return;
}
while (fgets(line_buf, sizeof(line_buf), fp))
{
if (strlen(line_buf) <= 16)
continue;
sscanf(line_buf, "%*s %s %s %s", mac_buf, ip_buf, hostname_buf);
dev_node_t *node = find_dev_node(mac_buf);
if (!node)
continue;
if (strlen(hostname_buf) > 0){
strncpy(node->hostname, hostname_buf, sizeof(node->hostname));
}
}
dev_node_t *node = find_dev_node(mac_buf);
if (!node)
continue;
if (strlen(hostname_buf) > 0)
{
strncpy(node->hostname, hostname_buf, sizeof(node->hostname));
}
}
fclose(fp);
}
void clean_dev_online_status(void){
int i;
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
void clean_dev_online_status(void)
{
int i;
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while(node){
node->online = 0;
node->offline_time = get_timestamp();
node = node->next;
}
while (node)
{
node->online = 0;
node->offline_time = get_timestamp();
node = node->next;
}
}
}
/*
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 check_dev_expire(void){
void check_dev_expire(void)
{
char line_buf[256] = {0};
char mac_buf[32] = {0};
char ip_buf[32] = {0};
FILE *fp = fopen("/proc/net/af_client", "r");
if (!fp){
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)){
while (fgets(line_buf, sizeof(line_buf), fp))
{
sscanf(line_buf, "%*s %s %s", mac_buf, ip_buf);
if (strlen(mac_buf) < 17){
if (strlen(mac_buf) < 17)
{
printf("invalid mac:%s\n", mac_buf);
continue;
}
dev_node_t *node = find_dev_node(mac_buf);
if (!node){
if (!node)
{
node = add_dev_node(mac_buf);
if (!node)
continue;
strncpy(node->ip, ip_buf, sizeof(node->ip));
}
node->online = 1;
}
fclose(fp);
}
void dump_dev_list(void){
void dump_dev_list(void)
{
int i, j;
int count = 0;
clean_dev_online_status();
update_dev_hostname();
check_dev_expire();
FILE *fp = fopen(OAF_DEV_LIST_FILE, "w");
if (!fp){
return;
}
fprintf(fp, "%-4s %-20s %-20s %-32s %-8s\n", "Id", "Mac Addr", "Ip Addr", "Hostname", "Online");
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
dev_node_t *node = dev_hash_table[i];
while(node){
if (node->online != 0){
if (strlen(node->hostname) == 0)
strcpy(node->hostname, "*");
fprintf(fp, "%-4d %-20s %-20s %-32s %-8d\n",
i + 1, node->mac, node->ip, node->hostname, node->online);
count++;
}
if (count >= MAX_SUPPORT_DEV_NUM){
goto EXIT;
}
node = node->next;
}
int count = 0;
char hostname_buf[MAX_HOSTNAME_SIZE] = {0};
char ip_buf[MAX_IP_LEN] = {0};
clean_dev_online_status();
update_dev_hostname();
check_dev_expire();
FILE *fp = fopen(OAF_DEV_LIST_FILE, "w");
if (!fp)
{
return;
}
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
fprintf(fp, "%-4s %-20s %-20s %-32s %-8s\n", "Id", "Mac Addr", "Ip Addr", "Hostname", "Online");
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while(node){
if (node->online == 0){
if (strlen(node->hostname) == 0)
strcpy(node->hostname, "*");
fprintf(fp, "%-4d %-20s %-20s %-32s %-8d\n",
i + 1, node->mac, node->ip, node->hostname, node->online);
}
if (count >= MAX_SUPPORT_DEV_NUM)
goto EXIT;
node = node->next;
}
while (node)
{
if (node->online != 0)
{
if (strlen(node->hostname) == 0)
strcpy(hostname_buf, "*");
else
strcpy(hostname_buf, node->hostname);
if (strlen(node->ip) == 0)
strcpy(ip_buf, "*");
else
strcpy(ip_buf, node->ip);
fprintf(fp, "%-4d %-20s %-20s %-32s %-8d\n",
i + 1, node->mac, ip_buf, hostname_buf, node->online);
count++;
}
if (count >= MAX_SUPPORT_DEV_NUM)
{
goto EXIT;
}
node = node->next;
}
}
EXIT:
fclose(fp);
}
void dump_dev_visit_list(void){
int i, j;
int count = 0;
FILE *fp = fopen(OAF_VISIT_LIST_FILE, "w");
if (!fp){
return;
}
fprintf(fp, "%-4s %-20s %-20s %-8s %-32s %-32s %-32s\n", "Id", "Mac Addr", \
"Ip Addr", "Appid", "First Time", "Latest Time", "Total Time(s)");
for (i = 0;i < MAX_DEV_NODE_HASH_SIZE; i++){
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while(node){
for (j = 0; j < MAX_VISIT_HASH_SIZE; j++){
visit_info_t *p_info = node->visit_htable[j];
while(p_info){
char *first_time_str = format_time(p_info->first_time);
char *latest_time_str = format_time(p_info->latest_time);
int total_time = p_info->latest_time - p_info->first_time;
fprintf(fp, "%-4d %-20s %-20s %-8d %-32s %-32s %-32d\n",
count, node->mac, node->ip, p_info->appid, first_time_str,
latest_time_str, total_time);
if (first_time_str)
free(first_time_str);
if (latest_time_str)
free(latest_time_str);
p_info = p_info->next;
count++;
if (count > 50)
goto EXIT;
}
}
node = node->next;
while (node)
{
if (node->online == 0)
{
if (strlen(node->hostname) == 0)
strcpy(hostname_buf, "*");
else
strcpy(hostname_buf, node->hostname);
if (strlen(node->ip) == 0)
strcpy(ip_buf, "*");
else
strcpy(ip_buf, node->ip);
fprintf(fp, "%-4d %-20s %-20s %-32s %-8d\n",
i + 1, node->mac, ip_buf, hostname_buf, node->online);
}
if (count >= MAX_SUPPORT_DEV_NUM)
goto EXIT;
node = node->next;
}
}
EXIT:
fclose(fp);
fclose(fp);
}
void dump_dev_visit_list(void)
{
int i, j;
int count = 0;
FILE *fp = fopen(OAF_VISIT_LIST_FILE, "w");
if (!fp)
{
return;
}
fprintf(fp, "%-4s %-20s %-20s %-8s %-32s %-32s %-32s\n", "Id", "Mac Addr",
"Ip Addr", "Appid", "First Time", "Latest Time", "Total Time(s)");
for (i = 0; i < MAX_DEV_NODE_HASH_SIZE; i++)
{
dev_node_t *node = dev_hash_table[i];
while (node)
{
for (j = 0; j < MAX_VISIT_HASH_SIZE; j++)
{
visit_info_t *p_info = node->visit_htable[j];
while (p_info)
{
char *first_time_str = format_time(p_info->first_time);
char *latest_time_str = format_time(p_info->latest_time);
int total_time = p_info->latest_time - p_info->first_time;
fprintf(fp, "%-4d %-20s %-20s %-8d %-32s %-32s %-32d\n",
count, node->mac, node->ip, p_info->appid, first_time_str,
latest_time_str, total_time);
if (first_time_str)
free(first_time_str);
if (latest_time_str)
free(latest_time_str);
p_info = p_info->next;
count++;
if (count > 50)
goto EXIT;
}
}
node = node->next;
}
}
EXIT:
fclose(fp);
}

View File

@ -1,95 +1,100 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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.
*/
#ifndef __FILTER_USER_H__
#define __FILTER_USER_H__
#define MAX_IP_LEN 32
#define MAX_MAC_LEN 32
#define MAX_VISIT_HASH_SIZE 64
#define MAX_DEV_NODE_HASH_SIZE 64
#define MAX_HOSTNAME_SIZE 64
#define MAX_SUPPORT_USER_NUM 64
#define MAX_IP_LEN 32
#define MAX_MAC_LEN 32
#define MAX_VISIT_HASH_SIZE 64
#define MAX_DEV_NODE_HASH_SIZE 64
#define MAX_HOSTNAME_SIZE 64
#define MAX_SUPPORT_USER_NUM 64
#define OAF_VISIT_LIST_FILE "/tmp/visit_list"
#define OAF_DEV_LIST_FILE "/tmp/dev_list"
#define MIN_VISIT_TIME 5 // default 5s
#define MAX_APP_STAT_NUM 8
#define MAX_VISITLIST_DUMP_NUM 16
#define MAX_APP_TYPE 16
#define MAX_APP_ID_NUM 128
#define MAX_APP_TYPE 16
#define MAX_APP_ID_NUM 128
#define MAX_SUPPORT_DEV_NUM 64
//extern dev_node_t *dev_hash_table[MAX_DEV_NODE_HASH_SIZE];
/*
{
"mac": "10:bf:48:37:0c:94",
"ip": "192.168.100.244",
"app_num": 0,
"visit_info": [{
"appid": 8002,
"latest_action": 1,
"latest_time": 1602604293,
"total_num": 4,
"drop_num": 4,
"history_info": []
}]
"mac": "10:bf:48:37:0c:94",
"ip": "192.168.100.244",
"app_num": 0,
"visit_info": [{
"appid": 8002,
"latest_action": 1,
"latest_time": 1602604293,
"total_num": 4,
"drop_num": 4,
"history_info": []
}]
}
*/
/* 单个访问记录结构 */
typedef struct visit_info{
int appid;
int first_time;
int latest_time;
int action;
struct visit_info *next;
}visit_info_t;
typedef struct visit_info
{
int appid;
int first_time;
int latest_time;
int action;
struct visit_info *next;
} visit_info_t;
/* 用于记录某个app总时间和总流量 */
typedef struct visit_stat{
unsigned long long total_time;
unsigned long long total_down_bytes;
unsigned long long total_up_bytes;
}visit_stat_t;
typedef struct visit_stat
{
unsigned long long total_time;
unsigned long long total_down_bytes;
unsigned long long total_up_bytes;
} visit_stat_t;
typedef struct dev_node{
typedef struct dev_node
{
char mac[MAX_MAC_LEN];
char ip[MAX_IP_LEN];
char hostname[MAX_HOSTNAME_SIZE];
int online;
int offline_time;
int online_time;
visit_info_t *visit_htable[MAX_VISIT_HASH_SIZE];
visit_stat_t stat[MAX_APP_TYPE][MAX_APP_ID_NUM];
char hostname[MAX_HOSTNAME_SIZE];
int online;
int offline_time;
int online_time;
visit_info_t *visit_htable[MAX_VISIT_HASH_SIZE];
visit_stat_t stat[MAX_APP_TYPE][MAX_APP_ID_NUM];
struct dev_node *next;
}dev_node_t;
} dev_node_t;
struct app_visit_info{
int app_id;
char app_name[32];
int total_time;
struct app_visit_info
{
int app_id;
char app_name[32];
int total_time;
};
struct app_visit_stat_info{
int num;
struct app_visit_info visit_list[MAX_APP_STAT_NUM];
struct app_visit_stat_info
{
int num;
struct app_visit_info visit_list[MAX_APP_STAT_NUM];
};
typedef void (*iter_func)(void *arg, dev_node_t *dev);
//todo:dev for each

View File

@ -1,23 +1,23 @@
/*
Copyright (C) 2020 Derry <destan19@126.com>
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:
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 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.
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>
@ -30,82 +30,87 @@
#include "appfilter_ubus.h"
#include "appfilter_config.h"
#include <time.h>
void check_appfilter_enable(void){
int enable = 1;
struct tm *t;
time_t tt;
time(&tt);
void check_appfilter_enable(void)
{
int enable = 1;
struct tm *t;
time_t tt;
time(&tt);
enable = config_get_appfilter_enable();
if (0 == enable)
goto EXIT;
af_ctl_time_t *af_t = load_appfilter_ctl_time_config();
if (!af_t){
enable = 0;
goto EXIT;
}
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){
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;
}
}
else
enable = 0;
t = localtime(&tt);
if (af_t->days[t->tm_wday] != 1)
{
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;
}
}
else
enable = 0;
EXIT:
if (enable){
system("echo 1 >/proc/sys/oaf/enable ");
}
else
system("echo 0 >/proc/sys/oaf/enable ");
free(af_t);
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){
void dev_list_timeout_handler(struct uloop_timeout *t)
{
dump_dev_list();
// dump_dev_visit_list();
check_appfilter_enable();
//todo: dev list expire
uloop_timeout_set(t, 10000);
// dump_dev_visit_list();
check_appfilter_enable();
//todo: dev list expire
uloop_timeout_set(t, 10000);
}
struct uloop_timeout dev_tm={
.cb = dev_list_timeout_handler
};
struct uloop_timeout dev_tm = {
.cb = dev_list_timeout_handler};
static struct uloop_fd appfilter_nl_fd = {
.cb = appfilter_nl_handler,
.cb = appfilter_nl_handler,
};
int main(int argc, char **argv)
{
int ret = 0;
uloop_init();
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;
}
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;
}
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;
}