4.4简单示例:
以下提供的是一个示例代码,该示例代码简单的注册了一个丢弃所有到达的数据包的函数。该代码同时展示了Netfilter的返回值如何被解析。
/*
* 安装一个丢弃所有到达的数据包的Netfilter hook函数的示例代码
*/
#define __KERNEL__
#define MODULE
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;
/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;
/* 注册的hook函数的实现 */
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 *))
{
return NF_DROP; /* 丢弃所有的数据包 */
}
/* 初始化程序 */
int init_module()
{
/* 填充我们的hook数据结构 */
nfho.hook = hook_func; /* 处理函数 */
nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST; /* 让我们的函数首先执行 */
nf_register_hook(&nfho);
return 0;
}
/* 清除程序 */
void cleanup_module()
{
nf_unregister_hook(&nfho);
}
MODULE_LICENSE("GPL"); //表示采用的开放协议
module_init(init_module); //
module_exit(cleanup_module); //
4.5基于源接口的数据包过滤
后面这些代码摘自LWFW
使用相应的net_device数据结构的name这个成员,通过比对接口名字,就可以根据数据包的源接口和目的接口来选择是否丢弃它
*
* 安装一个丢弃所有进入我们指定接口的数据包的Netfilter hook函数的示例代码
*/
#define __KERNEL__
#define MODULE
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/netdevice.h>;
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;
/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;
/* 我们丢弃的数据包来自的接口的名字 */
static char *drop_if = "lo";
/* 注册的hook函数的实现 */
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 *))
{
if (strcmp(in->name, drop_if) == 0) { //入接口名称
printk("Dropped packet on %s.../n", drop_if);
return NF_DROP;
} else {
return NF_ACCEPT;
}
}
/* 初始化程序 */
int init_module()
{
/* 填充我们的hook数据结构 */
nfho.hook = hook_func; /* 处理函数 */
nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST; /* 让我们的函数首先执行 */
nf_register_hook(&nfho);
return 0;
}
/* 清除程序 */
void cleanup_module()
{
nf_unregister_hook(&nfho);
}
MODULE_LICENSE("GPL"); //表示采用的开放协议
module_init(init_module); //
module_exit(cleanup_module); //
4.6 基于地址进行过滤
基于数据包的源或目的IP地址进行过滤同样简单
unsigned char *deny_ip = "/x7f/x00/x00/x01"; /* 127.0.0.1 */
static int check_ip_packet(struct sk_buff *skb)
{
/* We don't want any NULL pointers in the chain to
* the IP header. */
if (!skb )return NF_ACCEPT;
if (!(skb->;nh.iph)) return NF_ACCEPT;
if (skb->nh.iph->saddr == *(unsigned int *)deny_ip) {
return NF_DROP;
}
return NF_ACCEPT;
}
如果数据包的源地址与我们设定的丢弃数据包的地址匹配,那么该数据包将被丢弃。
为了使这个函数能按预期的方式工作,deny_ip的值应当以网络字节序(Big-endian,与Intel相反)存放
4.7基于数据包源地址的过滤
/* 安装丢弃所有来自指定IP地址的数据包的Netfilter hook的示例代码 */
#define __KERNEL__
#define MODULE
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/skbuff.h>;
#include <linux/ip.h>; /* For IP header */
#include <linux/netfilter.h>;
#include <linux/netfilter_ipv4.h>;
/* 用于注册我们的函数的数据结构 */
static struct nf_hook_ops nfho;
/* 我们要丢弃的数据包来自的地址,网络字节序 */
static unsigned char *drop_ip = "/x7f/x00/x00/x01";
/* 注册的hook函数的实现 */
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;
if (sb->nh.iph->saddr == *(unsigned int *)drop_ip) {
printk("Dropped packet from... %d.%d.%d.%d/n",
*drop_ip, *(drop_ip + 1),*(drop_ip + 2), *(drop_ip + 3));
return NF_DROP;
} else {
return NF_ACCEPT;
}
}
/* 初始化程序 */
int init_module()
{
/* 填充我们的hook数据结构 */
nfho.hook = hook_func; /* 处理函数 */
nfho.hooknum = NF_IP_PRE_ROUTING; /* 使用IPv4的第一个hook */
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST; /* 让我们的函数首先执行 */
nf_register_hook(&nfho);
return 0;
}
/* 清除程序 */
void cleanup_module()
{
nf_unregister_hook(&nfho);
}
4.8基于TCP端口进行过滤
unsigned char *deny_port = "/x00/x19"; /* port 25 deny_port必须是网络字节序 */
static int check_tcp_packet(struct sk_buff *skb)
{
struct tcphdr *thead;
/* We don't want any NULL pointers in the chain
* to the IP header. */
if (!skb ) return NF_ACCEPT;
if (!(skb->;nh.iph)) return NF_ACCEPT;
/* Be sure this is a TCP packet first */
if (skb->;nh.iph->;protocol != IPPROTO_TCP) {
return NF_ACCEPT;
}
thead = (struct tcphdr *)(skb->;data +
(skb->;nh.iph->;ihl * 4));
/* Now check the destination port */
if ((thead->;dest) == *(unsigned short *)deny_port) {
return NF_DROP;
}
return NF_ACCEPT;
}