#include #include #include #include #include #include #include #include #include #include #include "../modules/userhash/k-userhash.h" #include "../modules/usercfgrcv/usercfg_kinit.h" #include #include 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; }