1
2/*
3	author: derry
4	date:2019/1/10
5*/
6#include <linux/init.h>
7#include <linux/module.h>
8#include <linux/version.h>
9#include <net/tcp.h>
10#include <linux/netfilter.h>
11#include <net/netfilter/nf_conntrack.h>
12#include <net/netfilter/nf_conntrack_acct.h>
13#include <linux/skbuff.h>
14#include <net/ip.h>
15#include <linux/types.h>
16#include <net/sock.h>
17#include <linux/etherdevice.h>
18#include <linux/cdev.h>
19#include <linux/device.h>
20#include "app_filter.h"
21#include "af_utils.h"
22#include "af_log.h"
23#include "af_client.h"
24#include "af_client_fs.h"
25#include "cJSON.h"
26
27MODULE_LICENSE("GPL");
28MODULE_AUTHOR("destan19@126.com");
29MODULE_DESCRIPTION("app filter module");
30MODULE_VERSION("5.0");
31struct list_head af_feature_head = LIST_HEAD_INIT(af_feature_head);
32
33DEFINE_RWLOCK(af_feature_lock);
34
35#define feature_list_read_lock() read_lock_bh(&af_feature_lock);
36#define feature_list_read_unlock() read_unlock_bh(&af_feature_lock);
37#define feature_list_write_lock() write_lock_bh(&af_feature_lock);
38#define feature_list_write_unlock() write_unlock_bh(&af_feature_lock);
39
40#define SET_APPID(mark, appid) (mark = appid)
41#define GET_APPID(mark) (mark)
42#define MAX_OAF_NETLINK_MSG_LEN 1024
43
44int __add_app_feature(int appid, char *name, int proto, int src_port,
45				port_info_t dport_info, char *host_url, char *request_url, char *dict)
46{
47	af_feature_node_t *node = NULL;
48	char *p = dict;
49	char *begin = dict;
50	char pos[32] = {0};
51	int index = 0;
52	int value = 0;
53	node = kzalloc(sizeof(af_feature_node_t), GFP_KERNEL);
54	if (node == NULL)
55	{
56		printk("malloc feature memory error\n");
57		return -1;
58	}
59	else
60	{
61		node->app_id = appid;
62		strcpy(node->app_name, name);
63		node->proto = proto;
64		node->dport_info = dport_info;
65		node->sport = src_port;
66		strcpy(node->host_url, host_url);
67		strcpy(node->request_url, request_url);
68		// 00:0a-01:11
69		p = dict;
70		begin = dict;
71		index = 0;
72		value = 0;
73		while (*p++)
74		{
75			if (*p == '|')
76			{
77				memset(pos, 0x0, sizeof(pos));
78				strncpy(pos, begin, p - begin);
79				k_sscanf(pos, "%d:%x", &index, &value);
80				begin = p + 1;
81				node->pos_info[node->pos_num].pos = index;
82				node->pos_info[node->pos_num].value = value;
83				node->pos_num++;
84			}
85		}
86
87		if (begin != dict)
88			strncpy(pos, begin, p - begin);
89		else
90			strcpy(pos, dict);
91
92		k_sscanf(pos, "%d:%x", &index, &value);
93		node->pos_info[node->pos_num].pos = index;
94		node->pos_info[node->pos_num].value = value;
95		node->pos_num++;
96		feature_list_write_lock();
97		list_add(&(node->head), &af_feature_head);
98		feature_list_write_unlock();
99	}
100	return 0;
101}
102int validate_range_value(char *range_str){
103	if (!range_str)
104		return 0;
105	char *p = range_str;
106	while(*p){
107		if (*p == ' ' || *p == '!' || *p == '-' ||
108		((*p >= '0') && (*p <= '9'))){
109			p++;
110			continue;
111		}
112		else{
113			printk("error, invalid char %x\n", *p);
114			return 0;
115		}
116	}
117	return 1;
118}
119
120int parse_range_value(char *range_str, range_value_t *range){
121	char pure_range[128] = {0};
122	if (!validate_range_value(range_str)){
123		printk("validate range str failed, value = %s\n", range_str);
124		return -1;
125	}
126	k_trim(range_str);
127	if (range_str[0] == '!'){
128		range->not = 1;
129		strcpy(pure_range, range_str + 1);
130	}
131	else{
132		range->not = 0;
133		strcpy(pure_range, range_str);
134	}
135	k_trim(pure_range);
136	int start, end;
137	if (strstr(pure_range, "-")){
138		if (2 != sscanf(pure_range, "%d-%d",&start, &end))
139			return -1;
140	}
141	else{
142		if (1 != sscanf(pure_range, "%d", &start))
143			return -1;
144		end = start;
145	}
146	range->start = start;
147	range->end = end;
148	return 0;
149}
150
151int parse_port_info(char *port_str, port_info_t *info){
152	char *p = port_str;
153	char *begin = port_str;
154	int param_num = 0;
155	char one_port_buf[128] = {0};
156	k_trim(port_str);
157	if (strlen(port_str) == 0)
158		return -1;
159
160	while(*p++) {
161		if (*p != '|')
162			continue;
163		memset(one_port_buf, 0x0, sizeof(one_port_buf));
164		strncpy(one_port_buf, begin, p - begin);
165		if (0 == parse_range_value(one_port_buf, &info->range_list[info->num])){
166			info->num++;
167		}
168		param_num++;
169		begin = p + 1;
170	}
171	memset(one_port_buf, 0x0, sizeof(one_port_buf));
172	strncpy(one_port_buf, begin, p - begin);
173	if (0 == parse_range_value(one_port_buf, &info->range_list[info->num])){
174		info->num++;
175	}
176	return 0;
177}
178
179int af_match_port(port_info_t *info, int port){
180	int i;
181	int with_not = 0;
182	if (info->num == 0)
183		return 1;
184	for (i = 0; i < info->num; i++){
185		if (info->range_list[i].not){
186			with_not = 1;
187			break;
188		}
189	}
190	for (i = 0; i < info->num; i++){
191		if (with_not){
192			if (info->range_list[i].not && port >= info->range_list[i].start
193				&& port <= info->range_list[i].end){
194				return 0;
195			}
196		}
197		else{
198			if (port >= info->range_list[i].start
199				&& port <= info->range_list[i].end){
200				return 1;
201			}
202		}
203	}
204	if (with_not)
205		return 1;
206	else
207		return 0;
208}
209//[tcp;;443;baidu.com;;]
210int add_app_feature(int appid, char *name, char *feature)
211{
212	char proto_str[16] = {0};
213	char src_port_str[16] = {0};
214	port_info_t dport_info;
215	char dst_port_str[16] = {0};
216	char host_url[32] = {0};
217	char request_url[128] = {0};
218	char dict[128] = {0};
219	int proto = IPPROTO_TCP;
220	char *p = feature;
221	char *begin = feature;
222	int param_num = 0;
223	int dst_port = 0;
224	int src_port = 0;
225
226	if (!name || !feature)
227	{
228		AF_ERROR("error, name or feature is null\n");
229		return -1;
230	}
231	// tcp;8000;www.sina.com;0:get_name;00:0a-01:11
232	memset(&dport_info, 0x0, sizeof(dport_info));
233	while (*p++)
234	{
235		if (*p != ';')
236			continue;
237
238		switch (param_num)
239		{
240
241		case AF_PROTO_PARAM_INDEX:
242			strncpy(proto_str, begin, p - begin);
243			break;
244		case AF_SRC_PORT_PARAM_INDEX:
245			strncpy(src_port_str, begin, p - begin);
246			break;
247		case AF_DST_PORT_PARAM_INDEX:
248			strncpy(dst_port_str, begin, p - begin);
249			break;
250
251		case AF_HOST_URL_PARAM_INDEX:
252			strncpy(host_url, begin, p - begin);
253			break;
254
255		case AF_REQUEST_URL_PARAM_INDEX:
256			strncpy(request_url, begin, p - begin);
257			break;
258		}
259		param_num++;
260		begin = p + 1;
261	}
262	if (AF_DICT_PARAM_INDEX != param_num && strlen(feature) > MIN_FEATURE_STR_LEN)
263	{
264		return -1;
265	}
266	strncpy(dict, begin, p - begin);
267
268	if (0 == strcmp(proto_str, "tcp"))
269		proto = IPPROTO_TCP;
270	else if (0 == strcmp(proto_str, "udp"))
271		proto = IPPROTO_UDP;
272	else
273	{
274		AF_DEBUG("proto %s is not support\n", proto_str);
275		return -1;
276	}
277	sscanf(src_port_str, "%d", &src_port);
278//	sscanf(dst_port_str, "%d", &dst_port);
279	parse_port_info(dst_port_str, &dport_info);
280
281	__add_app_feature(appid, name, proto, src_port, dport_info, host_url, request_url, dict);
282	return 0;
283}
284
285void af_init_feature(char *feature_str)
286{
287	int app_id;
288	char app_name[128] = {0};
289	char feature_buf[MAX_FEATURE_LINE_LEN] = {0};
290	char *p = feature_str;
291	char *pos = NULL;
292	int len = 0;
293	char *begin = NULL;
294	char feature[MAX_FEATURE_STR_LEN];
295
296	if (strstr(feature_str, "#"))
297		return;
298
299	k_sscanf(feature_str, "%d%[^:]", &app_id, app_name);
300	while (*p++)
301	{
302		if (*p == '[')
303		{
304			pos = p + 1;
305			continue;
306		}
307		if (*p == ']' && pos != NULL)
308		{
309			len = p - pos;
310		}
311	}
312
313	if (pos && len)
314		strncpy(feature_buf, pos, len);
315	memset(feature, 0x0, sizeof(feature));
316	p = feature_buf;
317	begin = feature_buf;
318
319	while (*p++)
320	{
321		if (*p == ',')
322		{
323			memset(feature, 0x0, sizeof(feature));
324			strncpy((char *)feature, begin, p - begin);
325
326			add_app_feature(app_id, app_name, feature);
327			begin = p + 1;
328		}
329	}
330	if (p != begin)
331	{
332		memset(feature, 0x0, sizeof(feature));
333		strncpy((char *)feature, begin, p - begin);
334		add_app_feature(app_id, app_name, feature);
335	}
336}
337
338void load_feature_buf_from_file(char **config_buf)
339{
340	struct inode *inode = NULL;
341	struct file *fp = NULL;
342#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 7, 19)
343	 mm_segment_t fs;
344#endif
345	off_t size;
346	fp = filp_open(AF_FEATURE_CONFIG_FILE, O_RDONLY, 0);
347
348	if (IS_ERR(fp))
349	{
350		return;
351	}
352
353	inode = fp->f_inode;
354	size = inode->i_size;
355	if (size == 0)
356	{
357		return;
358	}
359	*config_buf = (char *)kzalloc(sizeof(char) * size, GFP_KERNEL);
360	if (NULL == *config_buf)
361	{
362		AF_ERROR("alloc buf fail\n");
363		filp_close(fp, NULL);
364		return;
365	}
366
367#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 7, 19)
368	fs = get_fs();
369	set_fs(KERNEL_DS);
370#endif
371// 4.14rc3 vfs_read-->kernel_read
372#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
373	kernel_read(fp, *config_buf, size, &(fp->f_pos));
374#else
375	vfs_read(fp, *config_buf, size, &(fp->f_pos));
376#endif
377
378#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 7, 19)
379	set_fs(fs);
380#endif
381	filp_close(fp, NULL);
382}
383
384int load_feature_config(void)
385{
386	char *feature_buf = NULL;
387	char *p;
388	char *begin;
389	char line[MAX_FEATURE_LINE_LEN] = {0};
390
391	load_feature_buf_from_file(&feature_buf);
392	if (!feature_buf)
393	{
394		return -1;
395	}
396	p = begin = feature_buf;
397	while (*p++)
398	{
399		if (*p == '\n')
400		{
401			if (p - begin < MIN_FEATURE_LINE_LEN || p - begin > MAX_FEATURE_LINE_LEN)
402			{
403				begin = p + 1;
404				continue;
405			}
406			memset(line, 0x0, sizeof(line));
407			strncpy(line, begin, p - begin);
408			af_init_feature(line);
409			begin = p + 1;
410		}
411	}
412	if (p != begin)
413	{
414		if (p - begin < MIN_FEATURE_LINE_LEN || p - begin > MAX_FEATURE_LINE_LEN)
415			return 0;
416		memset(line, 0x0, sizeof(line));
417		strncpy(line, begin, p - begin);
418		af_init_feature(line);
419		begin = p + 1;
420	}
421	if (feature_buf)
422		kfree(feature_buf);
423	return 0;
424}
425
426static void af_clean_feature_list(void)
427{
428	af_feature_node_t *node;
429	feature_list_write_lock();
430	while (!list_empty(&af_feature_head))
431	{
432		node = list_first_entry(&af_feature_head, af_feature_node_t, head);
433		list_del(&(node->head));
434		kfree(node);
435	}
436	feature_list_write_unlock();
437}
438
439int parse_flow_proto(struct sk_buff *skb, flow_info_t *flow)
440{
441	struct tcphdr *tcph = NULL;
442	struct udphdr *udph = NULL;
443	struct nf_conn *ct = NULL;
444	struct iphdr *iph = NULL;
445	if (!skb)
446		return -1;
447	iph = ip_hdr(skb);
448	if (!iph)
449		return -1;
450	flow->src = iph->saddr;
451	flow->dst = iph->daddr;
452	flow->l4_protocol = iph->protocol;
453	switch (iph->protocol)
454	{
455	case IPPROTO_TCP:
456		tcph = (struct tcphdr *)(iph + 1);
457		flow->l4_data = skb->data + iph->ihl * 4 + tcph->doff * 4;
458		flow->l4_len = ntohs(iph->tot_len) - iph->ihl * 4 - tcph->doff * 4;
459		flow->dport = htons(tcph->dest);
460		flow->sport = htons(tcph->source);
461		return 0;
462	case IPPROTO_UDP:
463		udph = (struct udphdr *)(iph + 1);
464		flow->l4_data = skb->data + iph->ihl * 4 + 8;
465		flow->l4_len = ntohs(udph->len) - 8;
466		flow->dport = htons(udph->dest);
467		flow->sport = htons(udph->source);
468		return 0;
469	case IPPROTO_ICMP:
470		break;
471	default:
472		return -1;
473	}
474	return -1;
475}
476#define MAX_HOST_LEN 32
477#define MIN_HOST_LEN 4
478
479int dpi_https_proto(flow_info_t *flow)
480{
481	int i;
482	short url_len = 0;
483	char *p = flow->l4_data;
484	int data_len = flow->l4_len;
485
486	if (NULL == flow)
487	{
488		AF_ERROR("flow is NULL\n");
489		return -1;
490	}
491	if (NULL == p || data_len == 0)
492	{
493		return -1;
494	}
495	if (!(p[0] == 0x16 && p[1] == 0x03 && p[2] == 0x01))
496		return -1;
497
498
499	for (i = 0; i < data_len; i++)
500	{
501		if (i + HTTPS_URL_OFFSET >= data_len)
502		{
503			return -1;
504		}
505
506
507		if (p[i] == 0x0 && p[i + 1] == 0x0 && p[i + 2] == 0x0 && p[i + 3] != 0x0)
508		{
509			// 2 bytes
510			memcpy(&url_len, p + i + HTTPS_LEN_OFFSET, 2);
511
512			if (ntohs(url_len) <= MIN_HOST_LEN || ntohs(url_len) > data_len || ntohs(url_len) > MAX_HOST_LEN)
513			{
514				continue;
515			}
516			if (i + HTTPS_URL_OFFSET + ntohs(url_len) < data_len)
517			{
518				flow->https.match = AF_TRUE;
519				flow->https.url_pos = p + i + HTTPS_URL_OFFSET;
520				flow->https.url_len = ntohs(url_len);
521				return 0;
522			}
523		}
524	}
525	return -1;
526}
527
528void dpi_http_proto(flow_info_t *flow)
529{
530	int i = 0;
531	int start = 0;
532	char *data = NULL;
533	int data_len = 0;
534	if (!flow)
535	{
536		AF_ERROR("flow is null\n");
537		return;
538	}
539	if (flow->l4_protocol != IPPROTO_TCP)
540	{
541		return;
542	}
543
544	data = flow->l4_data;
545	data_len = flow->l4_len;
546	if (data_len < MIN_HTTP_DATA_LEN)
547	{
548		return;
549	}
550	if (flow->sport != 80 && flow->dport != 80)
551		return;
552	for (i = 0; i < data_len; i++)
553	{
554		if (data[i] == 0x0d && data[i + 1] == 0x0a)
555		{
556			if (0 == memcmp(&data[start], "POST ", 5))
557			{
558				flow->http.match = AF_TRUE;
559				flow->http.method = HTTP_METHOD_POST;
560				flow->http.url_pos = data + start + 5;
561				flow->http.url_len = i - start - 5;
562			}
563			else if (0 == memcmp(&data[start], "GET ", 4))
564			{
565				flow->http.match = AF_TRUE;
566				flow->http.method = HTTP_METHOD_GET;
567				flow->http.url_pos = data + start + 4;
568				flow->http.url_len = i - start - 4;
569			}
570			else if (0 == memcmp(&data[start], "Host:", 5))
571			{
572				flow->http.host_pos = data + start + 6;
573				flow->http.host_len = i - start - 6;
574			}
575			if (data[i + 2] == 0x0d && data[i + 3] == 0x0a)
576			{
577				flow->http.data_pos = data + i + 4;
578				flow->http.data_len = data_len - i - 4;
579				break;
580			}
581			// 0x0d 0x0a
582			start = i + 2;
583		}
584	}
585}
586
587static void dump_http_flow_info(http_proto_t *http)
588{
589	if (!http)
590	{
591		AF_ERROR("http ptr is NULL\n");
592		return;
593	}
594	if (!http->match)
595		return;
596	if (http->method == HTTP_METHOD_GET)
597	{
598		printk("Http method: " HTTP_GET_METHOD_STR "\n");
599	}
600	else if (http->method == HTTP_METHOD_POST)
601	{
602		printk("Http method: " HTTP_POST_METHOD_STR "\n");
603	}
604	if (http->url_len > 0 && http->url_pos)
605	{
606		dump_str("Request url", http->url_pos, http->url_len);
607	}
608
609	if (http->host_len > 0 && http->host_pos)
610	{
611		dump_str("Host", http->host_pos, http->host_len);
612	}
613
614	printk("--------------------------------------------------------\n\n\n");
615}
616
617static void dump_https_flow_info(https_proto_t *https)
618{
619	if (!https)
620	{
621		AF_ERROR("https ptr is NULL\n");
622		return;
623	}
624	if (!https->match)
625		return;
626
627	if (https->url_len > 0 && https->url_pos)
628	{
629		dump_str("https server name", https->url_pos, https->url_len);
630	}
631
632	printk("--------------------------------------------------------\n\n\n");
633}
634static void dump_flow_info(flow_info_t *flow)
635{
636	if (!flow)
637	{
638		AF_ERROR("flow is null\n");
639		return;
640	}
641	if (flow->l4_len > 0)
642	{
643		AF_LMT_INFO("src=" NIPQUAD_FMT ",dst=" NIPQUAD_FMT ",sport: %d, dport: %d, data_len: %d\n",
644					NIPQUAD(flow->src), NIPQUAD(flow->dst), flow->sport, flow->dport, flow->l4_len);
645	}
646
647	if (flow->l4_protocol == IPPROTO_TCP)
648	{
649		if (AF_TRUE == flow->http.match)
650		{
651			printk("-------------------http protocol-------------------------\n");
652			printk("protocol:TCP , sport: %-8d, dport: %-8d, data_len: %-8d\n",
653				   flow->sport, flow->dport, flow->l4_len);
654			dump_http_flow_info(&flow->http);
655		}
656		if (AF_TRUE == flow->https.match)
657		{
658			printk("-------------------https protocol-------------------------\n");
659			dump_https_flow_info(&flow->https);
660		}
661	}
662}
663int af_match_by_pos(flow_info_t *flow, af_feature_node_t *node)
664{
665	int i;
666	unsigned int pos = 0;
667
668	if (!flow || !node)
669		return AF_FALSE;
670	if (node->pos_num > 0)
671	{
672		for (i = 0; i < node->pos_num; i++)
673		{
674			// -1
675			if (node->pos_info[i].pos < 0)
676			{
677				pos = flow->l4_len + node->pos_info[i].pos;
678			}
679			else
680			{
681				pos = node->pos_info[i].pos;
682			}
683			if (pos >= flow->l4_len)
684			{
685				return AF_FALSE;
686			}
687			if (flow->l4_data[pos] != node->pos_info[i].value)
688			{
689				return AF_FALSE;
690			}
691		}
692		AF_DEBUG("match by pos, appid=%d\n", node->app_id);
693		return AF_TRUE;
694	}
695	return AF_FALSE;
696}
697
698int af_match_by_url(flow_info_t *flow, af_feature_node_t *node)
699{
700	char reg_url_buf[MAX_URL_MATCH_LEN] = {0};
701
702	if (!flow || !node)
703		return AF_FALSE;
704	// match host or https url
705	if (flow->https.match == AF_TRUE && flow->https.url_pos)
706	{
707		if (flow->https.url_len >= MAX_URL_MATCH_LEN)
708			strncpy(reg_url_buf, flow->https.url_pos, MAX_URL_MATCH_LEN - 1);
709		else
710			strncpy(reg_url_buf, flow->https.url_pos, flow->https.url_len);
711	}
712	else if (flow->http.match == AF_TRUE && flow->http.host_pos)
713	{
714		if (flow->http.host_len >= MAX_URL_MATCH_LEN)
715			strncpy(reg_url_buf, flow->http.host_pos, MAX_URL_MATCH_LEN - 1);
716		else
717			strncpy(reg_url_buf, flow->http.host_pos, flow->http.host_len);
718	}
719	if (strlen(reg_url_buf) > 0 && strlen(node->host_url) > 0 && regexp_match(node->host_url, reg_url_buf))
720	{
721		AF_DEBUG("match url:%s	 reg = %s, appid=%d\n",
722				 reg_url_buf, node->host_url, node->app_id);
723		return AF_TRUE;
724	}
725
726	// match request url
727	if (flow->http.match == AF_TRUE && flow->http.url_pos)
728	{
729		memset(reg_url_buf, 0x0, sizeof(reg_url_buf));
730		if (flow->http.url_len >= MAX_URL_MATCH_LEN)
731			strncpy(reg_url_buf, flow->http.url_pos, MAX_URL_MATCH_LEN - 1);
732		else
733			strncpy(reg_url_buf, flow->http.url_pos, flow->http.url_len);
734		if (strlen(reg_url_buf) > 0 && strlen(node->request_url) && regexp_match(node->request_url, reg_url_buf))
735		{
736			AF_DEBUG("match request:%s   reg:%s appid=%d\n",
737					 reg_url_buf, node->request_url, node->app_id);
738			return AF_TRUE;
739		}
740	}
741	return AF_FALSE;
742}
743
744int af_match_one(flow_info_t *flow, af_feature_node_t *node)
745{
746	int ret = AF_FALSE;
747	if (!flow || !node)
748	{
749		AF_ERROR("node or flow is NULL\n");
750		return AF_FALSE;
751	}
752	if (node->proto > 0 && flow->l4_protocol != node->proto)
753		return AF_FALSE;
754	if (flow->l4_len == 0)
755		return AF_FALSE;
756
757	if (node->sport != 0 && flow->sport != node->sport)
758	{
759		return AF_FALSE;
760	}
761
762	if (!af_match_port(&node->dport_info, flow->dport)){
763		return AF_FALSE;
764	}
765
766	if (strlen(node->request_url) > 0 ||
767		strlen(node->host_url) > 0)
768	{
769		ret = af_match_by_url(flow, node);
770	}
771	else if (node->pos_num > 0)
772	{
773		ret = af_match_by_pos(flow, node);
774	}
775	else
776	{
777		AF_DEBUG("node is empty, match sport:%d,dport:%d, appid = %d\n",
778				 node->sport, node->dport, node->app_id);
779		return AF_TRUE;
780	}
781	return ret;
782}
783
784int app_filter_match(flow_info_t *flow)
785{
786	af_feature_node_t *n, *node;
787	af_client_info_t *client = NULL;
788	feature_list_read_lock();
789	if (!list_empty(&af_feature_head))
790	{
791		list_for_each_entry_safe(node, n, &af_feature_head, head)
792		{
793			if (af_match_one(flow, node))
794			{
795				flow->app_id = node->app_id;
796				strncpy(flow->app_name, node->app_name, sizeof(flow->app_name) - 1);
797				client = find_af_client_by_ip(flow->src);
798				if (!client)
799				{
800					goto EXIT;
801				}
802				if (is_user_match_enable() && !find_af_mac(client->mac))
803				{
804					goto EXIT;
805				}
806				if (af_get_app_status(node->app_id))
807				{
808					flow->drop = AF_TRUE;
809					feature_list_read_unlock();
810					return AF_TRUE;
811				}
812				else
813				{
814					goto EXIT;
815				}
816			}
817		}
818	}
819EXIT:
820	flow->drop = AF_FALSE;
821	feature_list_read_unlock();
822	return AF_FALSE;
823}
824
825#define NF_DROP_BIT 0x80000000
826
827static int af_get_visit_index(af_client_info_t *node, int app_id)
828{
829	int i;
830	for (i = 0; i < MAX_RECORD_APP_NUM; i++)
831	{
832		if (node->visit_info[i].app_id == app_id || node->visit_info[i].app_id == 0)
833		{
834			return i;
835		}
836	}
837	// default 0
838	return 0;
839}
840
841int af_update_client_app_info(af_client_info_t *node, int app_id, int drop)
842{
843	int index = -1;
844	if (!node)
845		return -1;
846
847	index = af_get_visit_index(node, app_id);
848	if (index < 0 || index >= MAX_RECORD_APP_NUM)
849		return 0;
850	node->visit_info[index].total_num++;
851	if (drop)
852		node->visit_info[index].drop_num++;
853	node->visit_info[index].app_id = app_id;
854	node->visit_info[index].latest_time = af_get_timestamp_sec();
855	node->visit_info[index].latest_action = drop;
856	return 0;
857}
858
859int af_send_msg_to_user(char *pbuf, uint16_t len);
860int af_match_bcast_packet(flow_info_t *f){
861	if (!f)
862		return 0;
863	if (0 == f->src || 0 == f->dst
864	|| 0xffffffff == f->dst || 0 == f->dst)
865		return 1;
866	return 0;
867}
868
869int af_match_local_packet(flow_info_t *f){
870	if (!f)
871		return 0;
872	if (0x0100007f == f->src || 0x0100007f == f->dst){
873		return 1;
874	}
875	return 0;
876}
877
878int dpi_main(struct sk_buff *skb, flow_info_t *flow){
879	dpi_http_proto(flow);
880	dpi_https_proto(flow);
881	if (TEST_MODE())
882		dump_flow_info(flow);
883	return 0;
884}
885
886void af_get_smac(struct sk_buff *skb, u_int8_t *smac){
887	struct ethhdr *ethhdr = NULL;
888	ethhdr = eth_hdr(skb);
889	if (ethhdr)
890		memcpy(smac, ethhdr->h_source, ETH_ALEN);
891	else
892		memcpy(smac, &skb->cb[40], ETH_ALEN);
893}
894int is_ipv4_broadcast(uint32_t ip) {
895
896    return (ip & 0x00FFFFFF) == 0x00FFFFFF;
897}
898
899int is_ipv4_multicast(uint32_t ip) {
900    return (ip & 0xF0000000) == 0xE0000000;
901}
902int af_check_bcast_ip(flow_info_t *f)
903{
904
905	if (0 == f->src || 0 == f->dst)
906		return 1;
907	if (is_ipv4_broadcast(ntohl(f->src)) || is_ipv4_broadcast(ntohl(f->dst))){
908		return 1;
909	}
910	if (is_ipv4_multicast(ntohl(f->src)) || is_ipv4_multicast(ntohl(f->dst))){
911		return 1;
912	}
913
914	return 0;
915}
916#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
917u_int32_t app_filter_hook_bypass_handle(struct sk_buff *skb, struct net_device *dev){
918	flow_info_t flow;
919	u_int8_t smac[ETH_ALEN];
920	af_client_info_t *client = NULL;
921
922	if (!skb || !dev)
923		return NF_ACCEPT;
924
925	if (0 == af_lan_ip || 0 == af_lan_mask)
926		return NF_ACCEPT;
927	if (dev->name && strstr(dev->name, "docker"))
928		return NF_ACCEPT;
929
930	memset((char *)&flow, 0x0, sizeof(flow_info_t));
931	if (parse_flow_proto(skb, &flow) < 0)
932		return NF_ACCEPT;
933
934	if (af_lan_ip == flow.src || af_lan_ip == flow.dst){
935		return NF_ACCEPT;
936	}
937	if (af_check_bcast_ip(&flow) || af_match_local_packet(&flow))
938		return NF_ACCEPT;
939
940	if ((flow.src & af_lan_mask) != (af_lan_ip & af_lan_mask)){
941		return NF_ACCEPT;
942	}
943	af_get_smac(skb, smac);
944
945	AF_CLIENT_LOCK_W();
946	client = find_and_add_af_client(smac);
947	if (!client){
948		AF_CLIENT_UNLOCK_W();
949		return NF_ACCEPT;
950	}
951	client->update_jiffies = jiffies;
952	AF_CLIENT_UNLOCK_W();
953
954	if (0 != dpi_main(skb, &flow))
955		return NF_ACCEPT;
956
957	client->ip = flow.src;
958	app_filter_match(&flow);
959	if (flow.app_id != 0){
960		af_update_client_app_info(client, flow.app_id, flow.drop);
961	}
962	if (flow.drop)
963	{
964		return NF_DROP;
965	}
966	return NF_ACCEPT;
967}
968
969u_int32_t app_filter_hook_gateway_handle(struct sk_buff *skb, struct net_device *dev){
970	unsigned long long total_packets = 0;
971	flow_info_t flow;
972	enum ip_conntrack_info ctinfo;
973	struct nf_conn *ct = NULL;
974	struct nf_conn_acct *acct;
975	af_client_info_t *client = NULL;
976	int app_id = 0;
977	int drop = 0;
978
979	memset((char *)&flow, 0x0, sizeof(flow_info_t));
980	if (parse_flow_proto(skb, &flow) < 0)
981		return NF_ACCEPT;
982
983	ct = nf_ct_get(skb, &ctinfo);
984	if (ct == NULL || !nf_ct_is_confirmed(ct))
985		return NF_ACCEPT;
986
987	AF_CLIENT_LOCK_R();
988	client = find_af_client_by_ip(flow.src);
989	if (!client){
990		AF_CLIENT_UNLOCK_R();
991		return NF_ACCEPT;
992	}
993	client->update_jiffies = jiffies;
994	AF_CLIENT_UNLOCK_R();
995
996	if (ct->mark != 0)
997	{
998		app_id = ct->mark & (~NF_DROP_BIT);
999		if (app_id > 1000 && app_id < 9999){
1000			if (NF_DROP_BIT == (ct->mark & NF_DROP_BIT))
1001				drop = 1;
1002			AF_CLIENT_LOCK_W();
1003			af_update_client_app_info(client, app_id, drop);
1004			AF_CLIENT_UNLOCK_W();
1005
1006			if (drop){
1007				return NF_DROP;
1008			}
1009		}
1010	}
1011	acct = nf_conn_acct_find(ct);
1012	if(!acct)
1013		return NF_ACCEPT;
1014	total_packets = (unsigned long long)atomic64_read(&acct->counter[IP_CT_DIR_ORIGINAL].packets)
1015		+ (unsigned long long)atomic64_read(&acct->counter[IP_CT_DIR_REPLY].packets);
1016
1017	if(total_packets > MAX_DPI_PKT_NUM)
1018		return NF_ACCEPT;
1019
1020	if (0 != dpi_main(skb, &flow))
1021		return NF_ACCEPT;
1022
1023	app_filter_match(&flow);
1024
1025	if (flow.app_id != 0)
1026	{
1027		ct->mark = flow.app_id;
1028		AF_CLIENT_LOCK_W();
1029		af_update_client_app_info(client, flow.app_id, flow.drop);
1030		AF_CLIENT_UNLOCK_W();
1031		AF_LMT_INFO("match %s %pI4(%d)--> %pI4(%d) len = %d, %d\n ", IPPROTO_TCP == flow.l4_protocol ? "tcp" : "udp",
1032					&flow.src, flow.sport, &flow.dst, flow.dport, skb->len, flow.app_id);
1033	}
1034	if (flow.drop)
1035	{
1036		ct->mark |= NF_DROP_BIT;
1037		AF_LMT_INFO("##Drop app %s flow, appid is %d\n", flow.app_name, flow.app_id);
1038		return NF_DROP;
1039	}
1040	return NF_ACCEPT;
1041}
1042
1043
1044#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
1045static u_int32_t app_filter_hook(void *priv,
1046								 struct sk_buff *skb,
1047								 const struct nf_hook_state *state)
1048{
1049#else
1050static u_int32_t app_filter_hook(unsigned int hook,
1051								 struct sk_buff *skb,
1052								 const struct net_device *in,
1053								 const struct net_device *out,
1054								 int (*okfn)(struct sk_buff *))
1055{
1056#endif
1057	if (!g_oaf_enable)
1058		return NF_ACCEPT;
1059	if (AF_MODE_BYPASS == af_work_mode)
1060		return NF_ACCEPT;
1061	return app_filter_hook_gateway_handle(skb, skb->dev);
1062}
1063
1064#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
1065static u_int32_t app_filter_by_pass_hook(void *priv,
1066								 struct sk_buff *skb,
1067								 const struct nf_hook_state *state)
1068{
1069#else
1070static u_int32_t app_filter_by_pass_hook(unsigned int hook,
1071								 struct sk_buff *skb,
1072								 const struct net_device *in,
1073								 const struct net_device *out,
1074								 int (*okfn)(struct sk_buff *))
1075{
1076#endif
1077	if (!g_oaf_enable)
1078		return NF_ACCEPT;
1079	if (AF_MODE_GATEWAY == af_work_mode)
1080		return NF_ACCEPT;
1081	return app_filter_hook_bypass_handle(skb, skb->dev);
1082}
1083
1084
1085#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
1086static struct nf_hook_ops app_filter_ops[] __read_mostly = {
1087	{
1088		.hook = app_filter_hook,
1089		.pf = PF_INET,
1090		.hooknum = NF_INET_FORWARD,
1091		.priority = NF_IP_PRI_MANGLE + 1,
1092
1093	},
1094	{
1095		.hook = app_filter_by_pass_hook,
1096		.pf = PF_INET,
1097		.hooknum = NF_INET_PRE_ROUTING,
1098		.priority = NF_IP_PRI_MANGLE + 1,
1099	},
1100};
1101#else
1102static struct nf_hook_ops app_filter_ops[] __read_mostly = {
1103	{
1104		.hook = app_filter_hook,
1105		.owner = THIS_MODULE,
1106		.pf = PF_INET,
1107		.hooknum = NF_INET_FORWARD,
1108		.priority = NF_IP_PRI_MANGLE + 1,
1109	},
1110};
1111#endif
1112
1113
1114struct timer_list oaf_timer;
1115int report_flag = 0;
1116#define OAF_TIMER_INTERVAL 1
1117#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
1118static void oaf_timer_func(struct timer_list *t)
1119#else
1120static void oaf_timer_func(unsigned long ptr)
1121#endif
1122{
1123	static int count = 0;
1124	if (count % 60 == 0)
1125		check_client_expire();
1126	if (count % 60 == 0 || report_flag)
1127	{
1128		report_flag = 0;
1129		af_visit_info_report();
1130	}
1131	count++;
1132	mod_timer(&oaf_timer, jiffies + OAF_TIMER_INTERVAL * HZ);
1133}
1134
1135void init_oaf_timer(void)
1136{
1137#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
1138	timer_setup(&oaf_timer, oaf_timer_func, 0);
1139#else
1140	setup_timer(&oaf_timer, oaf_timer_func, OAF_TIMER_INTERVAL * HZ);
1141#endif
1142	mod_timer(&oaf_timer, jiffies + OAF_TIMER_INTERVAL * HZ);
1143	AF_INFO("init oaf timer...ok");
1144}
1145
1146void fini_oaf_timer(void)
1147{
1148	del_timer_sync(&oaf_timer);
1149	AF_INFO("del oaf timer...ok");
1150}
1151
1152static struct sock *oaf_sock = NULL;
1153
1154int af_send_msg_to_user(char *pbuf, uint16_t len)
1155{
1156	struct sk_buff *nl_skb;
1157	struct nlmsghdr *nlh;
1158	//todo: kmalloc
1159	char msg_buf[MAX_OAF_NL_MSG_LEN] = {0};
1160	struct af_msg_hdr *hdr = NULL;
1161	char *p_data = NULL;
1162	int ret;
1163	if (len >= MAX_OAF_NL_MSG_LEN)
1164		return -1;
1165
1166	memset(msg_buf, 0x0, sizeof(msg_buf));
1167	nl_skb = nlmsg_new(len + sizeof(struct af_msg_hdr), GFP_ATOMIC);
1168	if (!nl_skb)
1169	{
1170		return -1;
1171	}
1172
1173	nlh = nlmsg_put(nl_skb, 0, 0, OAF_NETLINK_ID, len + sizeof(struct af_msg_hdr), 0);
1174	if (nlh == NULL)
1175	{
1176		nlmsg_free(nl_skb);
1177		return -1;
1178	}
1179
1180	hdr = (struct af_msg_hdr *)msg_buf;
1181	hdr->magic = 0xa0b0c0d0;
1182	hdr->len = len;
1183	p_data = msg_buf + sizeof(struct af_msg_hdr);
1184	memcpy(p_data, pbuf, len);
1185	memcpy(nlmsg_data(nlh), msg_buf, len + sizeof(struct af_msg_hdr));
1186	ret = netlink_unicast(oaf_sock, nl_skb, 999, MSG_DONTWAIT);
1187	return ret;
1188}
1189
1190static void oaf_user_msg_handle(af_msg_t *msg)
1191{
1192	switch (msg->action)
1193	{
1194	case AF_MSG_INIT:
1195		af_client_list_reset_report_num();
1196		report_flag = 1;
1197		break;
1198	default:
1199		break;
1200	}
1201}
1202static void oaf_msg_rcv(struct sk_buff *skb)
1203{
1204	struct nlmsghdr *nlh = NULL;
1205	char *umsg = NULL;
1206	void *udata = NULL;
1207	struct af_msg_hdr *af_hdr = NULL;
1208	if (skb->len >= nlmsg_total_size(0))
1209	{
1210		nlh = nlmsg_hdr(skb);
1211		umsg = NLMSG_DATA(nlh);
1212		af_hdr = (struct af_msg_hdr *)umsg;
1213		if (af_hdr->magic != 0xa0b0c0d0)
1214			return;
1215		if (af_hdr->len <= 0 || af_hdr->len >= MAX_OAF_NETLINK_MSG_LEN)
1216			return;
1217		udata = umsg + sizeof(struct af_msg_hdr);
1218
1219		if (udata)
1220			oaf_user_msg_handle((af_msg_t *)udata);
1221	}
1222}
1223
1224int netlink_oaf_init(void)
1225{
1226	struct netlink_kernel_cfg nl_cfg = {0};
1227	nl_cfg.input = oaf_msg_rcv;
1228	oaf_sock = netlink_kernel_create(&init_net, OAF_NETLINK_ID, &nl_cfg);
1229
1230	if (NULL == oaf_sock)
1231	{
1232		AF_ERROR("init oaf netlink failed, id=%d\n", OAF_NETLINK_ID);
1233		return -1;
1234	}
1235	AF_INFO("init oaf netlink ok, id = %d\n", OAF_NETLINK_ID);
1236	return 0;
1237}
1238
1239static int __init app_filter_init(void)
1240{
1241	if (0 != load_feature_config())
1242	{
1243		return -1;
1244	}
1245
1246	netlink_oaf_init();
1247	af_log_init();
1248	af_register_dev();
1249	af_mac_list_init();
1250	af_init_app_status();
1251	init_af_client_procfs();
1252	af_client_init();
1253#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
1254	nf_register_net_hooks(&init_net, app_filter_ops, ARRAY_SIZE(app_filter_ops));
1255#else
1256	nf_register_hooks(app_filter_ops, ARRAY_SIZE(app_filter_ops));
1257#endif
1258	init_oaf_timer();
1259	AF_INFO("init app filter ........ok\n");
1260	return 0;
1261}
1262
1263static void app_filter_fini(void)
1264{
1265	AF_INFO("app filter module exit\n");
1266	fini_oaf_timer();
1267#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
1268	nf_unregister_net_hooks(&init_net, app_filter_ops, ARRAY_SIZE(app_filter_ops));
1269#else
1270	nf_unregister_hooks(app_filter_ops, ARRAY_SIZE(app_filter_ops));
1271#endif
1272
1273	af_clean_feature_list();
1274	af_mac_list_clear();
1275	af_unregister_dev();
1276	af_log_exit();
1277	af_client_exit();
1278	finit_af_client_procfs();
1279	if (oaf_sock)
1280		netlink_kernel_release(oaf_sock);
1281	return;
1282}
1283
1284module_init(app_filter_init);
1285module_exit(app_filter_fini);
1286