154 lines
5.4 KiB
C
154 lines
5.4 KiB
C
#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;
|
||
}
|
||
}
|
||
}
|
||
|