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

154 lines
5.4 KiB
C
Raw Normal View History

#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.80DHCP和DNSDHCP和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;
}
}
}