106 lines
3.2 KiB
C
106 lines
3.2 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 "../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.目的端口不是80的情况下,判断协议是否是DHCP和DNS,如果是DHCP和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;
|
|||
|
}
|
|||
|
|