#include <linux/module.h> #include <linux/kernel.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/netdevice.h> #include <linux/in.h>
MODULE_LICENSE("GPL"); MODULE_VERSION("1.0");
static struct nf_hook_ops nfho; unsigned int hook_func(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sk_buff *sb = *skb; struct iphdr *iph;
if(!sb) return NF_ACCEPT;
//iph = ip_hdr(sb);//for 2.4.X
iph = (struct iphdr*)sb->nh.iph;
if(!iph) return NF_ACCEPT; if(iph->protocol == IPPOROT_ICMP) { printk("Drop packet of TCP\n"); return NF_DROP; } return NF_ACCEPT; }
int init_module() { nfho.hook = hook_func; nfho.hooknum = NF_IP_ROUTING; nfho.pf = PF_INET; nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho); pr_info("Install Into Kernel\n"); return 0; }
void cleanup_module() { nf_unregister_hook(&nfho); pr_info("Removed From Kernel\n"); }
|
非原创,只为以后应用方便做记录
后记:
转换IP地址格式
printk("source ip :%d.%d.%d.%d:%u\n",NIPQUAD(iph->saddr));//从__be32转换为常用格式
NIPQUAD是IPv4用
NIP6是IPv6用
netfilter的hook点
在netfilter的hook点上为 contrack定义了如下几个挂接点,用来处理流经的ip包: NF_IP_PRE_ROUTING : ip_conntrack_defrag -> ip_conntrack_in NF_IP_LOCAL_IN : ip_conntrack_help -> ip_confirm NF_IP_LOCAL_OUT : ip_conntrack_defrag -> ip_conntrack_local NF_IP_POST_ROUTING :ip_conntrack_help -> ip_confirm其中ip_contrack_defrag用来处理报文分 片;ip_conntrack_in和ip_conntrack_local(内部调用ip_conntrack_in)用于conntrack为每个连 接建立模式记录,ip_conntrack,并判断报文是否符合合法的模式,不符合则丢弃;ip_conntrack_help是针对使用动态协议和端口 的连接设计的数据结构,如一个ftp连接针对数据流和控制流分别用到了两个端口,;ip_confirm判断报文所属的模式ip_conntrack是否 已经存在系统哈希中,否则加入到系统的hash中。
tuple
tuple 结构仅仅用来标识一个连接,并不是描述一条完整的连接状态,netfilter将数据包转换成tuple结构,并根据其计算hash,在相应的链表上查询,获取相应的连接状态,如果没有查到,则表示是一个新的连接。
内核中,描述一个包的连接状态,使用了struct ip_conntrack(ip_conntrack.h) 结构
阅读(3132) | 评论(0) | 转发(0) |