⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netfilter.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (ops->cleanup_task)		wake_up_process(ops->cleanup_task);	up(&nf_sockopt_mutex);	return ret;}int nf_setsockopt(struct sock *sk, int pf, int val, char *opt,		  int len){	return nf_sockopt(sk, pf, val, opt, &len, 0);}int nf_getsockopt(struct sock *sk, int pf, int val, char *opt, int *len){	return nf_sockopt(sk, pf, val, opt, len, 1);}static unsigned int nf_iterate(struct list_head *head,			       struct sk_buff **skb,			       int hook,			       const struct net_device *indev,			       const struct net_device *outdev,			       struct list_head **i,			       int (*okfn)(struct sk_buff *)){	for (*i = (*i)->next; *i != head; *i = (*i)->next) {		struct nf_hook_ops *elem = (struct nf_hook_ops *)*i;		switch (elem->hook(hook, skb, indev, outdev, okfn)) {		case NF_QUEUE:			return NF_QUEUE;		case NF_STOLEN:			return NF_STOLEN;		case NF_DROP:			return NF_DROP;		case NF_REPEAT:			*i = (*i)->prev;			break;#ifdef CONFIG_NETFILTER_DEBUG		case NF_ACCEPT:			break;		default:			NFDEBUG("Evil return from %p(%u).\n", 				elem->hook, hook);#endif		}	}	return NF_ACCEPT;}int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data){      	int ret;	br_write_lock_bh(BR_NETPROTO_LOCK);	if (queue_handler[pf].outfn)		ret = -EBUSY;	else {		queue_handler[pf].outfn = outfn;		queue_handler[pf].data = data;		ret = 0;	}	br_write_unlock_bh(BR_NETPROTO_LOCK);	return ret;}/* The caller must flush their queue before this */int nf_unregister_queue_handler(int pf){	br_write_lock_bh(BR_NETPROTO_LOCK);	queue_handler[pf].outfn = NULL;	queue_handler[pf].data = NULL;	br_write_unlock_bh(BR_NETPROTO_LOCK);	return 0;}/*  * Any packet that leaves via this function must come back  * through nf_reinject(). */static void nf_queue(struct sk_buff *skb, 		     struct list_head *elem, 		     int pf, unsigned int hook,		     struct net_device *indev,		     struct net_device *outdev,		     int (*okfn)(struct sk_buff *)){	int status;	struct nf_info *info;	if (!queue_handler[pf].outfn) {		kfree_skb(skb);		return;	}	info = kmalloc(sizeof(*info), GFP_ATOMIC);	if (!info) {		if (net_ratelimit())			printk(KERN_ERR "OOM queueing packet %p\n",			       skb);		kfree_skb(skb);		return;	}	*info = (struct nf_info) { 		(struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn };	/* Bump dev refs so they don't vanish while packet is out */	if (indev) dev_hold(indev);	if (outdev) dev_hold(outdev);	status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data);	if (status < 0) {		/* James M doesn't say fuck enough. */		if (indev) dev_put(indev);		if (outdev) dev_put(outdev);		kfree(info);		kfree_skb(skb);		return;	}}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 *)){	struct list_head *elem;	unsigned int verdict;	int ret = 0;	/* This stopgap cannot be removed until all the hooks are audited. */	if (skb_is_nonlinear(skb) && skb_linearize(skb, GFP_ATOMIC) != 0) {		kfree_skb(skb);		return -ENOMEM;	}	if (skb->ip_summed == CHECKSUM_HW) {		if (outdev == NULL) {			skb->ip_summed = CHECKSUM_NONE;		} else {			skb_checksum_help(skb);		}	}	/* We may already have this, but read-locks nest anyway */	br_read_lock_bh(BR_NETPROTO_LOCK);#ifdef CONFIG_NETFILTER_DEBUG	if (skb->nf_debug & (1 << hook)) {		printk("nf_hook: hook %i already set.\n", hook);		nf_dump_skb(pf, skb);	}	skb->nf_debug |= (1 << hook);#endif	elem = &nf_hooks[pf][hook];	verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev,			     outdev, &elem, okfn);	if (verdict == NF_QUEUE) {		NFDEBUG("nf_hook: Verdict = QUEUE.\n");		nf_queue(skb, elem, pf, hook, indev, outdev, okfn);	}	switch (verdict) {	case NF_ACCEPT:		ret = okfn(skb);		break;	case NF_DROP:		kfree_skb(skb);		ret = -EPERM;		break;	}	br_read_unlock_bh(BR_NETPROTO_LOCK);	return ret;}void nf_reinject(struct sk_buff *skb, struct nf_info *info,		 unsigned int verdict){	struct list_head *elem = &info->elem->list;	struct list_head *i;	/* We don't have BR_NETPROTO_LOCK here */	br_read_lock_bh(BR_NETPROTO_LOCK);	for (i = nf_hooks[info->pf][info->hook].next; i != elem; i = i->next) {		if (i == &nf_hooks[info->pf][info->hook]) {			/* The module which sent it to userspace is gone. */			NFDEBUG("%s: module disappeared, dropping packet.\n",			         __FUNCTION__);			verdict = NF_DROP;			break;		}	}	/* Continue traversal iff userspace said ok... */	if (verdict == NF_REPEAT) {		elem = elem->prev;		verdict = NF_ACCEPT;	}	if (verdict == NF_ACCEPT) {		verdict = nf_iterate(&nf_hooks[info->pf][info->hook],				     &skb, info->hook, 				     info->indev, info->outdev, &elem,				     info->okfn);	}	switch (verdict) {	case NF_ACCEPT:		info->okfn(skb);		break;	case NF_QUEUE:		nf_queue(skb, elem, info->pf, info->hook, 			 info->indev, info->outdev, info->okfn);		break;	case NF_DROP:		kfree_skb(skb);		break;	}	br_read_unlock_bh(BR_NETPROTO_LOCK);	/* Release those devices we held, or Alexey will kill me. */	if (info->indev) dev_put(info->indev);	if (info->outdev) dev_put(info->outdev);		kfree(info);	return;}#ifdef CONFIG_INET/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */int ip_route_me_harder(struct sk_buff **pskb){	struct iphdr *iph = (*pskb)->nh.iph;	struct rtable *rt;	struct rt_key key = { dst:iph->daddr,			      src:iph->saddr,			      oif:(*pskb)->sk ? (*pskb)->sk->bound_dev_if : 0,			      tos:RT_TOS(iph->tos)|RTO_CONN,#ifdef CONFIG_IP_ROUTE_FWMARK			      fwmark:(*pskb)->nfmark#endif			    };	struct net_device *dev_src = NULL;	int err;	/* accomodate ip_route_output_slow(), which expects the key src to be	   0 or a local address; however some non-standard hacks like	   ipt_REJECT.c:send_reset() can cause packets with foreign           saddr to be appear on the NF_IP_LOCAL_OUT hook -MB */	if(key.src && !(dev_src = ip_dev_find(key.src)))		key.src = 0;	if ((err=ip_route_output_key(&rt, &key)) != 0) {		printk("route_me_harder: ip_route_output_key(dst=%u.%u.%u.%u, src=%u.%u.%u.%u, oif=%d, tos=0x%x, fwmark=0x%lx) error %d\n",			NIPQUAD(iph->daddr), NIPQUAD(iph->saddr),			(*pskb)->sk ? (*pskb)->sk->bound_dev_if : 0,			RT_TOS(iph->tos)|RTO_CONN,#ifdef CONFIG_IP_ROUTE_FWMARK			(*pskb)->nfmark,#else			0UL,#endif			err);		goto out;	}	/* Drop old route. */	dst_release((*pskb)->dst);	(*pskb)->dst = &rt->u.dst;	/* Change in oif may mean change in hh_len. */	if (skb_headroom(*pskb) < (*pskb)->dst->dev->hard_header_len) {		struct sk_buff *nskb;		nskb = skb_realloc_headroom(*pskb,					    (*pskb)->dst->dev->hard_header_len);		if (!nskb) {			err = -ENOMEM;			goto out;		}		if ((*pskb)->sk)			skb_set_owner_w(nskb, (*pskb)->sk);		kfree_skb(*pskb);		*pskb = nskb;	}out:	if (dev_src)		dev_put(dev_src);	return err;}#endif /*CONFIG_INET*//* This does not belong here, but ipt_REJECT needs it if connection   tracking in use: without this, connection may not be in hash table,   and hence manufactured ICMP or RST packets will not be associated   with it. */void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);void __init netfilter_init(void){	int i, h;	for (i = 0; i < NPROTO; i++) {		for (h = 0; h < NF_MAX_HOOKS; h++)			INIT_LIST_HEAD(&nf_hooks[i][h]);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -