原标题:Linux网络子系统安全性模块详细分析之核心文件分析-结构体定义及内外部函数
2.4.2.3结构体定义
nf_hook_ops 结构体定义如下:
struct nf_hook_ops {
struct list_head list;
nf_hookfn *hook;
struct module *owner;
u_int8_t pf;
unsigned int hooknum;
int priority;
};
该结构体描述钩子点的操作集合。list成员将钩子点上的所有集合用链表组织起来;hook表示钩子点的处理函数;hooknum表示钩子点的序号;priority表示操作集的优先级。
2.4.2.4 外部函数
参见2.4.1和2.4.3
2.4.2.5 内部函数
1.nf_nat_standalone_init( )函数原型:static int __init nf_nat_standalone_init(void)函数参数:空。函数功能:完成nat表的初始化,并进一步对nat进行注册,同时注册了两个target,SNAT和DNAT;完成操作集的注册。返回值:成功时返回0;反之返回相应的错误码。2. nf_nat_fn( )函数原型:static unsigned int nf_nat_fn(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out, int (*okfn)(struct sk_buff *))函数参数:hooknum表示哪一个钩子点处,skb表示数据包的结构体,out表示出去的网络设备接口,in表示进来的网络设备接口,okfn执行数据包的处理函数指针。函数功能:nf_nat_fn( )函数会根据连接信息结构体ip_conntrack_info,也就是连接的方向,这里主要就分两个方向,判断是发送的包还是回应的包。如果是发送的包,会首先调用nf_nat_rule_find( )函数查找规则,并调用ipt_do_table( ),进行规则的遍历,并执行目标。返回值:不成功时返回相应的错误码。2.4.2.6 核心代码注释
nf_nat_fn( )是nat hook的主处理函数,其它几个钩子函数最终都调用这个函数。nf_nat_fn( )函数会根据连接信息结构体ip_conntrack_info,也就是连接的方向,判断是发送的包还是回应的包。如果是发送的包,会首先调用nf_nat_rule_find( )函数查找规则,并调用ipt_do_table( ),进行规则的遍历,并执行目标为SNAT的操作。
static unsigned int nf_nat_fn(unsigned int hooknum,struct sk_buff *skb,
const struct net_device *in,const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
struct nf_conn_nat *nat;
/*标志snat还是dnat转换*/
enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum)
NF_CT_ASSERT(!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)));
ct = nf_ct_get(skb, &ctinfo);
/* 如果找不到对应连接,直接让其通过*/
if (!ct)
return NF_ACCEPT;
/*如果没有连接跟踪则不进行NAT处理*/
if (nf_ct_is_untracked(ct))
return NF_ACCEPT;
…
/*根据连接状态进行相应处理*/
switch (ctinfo) {
/*应答的数据包*/
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
if (!nf_nat_icmp_reply_translation(ct, ctinfo,hooknum, skb))
return NF_DROP;
else
return NF_ACCEPT;
}
case IP_CT_NEW: /*新连接*/
if (!nf_nat_initialized(ct, maniptype)) {
unsigned int ret;
ret = nf_nat_rule_find(skb, hooknum, in, out, ct); /*查找规则*/
} else
pr_debug("Already setup manip %s for ct %pn",
maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
ct);
break;
default:
/*已建立的连接*/
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
}
return nf_nat_packet(ct, ctinfo, hooknum, skb);
责任编辑: