secgateway/Product/modules/match_rule/k-matchrule.c

154 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <net/net_namespace.h>
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_l3proto.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <linux/skbuff.h>
#include <net/netfilter/nf_conntrack_core.h>
#include "k-userhash.h"
//#include "../modules/usercfgrcv/usercfg_kinit.h"
#include <asm-generic/int-ll64.h>
#include <linux/netfilter.h>
#include "conntrack_api.h"
#include "nf_conntrack.h"
#include "k-matchrule.h"
#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/rtc.h>
#define AUTH_MARK_VALUE 1
#define agingtime 30*60
/*内核在线用户hash表*/
extern struct list_head khash_array[];
/*免认证规则以数组方式存储,用户态增删改移之后通过共享内存同步到内核*/
freeauth_configure_t freeauth_array[10] = {0};
int match_rule(const struct sk_buff *skb, u_int16_t l3num,
struct net *net,struct nf_conntrack_tuple *tuple)
{
const struct nf_conntrack_l3proto *l3proto;
const struct nf_conntrack_l4proto *l4proto;
unsigned int nhoff; /*nhoff表示L3首部在skb中的偏移 */
unsigned int protoff;
u_int8_t protonum;
unsigned int dataoff; /*dataoff表示L4首部在skb中的偏移 */
int ret;
int result;
int match_num;
cmhi_ext_type type = AUTH_MARK;
int ret_result;
int i;
K_USERINFO *kresult;
kresult = (K_USERINFO *)kmalloc(sizeof(K_USERINFO), GFP_KERNEL);
if (NULL == kresult)
{
return ENOMEM;
}
/*获取版本号、源端口、目的端口、源IP、目的IP */
/*nf_ct_get_tuple函数主要根据协议号调用pkt_to_tuple生成一个tuple */
/*tcp/udp协议就是生成五元组(源ip、目的ip、源端口、目的端口、协议号)icmp协议就是(id、code、type) */
ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, net, tuple, l3proto, l4proto);
if(ret == 0)
{
printk("resolve_normal_ct: can't get tuple\n");
return EIO;
}
/*1.判断用户认证成功 ——非重定向
2.判断是否符合免认证规则 ——非重定向
3.判断目的端口是否是80—— 重定向标记
4.目的端口不是80的情况下判断协议是否是DHCP和DNS如果是DHCP和DNS——非重定向
5.其余包 drop*/
kresult = search_user(tuple->src.u3.ip);
/*用户已经认证通过 */
if(kresult != NULL)
{
struct timex txc;
struct rtc_time tm;
do_gettimeofday(&(txc.time));
printk("online time:%d\n", txc.time.tv_sec); /* seconds */
rtc_time_to_tm(txc.time.tv_sec,&tm);
printk("UTC time:%d-%d-%d %d-%d-%d\n", tm.tm_year + 1900 , tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
if(txc.time.tv_sec >= agingtime)
{
/*用户下线*/
del_user(tuple->src.u3.ip);
printk("user offline success\n");
}
else
{
int r = add_user(tuple->src.u3.ip, kresult->k_user.kuser_name, kresult->k_user.kuser_id, kresult->k_user.kgroup_id,
kresult->k_user.kmessage_num, kresult->k_user.kgroup_id, txc.time.tv_sec);
if(r == 0)
{
printk("add user success\n");
}
}
/*认证通过后获取下行字节数,存入在线用户hash表*/
#if 0
int r1 = add_user(tuple->src.u3.ip, kresult->k_user.kuser_name, kresult->k_user.kuser_id, kresult->k_user.kgroup_id,
ddd kresult->k_user.kgroup_id, txc.time.tv_sec);
if(r1 == 0)
{
printk("add user success\n");
}
#endif
kfree(kresult);
return NF_ACCEPT;
}
/*报文按优先级匹配免认证规则 */
for(i; i < 10; i++)
{
/*匹配免认证规则 协议为HTTP协议,HTTP基于TCP, 源IP地址、目的IP地址、目的端口号依次匹配免认证规则*/
printk("number of freeauth rule:%d\n", i);
if((tuple->dst.protonum == 6) && (tuple->src.u3.ip == freeauth_array[i].sip) && (tuple->dst.u3.ip = freeauth_array[i].dip) &&
(tuple->dst.u.tcp.port == freeauth_array[i].dport))
{
match_num++;
printk("value of match number:%d\n", match_num);
break;
}
}
if(match_num == 0)
{
/*80端口接入的HTTP报文重定向到Web Server */
if((tuple->dst.protonum == 6) && (tuple->dst.u.tcp.port == 80))
{
/*打重定向Mark标记 */
printk(KERN_INFO"[test_set_correct_value] test set auth_mark 1\n");
ret_result = cmhi_set_conntrack_u32(skb, AUTH_MARK_VALUE, type);
if(ret_result == CMHI_EXT_ERR)
{
printk(KERN_INFO"[test_set_correct_value] set auth_mark failed\n");
}
printk(KERN_INFO"[test_set_correct_value] set auth_mark successed\n");
return NF_ACCEPT;
}
else if((tuple->dst.u.tcp.port == 67) || (tuple->dst.u.tcp.port == 68) || (tuple->dst.u.tcp.port ==53))
{
printk("dhcp or dns\n");
return NF_ACCEPT;
}
else
{
printk("drop\n");
return NF_DROP;
}
}
}