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

106 lines
3.2 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 "../modules/userhash/k-userhash.h"
#include "../modules/usercfgrcv/usercfg_kinit.h"
#include <asm-generic/int-ll64.h>
#include <linux/netfilter.h>
extern struct list_head hash_array[];
extern freeauth_configure_t *kfreeauth;
/*匹配免认证规则 */
int judge(u_int8_t proto, __be32 sip, __be32 dip, __be16 dport )
{
/*免认证规则要求是http报文,http基于tcp协议 */
if (proto != 6) return 0;
if ((sip != kfreeauth->sip) && (dip != kfreeauth->dip)) return 0;
if (dport != kfreeauth->dport) return 0;
return 1;
}
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;
USERINFO *kresult;
kresult = (USERINFO *)kmalloc(sizeof(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");
kfree(kresult);
return EIO;
}
/*1.判断用户认证成功 ——非重定向
2.
3.80
4.80DHCP和DNSDHCP和DNS
5. drop*/
kresult = search_user(tuple->src.u3.ip);
/*用户已经认证通过 */
if(kresult != NULL)
{
kfree(kresult);
return NF_ACCEPT;
}
/*报文匹配免认证规则 */
result = judge(tuple->dst.protonum, tuple->src.u3.ip, tuple->dst.u3.ip, tuple->dst.u.tcp.port );
if (result == 1)
{
kfree(kresult);
return NF_ACCEPT;
}
/*80端口接入的HTTP报文重定向到Web Server */
if((tuple->dst.protonum == 6) && (tuple->dst.u.tcp.port == 80))
{
/*打重定向Mark标记 */
kfree(kresult);
}
else
{
/*dhcp报文 dns报文 默认放行 */
if((tuple->dst.u.tcp.port == 67) || (tuple->dst.u.tcp.port == 68) || (tuple->dst.u.tcp.port ==53))
{
kfree(kresult);
return NF_ACCEPT;
}
}
kfree(kresult);
return NF_DROP;
}