2019-08-28 07:29:18 +00:00
|
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
|
#include <linux/timer.h>
|
|
|
|
|
#include <linux/uaccess.h>
|
|
|
|
|
#include <linux/sysctl.h>
|
|
|
|
|
#include <linux/ip.h>
|
|
|
|
|
#include <linux/ipv6.h>
|
2019-09-06 08:41:04 +00:00
|
|
|
|
#include <linux/inet.h>
|
2019-08-28 07:29:18 +00:00
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
#include "dpi_trie_cache.h"
|
2019-08-28 07:29:18 +00:00
|
|
|
|
|
|
|
|
|
/*
|
2019-09-06 08:41:04 +00:00
|
|
|
|
* 三元组超时时间设置为300s
|
2019-08-28 07:29:18 +00:00
|
|
|
|
*/
|
2019-09-06 08:41:04 +00:00
|
|
|
|
int dpi_cache_node_timeout = 300;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
|
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
#define IPV4_ADDR (1)
|
|
|
|
|
#define IPV6_ADDR (2)
|
2019-08-28 07:29:18 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 初始化cache链表
|
|
|
|
|
*/
|
|
|
|
|
#define TRIPLE_CAHCE_HASH_SIZE (2048)
|
|
|
|
|
struct list_head dpi_cache_head[TRIPLE_CAHCE_HASH_SIZE] = {0};
|
|
|
|
|
|
|
|
|
|
typedef struct pkt_info{
|
|
|
|
|
unsigned int srcip;
|
|
|
|
|
unsigned short sport;
|
|
|
|
|
unsigned int dstip;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
unsigned short port;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
unsigned short proto;
|
|
|
|
|
}pkt_info_t;
|
|
|
|
|
|
|
|
|
|
#define POLY 0x01101 // CRC20生成多项式x^20+x^12+x^8+1即:01101 CRC32:04C11DB7L
|
|
|
|
|
static unsigned int crc_table[256] = {0};
|
|
|
|
|
|
|
|
|
|
unsigned int get_sum_poly(unsigned char data)
|
|
|
|
|
{
|
|
|
|
|
unsigned int sum_poly = data;
|
|
|
|
|
int j;
|
|
|
|
|
sum_poly <<= 24;
|
|
|
|
|
for(j = 0; j < 8; j++)
|
|
|
|
|
{
|
|
|
|
|
int hi = sum_poly&0x80000000; // 取得reg的最高位
|
|
|
|
|
sum_poly <<= 1;
|
|
|
|
|
if(hi) sum_poly = sum_poly^POLY;
|
|
|
|
|
}
|
|
|
|
|
return sum_poly;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_crc_table(void) //在使用CRC20_key函数应该先建立crc表
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i = 0; i < 256; i++)
|
|
|
|
|
{
|
|
|
|
|
crc_table[i] = get_sum_poly(i&0xFF);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int CRC20_key(unsigned char* data, int len)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
unsigned int reg = 0xFFFFFFFF;// 0xFFFFFFFF,见后面解释
|
|
|
|
|
for(i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
reg = (reg<<8) ^ crc_table[((reg>>24)&0xFF) ^ data[i]];
|
|
|
|
|
}
|
|
|
|
|
return (reg&0XFFFFF);//得到的reg取后20作为key值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 初始化dpi三元组hash链表
|
|
|
|
|
*/
|
|
|
|
|
void dpi_cache_list_init(void)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (i = 0; i < TRIPLE_CAHCE_HASH_SIZE; i++){
|
|
|
|
|
INIT_LIST_HEAD(&dpi_cache_head[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 三元组hash值计算
|
|
|
|
|
*/
|
|
|
|
|
int dpi_cache_node_hash(struct dpi_cache_node node)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
int dip = 0;
|
|
|
|
|
|
|
|
|
|
pkt_info_t info;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
info.port = node.port;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
info.sport = 0;
|
|
|
|
|
info.srcip = 0;
|
|
|
|
|
info.proto = node.proto;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
if (node.ipv4 == true ) {
|
2019-08-28 07:29:18 +00:00
|
|
|
|
info.dstip = node.ip.ip4.s_addr;
|
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i < 4; ++i) {
|
|
|
|
|
dip ^= node.ip.ip6.s6_addr32[i];
|
|
|
|
|
}
|
|
|
|
|
info.dstip = dip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CRC20_key((unsigned char *)&info, sizeof(pkt_info_t))&(TRIPLE_CAHCE_HASH_SIZE - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* src 和dst比较,并更新dst的appid,update_appid=true,update
|
|
|
|
|
*/
|
|
|
|
|
bool dpi_cache_node_compare(struct dpi_cache_node src,struct dpi_cache_node dst,bool update_appid)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
if (src.port != dst.port){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src.proto != dst.proto){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
if(src.ipv4 == true){
|
2019-08-28 07:29:18 +00:00
|
|
|
|
if(src.ip.ip4.s_addr != dst.ip.ip4.s_addr){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
for (i = 0; i < 4; i++){
|
|
|
|
|
if (src.ip.ip6.s6_addr32[i] != dst.ip.ip6.s6_addr32[i]){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_appid){
|
2019-09-06 08:41:04 +00:00
|
|
|
|
if(src.appid != -1)
|
|
|
|
|
dst.appid = src.appid;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
dst.uptime = get_jiffies_64();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*遍历hash链表,查找node
|
|
|
|
|
*/
|
|
|
|
|
bool dpi_cache_node_search(struct dpi_cache_node node,int flag)
|
|
|
|
|
{
|
|
|
|
|
struct list_head * pList;
|
|
|
|
|
struct dpi_cache_node *pNode;
|
|
|
|
|
int hash = dpi_cache_node_hash(node);
|
|
|
|
|
list_for_each(pList,&dpi_cache_head[hash]){
|
|
|
|
|
pNode = list_entry(pList,struct dpi_cache_node,list);
|
|
|
|
|
if (dpi_cache_node_compare(node,*pNode,flag)){
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* DPI 信息记录,外部接口调用
|
|
|
|
|
*/
|
|
|
|
|
bool dpi_cache_node_add(struct dpi_cache_node node)
|
|
|
|
|
{
|
|
|
|
|
int hash = 0;
|
|
|
|
|
struct dpi_cache_node *pNode =NULL;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
|
2019-08-28 07:29:18 +00:00
|
|
|
|
if (dpi_cache_node_search(node,true)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pNode = kmalloc(sizeof(struct dpi_cache_node), GFP_KERNEL);
|
|
|
|
|
if (NULL == pNode) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash = dpi_cache_node_hash(node);
|
2019-09-06 08:41:04 +00:00
|
|
|
|
memcpy((char*)pNode,(char*)&node,sizeof(node));
|
2019-08-28 07:29:18 +00:00
|
|
|
|
pNode->uptime = get_jiffies_64();
|
2019-09-06 08:41:04 +00:00
|
|
|
|
//printk("%s,%d,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->proto,pNode->port,pNode->ipv4);
|
2019-08-28 07:29:18 +00:00
|
|
|
|
list_add_tail(&pNode->list,&dpi_cache_head[hash]);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 释放hash链表上所有node节点
|
|
|
|
|
*/
|
|
|
|
|
void dpi_cache_list_release(void)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (i = 0; i < TRIPLE_CAHCE_HASH_SIZE; i++){
|
2019-09-06 08:41:04 +00:00
|
|
|
|
while(!list_empty(&dpi_cache_head[i]))
|
|
|
|
|
{
|
|
|
|
|
list_del(dpi_cache_head[i].next);
|
2019-08-28 07:29:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*定时器超时,删除超时的节点
|
|
|
|
|
*/
|
|
|
|
|
void dpi_cache_node_timeout_func(void)
|
|
|
|
|
{
|
|
|
|
|
struct list_head * pList = NULL;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
struct list_head * n = NULL;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
struct dpi_cache_node *pNode = NULL;
|
2019-09-06 08:41:04 +00:00
|
|
|
|
|
2019-08-28 07:29:18 +00:00
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < TRIPLE_CAHCE_HASH_SIZE; i++){
|
2019-09-06 08:41:04 +00:00
|
|
|
|
list_for_each_safe(pList,(n),&dpi_cache_head[i]){
|
2019-08-28 07:29:18 +00:00
|
|
|
|
pNode = list_entry(pList,struct dpi_cache_node,list);
|
2019-09-06 08:41:04 +00:00
|
|
|
|
//printk("%s,%d,%d\n",__FUNCTION__,__LINE__,pNode->port);
|
2019-08-28 07:29:18 +00:00
|
|
|
|
if(pNode&&
|
|
|
|
|
(get_jiffies_64() - pNode->uptime >= dpi_cache_node_timeout)){
|
|
|
|
|
list_del(&pNode->list);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 定时器操作
|
|
|
|
|
*/
|
|
|
|
|
struct timer_list gTimer;
|
|
|
|
|
void dpi_cache_timer_handler(unsigned long data) {
|
2019-09-06 08:41:04 +00:00
|
|
|
|
//printk(KERN_INFO"timer pending:%d\n", timer_pending(&gTimer));
|
2019-08-28 07:29:18 +00:00
|
|
|
|
dpi_cache_node_timeout_func();
|
|
|
|
|
mod_timer(&gTimer, jiffies+msecs_to_jiffies(dpi_cache_node_timeout*1000));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int dpi_cache_timer_init(void) {
|
|
|
|
|
printk(KERN_INFO"%s jiffies:%ld\n", __func__, jiffies);
|
|
|
|
|
printk(KERN_INFO"ji:%d,HZ:%d\n", jiffies_to_msecs(250), HZ);
|
|
|
|
|
init_timer(&gTimer);
|
|
|
|
|
gTimer.expires = jiffies + dpi_cache_node_timeout*HZ;
|
|
|
|
|
gTimer.function = dpi_cache_timer_handler;
|
|
|
|
|
add_timer(&gTimer);
|
|
|
|
|
printk(KERN_INFO"timer pending:%d\n", timer_pending(&gTimer));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-09-06 08:41:04 +00:00
|
|
|
|
void test_func(void)
|
|
|
|
|
{
|
|
|
|
|
struct dpi_cache_node node1,node2,node3;
|
|
|
|
|
node1.proto = 17;
|
|
|
|
|
in4_pton("192.168.1.1", strlen("192.168.1.1"), (u8*)&node1.ip.ip4, -1, NULL);
|
|
|
|
|
node1.port = 200;
|
|
|
|
|
node1.ipv4 = true;
|
|
|
|
|
dpi_cache_node_add(node1);
|
|
|
|
|
|
|
|
|
|
node2.proto = 17;
|
|
|
|
|
in4_pton("192.168.2.1", strlen("192.168.1.1"), (u8*)&node2.ip.ip4, -1, NULL);
|
|
|
|
|
node2.port = 200;
|
|
|
|
|
node2.ipv4 = true;
|
|
|
|
|
dpi_cache_node_add(node2);
|
|
|
|
|
|
|
|
|
|
node3.proto = 17;
|
|
|
|
|
in6_pton("2a01:198:603:0:396e:4789:8e99:890f", strlen("2a01:198:603:0:396e:4789:8e99:890f"), (u8*)&node3.ip.ip6, -1, NULL);
|
|
|
|
|
node3.port = 200;
|
|
|
|
|
node3.ipv4 = false;
|
|
|
|
|
dpi_cache_node_add(node3);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-28 07:29:18 +00:00
|
|
|
|
void dpi_cache_timer_exit(void) {
|
|
|
|
|
printk(KERN_INFO"%s jiffies:%ld\n", __func__, jiffies);
|
|
|
|
|
del_timer(&gTimer);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
static int __init dpi_cahce_module_init(void)
|
2019-08-28 07:29:18 +00:00
|
|
|
|
{
|
|
|
|
|
dpi_cache_list_init();
|
2019-09-06 08:41:04 +00:00
|
|
|
|
dpi_cache_timer_init();
|
|
|
|
|
|
|
|
|
|
//test_func();
|
|
|
|
|
return 0;
|
2019-08-28 07:29:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
static void __exit dpi_cache_module_exit(void)
|
2019-08-28 07:29:18 +00:00
|
|
|
|
{
|
|
|
|
|
dpi_cache_timer_exit();
|
|
|
|
|
dpi_cache_list_release();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 08:41:04 +00:00
|
|
|
|
|
|
|
|
|
|
2019-08-28 07:29:18 +00:00
|
|
|
|
module_init(dpi_cahce_module_init);
|
2019-09-06 08:41:04 +00:00
|
|
|
|
module_exit(dpi_cache_module_exit);
|
2019-08-28 07:29:18 +00:00
|
|
|
|
MODULE_LICENSE("GPL");
|
2019-09-06 08:41:04 +00:00
|
|
|
|
MODULE_DESCRIPTION("rpdb process module");
|
|
|
|
|
MODULE_AUTHOR("wuhuanzheng");
|
2019-08-28 07:29:18 +00:00
|
|
|
|
|