netfilter.h的解释

这个文件是2.4防火墙总处理程序的头文件。主要是向内核其他部分、应用程序提供接口。我将结合源文件一一说明。 

#ifndef __LINUX_NETFILTER_H 
#define __LINUX_NETFILTER_H 

#ifdef __KERNEL__ 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#endif 

以下几个值是向内核提供的接口函数的返回值,也就是在ip_input.c ip_forward.c ip_output.c所调用宏调用的处理函数的返回值。 
/* Responses from hook functions. */ 
#define NF_DROP 0 表示分组将要被丢弃,并且不返回ICMP信息 
#define NF_ACCEPT 1 表示分组被接受 
#define NF_STOLEN 2 表示异常分组 
#define NF_QUEUE 3 表示分组将要提交给用户进程 
#define NF_REPEAT 4 表示分组将要被继续处理 
#define NF_MAX_VERDICT NF_REPEAT 

/* Generic cache responses from hook functions. */ 
#define NFC_ALTERED 0x8000 
#define NFC_UNKNOWN 0x4000 

#ifdef __KERNEL__ 
#include 
#ifdef CONFIG_NETFILTER 

extern void netfilter_init(void); 

/* Largest hook number + 1 */ 
#define NF_MAX_HOOKS 8 

struct sk_buff; 向前声明结构 
struct net_device; 

声明hook函数类型 
typedef unsigned int nf_hookfn(unsigned int hooknum, 
struct sk_buff **skb, 
const struct net_device *in, 
const struct net_device *out, 
int (*okfn)(struct sk_buff *)); 

向内核提供的防火墙接口 
struct nf_hook_ops 

struct list_head list; 将多个接口函数组成链表 

/* User fills in from here down. */ 
nf_hookfn *hook; hook函数指针,指向防火墙处理函数,它的返回值就是上面说明的值 
int pf; 协议值,表示这个接口属于那个协议族 
int hooknum;表示这个接口属于哪个HOOK LOCAL_INPUT、 LOCAL_OUT FORWARD、PREROUTING 还是 AFTERROUTING 

/* Hooks are ordered in ascending priority. */ 
int priority; 接口的优先级 
}; 

向用户进程提供的放火墙接口,用户进程通过这个接口设置规则。 
struct nf_sockopt_ops 

struct list_head list; 同上 

int pf; 同上 
当调用setsockopt和getsockopt系统调用时,用户通常给定命令常数。下面的范围就是给定命令常数的范围。这里要设置范围主要是因为ip_tables 和ipchains处理的命令常数的范围不同。 
/* Non-inclusive ranges: use 0/0/NULL to never get called. */ 
int set_optmin; 
int set_optmax; 
int (*set)(struct sock *sk, int optval, void *user, unsigned int len); 

int get_optmin; 
int get_optmax; 
int (*get)(struct sock *sk, int optval, void *user, int *len); 

/* Number of users inside set() or get(). */ 
unsigned int use;指示当前有几个进程在使用该模块 
struct task_struct *cleanup_task;这指针指向想要释放该接口的进程。如果有进程正在使用该接口,那么当前进程将被阻塞。最后当使用接口的进程使用完毕时,它通过该指针唤醒本进程,最终释放这个结构。 

}; 

如注释所述,它主要是附加到每一个提交给用户进程的IP分组上(skbuff是报文的载体) 
/* Each queued (to userspace) skbuff has one of these. */ 
struct nf_info 

/* The ops struct which sent us to userspace. */ 
struct nf_hook_ops *elem; 

/* If we're sent to userspace, this keeps housekeeping info */ 
int pf; 
unsigned int hook; 
struct net_device *indev, *outdev; 
int (*okfn)(struct sk_buff *); 
}; 

下面两个函数是提供给各个放火墙模块的HOOK注册函数。它实质上是为了建立内核与防火墙的接口链表,当用有分组达到是可以沿着链表一一处理 
/* Function to register/unregister hook points. */ 
int nf_register_hook(struct nf_hook_ops *reg); 
void nf_unregister_hook(struct nf_hook_ops *reg); 

这是提供给各个防火墙模块的,用来设置处理用户进程set/getsockopt系统调用的注册函数。它将建立一个处理链表,当用户发出set/getsockopt系统调用时,由内核根据命令常数的范围判断防火墙内核的响应处理函数 
/* Functions to register get/setsockopt ranges (non-inclusive). You 
need to check permissions yourself! */ 
int nf_register_sockopt(struct nf_sockopt_ops *reg); 
void nf_unregister_sockopt(struct nf_sockopt_ops *reg); 

extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; HOOK链表 

/* Activate hook; either okfn or kfree_skb called, unless a hook 
returns NF_STOLEN (in which case, it's up to the hook to deal with 
the consequences). 

Returns -ERRNO if packet dropped. Zero means queued, stolen or 
accepted. 
*/ 

/* RR: 
> I don't want nf_hook to return anything because people might forget 
> about async and trust the return value to mean "packet was ok". 

AK: 
Just document it clearly, then you can expect some sense from kernel 
coders :) 
*/ 

/* This is gross, but inline doesn't cut it for avoiding the function 
call in fast path: gcc doesn't inline (needs value tracking?). --RR */ 
下面这个宏就是提供给网络内核的接口宏。我们先看看它的参数。pf是指地址族,因为netfilter不光可以处理AF_INET还可以处理其它 协议,而HOOK是根据协议族分类的。hook指示五个HOOK中的哪一个规则链来处理调用该宏的分组。indev和outdev分别指示进入的网络接口 和发送的网络接口。okfn是指当防火墙处理完后,继续处理分组的网络内核函数,而不是防火墙模块的函数。从宏定义可以看出,当具体的地址族的具体 HOOK的规则连为空时,直接将分组控制权交给okfn,否则调用nf_hook_slow(),这个函数进一步调用hook函数处理链中的处理函数,别 忘了,前面我已经说过注册函数已经建立这个处理链表。最后将控制权交给okfn。 
#ifdef CONFIG_NETFILTER_DEBUG 
#define NF_HOOK nf_hook_slow 
#else 
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ 
(list_empty(&nf_hooks[(pf)][(hook)]) \ 
? (okfn)(skb) \ 
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn))) 
#endif 

int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, 
struct net_device *indev, struct net_device *outdev, 
int (*okfn)(struct sk_buff *)); 
防火墙netfilter中的对应于系统调用(s)getsockopt的处理函数。 
/* Call setsockopt() */ 
int nf_setsockopt(struct sock *sk, int pf, int optval, char *opt, 
int len); 
int nf_getsockopt(struct sock *sk, int pf, int optval, char *opt, 
int *len); 

/* Packet queuing */ 
用于处理递交给用户进程的分组的注册函数和处理函数 
typedef int (*nf_queue_outfn_t)(struct sk_buff *skb, 
struct nf_info *info, void *data); 
extern int nf_register_queue_handler(int pf, 
nf_queue_outfn_t outfn, void *data); 
extern int nf_unregister_queue_handler(int pf); 
extern void nf_reinject(struct sk_buff *skb, 
struct nf_info *info, 
unsigned int verdict); 

以下的定义容易理解,这里不在说明 
#ifdef CONFIG_NETFILTER_DEBUG 
extern void nf_dump_skb(int pf, struct sk_buff *skb); 
#endif 

/* FIXME: Before cache is ever used, this must be implemented for real. */ 
extern void nf_invalidate_cache(int pf); 

#else /* !CONFIG_NETFILTER */ 
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) 
#endif /*CONFIG_NETFILTER*/ 

/* From arch/i386/kernel/smp.c: 

* Why isn't this somewhere standard ?? 

* Maybe because this procedure is horribly buggy, and does 
* not deserve to live. Think about signedness issues for five 
* seconds to see why. - Linus 
*/ 

/* Two signed, return a signed. */ 
#define SMAX(a,b) ((ssize_t)(a)>(ssize_t)(b) ? (ssize_t)(a) : (ssize_t)(b)) 
#define SMIN(a,b) ((ssize_t)(a)<(ssize_t)(b) ? (ssize_t)(a) : (ssize_t)(b)) 

/* Two unsigned, return an unsigned. */ 
#define UMAX(a,b) ((size_t)(a)>(size_t)(b) ? (size_t)(a) : (size_t)(b)) 
#define UMIN(a,b) ((size_t)(a)<(size_t)(b) ? (size_t)(a) : (size_t)(b)) 

/* Two unsigned, return a signed. */ 
#define SUMAX(a,b) ((size_t)(a)>(size_t)(b) ? (ssize_t)(a) : (ssize_t)(b)) 
#define SUMIN(a,b) ((size_t)(a)<(size_t)(b) ? (ssize_t)(a) : (ssize_t)(b)) 
#endif /*__KERNEL__*/ 

#endif /*__LINUX_NETFILTER_H*/ 

好了,现在我已经介绍完了netfilter的头文件,下一次我将来分析netfilter.c。进一步介绍这些变量、函数、结构将如何使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值