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

📄 ipfwadm_core.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
#warning ipfwadm is obsolete, and will be removed soon./* Minor modifications to fit on compatibility framework:   Rusty.Russell@rustcorp.com.au*/#include <linux/config.h>#define CONFIG_IP_FIREWALL#define CONFIG_IP_FIREWALL_VERBOSE#define CONFIG_IP_MASQUERADE#define CONFIG_IP_ACCT#define CONFIG_IP_TRANSPARENT_PROXY#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)#define CONFIG_IP_FIREWALL_NETLINK#endif/* *	IP firewalling code. This is taken from 4.4BSD. Please note the *	copyright message below. As per the GPL it must be maintained *	and the licenses thus do not conflict. While this port is subject *	to the GPL I also place my modifications under the original *	license in recognition of the original copyright. *				-- Alan Cox. * *	$Id: ipfwadm_core.c,v 1.11 2002/01/24 15:50:31 davem Exp $ * *	Ported from BSD to Linux, *		Alan Cox 22/Nov/1994. *	Zeroing /proc and other additions *		Jos Vos 4/Feb/1995. *	Merged and included the FreeBSD-Current changes at Ugen's request *	(but hey it's a lot cleaner now). Ugen would prefer in some ways *	we waited for his final product but since Linux 1.2.0 is about to *	appear it's not practical - Read: It works, it's not clean but please *	don't consider it to be his standard of finished work. *		Alan Cox 12/Feb/1995 *	Porting bidirectional entries from BSD, fixing accounting issues, *	adding struct ip_fwpkt for checking packets with interface address *		Jos Vos 5/Mar/1995. *	Established connections (ACK check), ACK check on bidirectional rules, *	ICMP type check. *		Wilfred Mollenvanger 7/7/1995. *	TCP attack protection. *		Alan Cox 25/8/95, based on information from bugtraq. *	ICMP type printk, IP_FW_F_APPEND *		Bernd Eckenfels 1996-01-31 *	Split blocking chain into input and output chains, add new "insert" and *	"append" commands to replace semi-intelligent "add" command, let "delete". *	only delete the first matching entry, use 0xFFFF (0xFF) as ports (ICMP *	types) when counting packets being 2nd and further fragments. *		Jos Vos <jos@xos.nl> 8/2/1996. *	Add support for matching on device names. *		Jos Vos <jos@xos.nl> 15/2/1996. *	Transparent proxying support. *		Willy Konynenberg <willy@xos.nl> 10/5/96. *	Make separate accounting on incoming and outgoing packets possible. *		Jos Vos <jos@xos.nl> 18/5/1996. *	Added trap out of bad frames. *		Alan Cox <alan@cymru.net> 17/11/1996 * * * Masquerading functionality * * Copyright (c) 1994 Pauline Middelink * * The pieces which added masquerading functionality are totally * my responsibility and have nothing to with the original authors * copyright or doing. * * Parts distributed under GPL. * * Fixes: *	Pauline Middelink	:	Added masquerading. *	Alan Cox		:	Fixed an error in the merge. *	Thomas Quinot		:	Fixed port spoofing. *	Alan Cox		:	Cleaned up retransmits in spoofing. *	Alan Cox		:	Cleaned up length setting. *	Wouter Gadeyne		:	Fixed masquerading support of ftp PORT commands * *	Juan Jose Ciarlante	:	Masquerading code moved to ip_masq.c *	Andi Kleen :		Print frag_offsets and the ip flags properly. * *	All the real work was done by ..... * *//* * Copyright (c) 1993 Daniel Boulet * Copyright (c) 1994 Ugen J.S.Antsilevich * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * * Redistribution in binary form may occur without any restrictions. * Obviously, it would be nice if you gave credit where credit is due * but requiring it would be too onerous. * * This software is provided ``AS IS'' without any warranties of any kind. */#include <asm/uaccess.h>#include <asm/system.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/module.h>#include <linux/socket.h>#include <linux/sockios.h>#include <linux/in.h>#include <linux/inet.h>#include <linux/netdevice.h>#include <linux/icmp.h>#include <linux/udp.h>#include <net/ip.h>#include <net/protocol.h>#include <net/route.h>#include <net/tcp.h>#include <net/udp.h>#include <net/sock.h>#include <net/icmp.h>#include <linux/netlink.h>#include <linux/init.h>#include <linux/spinlock.h>#include <linux/netfilter_ipv4/ipfwadm_core.h>#include <linux/netfilter_ipv4/compat_firewall.h>#include <linux/netfilter_ipv4/lockhelp.h>#include <linux/netfilter_ipv4/ip_nat_core.h>#include <net/checksum.h>#include <linux/proc_fs.h>#include <linux/stat.h>MODULE_LICENSE("Dual BSD/GPL");MODULE_DESCRIPTION("ipfwadm backwards compatibility layer");/* *	Implement IP packet firewall */#ifdef DEBUG_IP_FIREWALL#define dprintf1(a)		printk(a)#define dprintf2(a1,a2)		printk(a1,a2)#define dprintf3(a1,a2,a3)	printk(a1,a2,a3)#define dprintf4(a1,a2,a3,a4)	printk(a1,a2,a3,a4)#else#define dprintf1(a)#define dprintf2(a1,a2)#define dprintf3(a1,a2,a3)#define dprintf4(a1,a2,a3,a4)#endif#define print_ip(a)	 printk("%u.%u.%u.%u", NIPQUAD(a));#ifdef DEBUG_IP_FIREWALL#define dprint_ip(a)	print_ip(a)#else#define dprint_ip(a)#endifstatic DECLARE_RWLOCK(ip_fw_lock);#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)struct ip_fw *ip_fw_fwd_chain;struct ip_fw *ip_fw_in_chain;struct ip_fw *ip_fw_out_chain;struct ip_fw *ip_acct_chain;struct ip_fw *ip_masq_chain;static struct ip_fw **chains[] =	{&ip_fw_fwd_chain, &ip_fw_in_chain, &ip_fw_out_chain, &ip_acct_chain,	 &ip_masq_chain	};#endif /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */#ifdef CONFIG_IP_FIREWALLint ip_fw_fwd_policy=IP_FW_F_ACCEPT;int ip_fw_in_policy=IP_FW_F_ACCEPT;int ip_fw_out_policy=IP_FW_F_ACCEPT;static int *policies[] =	{&ip_fw_fwd_policy, &ip_fw_in_policy, &ip_fw_out_policy};#endif#ifdef CONFIG_IP_FIREWALL_NETLINKstruct sock *ipfwsk;#endif/* *	Returns 1 if the port is matched by the vector, 0 otherwise */extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag){	if (!nports)		return 1;	if ( range_flag )	{		if ( portptr[0] <= port && port <= portptr[1] )		{			return( 1 );		}		nports -= 2;		portptr += 2;	}	while ( nports-- > 0 )	{		if ( *portptr++ == port )		{			return( 1 );		}	}	return(0);}#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)#ifdef CONFIG_IP_FIREWALL_VERBOSE/* *	VERY ugly piece of code which actually makes kernel printf for * 	matching packets. */static char *chain_name(struct ip_fw *chain, int mode){	switch (mode) {	case IP_FW_MODE_ACCT_IN: return "acct in";	case IP_FW_MODE_ACCT_OUT: return "acct out";	default:		if (chain == ip_fw_fwd_chain)			return "fw-fwd";		else if (chain == ip_fw_in_chain)			return "fw-in";		else			return "fw-out";	}}static char *rule_name(struct ip_fw *f, int mode, char *buf){	if (mode == IP_FW_MODE_ACCT_IN || mode == IP_FW_MODE_ACCT_OUT)		return "";	if(f->fw_flg&IP_FW_F_ACCEPT) {		if(f->fw_flg&IP_FW_F_REDIR) {			sprintf(buf, "acc/r%d ", f->fw_pts[f->fw_nsp+f->fw_ndp]);			return buf;		} else if(f->fw_flg&IP_FW_F_MASQ)			return "acc/masq ";		else			return "acc ";	} else if(f->fw_flg&IP_FW_F_ICMPRPL) {		return "rej ";	} else {		return "deny ";	}}static void print_packet(struct sk_buff **pskb,			 u16 src_port, u16 dst_port, u16 icmp_type,			 char *chain, char *rule, char *devname){	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);	int opti;	__u16 foff = ntohs((*pskb)->nh.iph->frag_off);	int protocol = (*pskb)->nh.iph->protocol;	printk(KERN_INFO "IP %s %s%s", chain, rule, devname);	switch (protocol) {	case IPPROTO_TCP:		printk(" TCP ");		break;	case IPPROTO_UDP:		printk(" UDP ");		break;	case IPPROTO_ICMP:		printk(" ICMP/%d ", icmp_type);		break;	default:		printk(" PROTO=%d ", protocol);		break;	};	print_ip((*pskb)->nh.iph->saddr);	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)		printk(":%hu", src_port);	printk(" ");	print_ip((*pskb)->nh.iph->daddr);	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)		printk(":%hu", dst_port);	printk(" L=%hu S=0x%2.2hX I=%hu FO=0x%4.4hX T=%hu",	       ntohs((*pskb)->nh.iph->tot_len),	       (*pskb)->nh.iph->tos,	       ntohs((*pskb)->nh.iph->id),	       foff & IP_OFFSET,	       (*pskb)->nh.iph->ttl);	if (foff & IP_DF)		printk(" DF=1");	if (foff & IP_MF)		printk(" MF=1");	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)		printk(" O=0x%8.8X", *opt++);	printk("\n");}#endif/* *	Returns one of the generic firewall policies, like FW_ACCEPT. *	Also does accounting so you can feed it the accounting chain. * *	The modes is either IP_FW_MODE_FW (normal firewall mode), *	IP_FW_MODE_ACCT_IN or IP_FW_MODE_ACCT_OUT (accounting mode, *	steps through the entire chain and handles fragments *	differently), or IP_FW_MODE_CHK (handles user-level check, *	counters are not updated). */int ip_fw_chk(struct sk_buff **pskb,	      struct net_device *rif, __u16 *redirport,	      struct ip_fw *chain, int policy, int mode){	struct ip_fw *f;	__u32			src, dst;	__u16			src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;	unsigned short		f_prt=0, prt;	char			notcpsyn=0, notcpack=0, match;	unsigned short		offset;	int			answer;	unsigned char		tosand, tosxor;	int			protocol;	/*	 *	If the chain is empty follow policy. The BSD one	 *	accepts anything giving you a time window while	 *	flushing and rebuilding the tables.	 */	/*	 *	This way we handle fragmented packets.	 *	we ignore all fragments but the first one	 *	so the whole packet can't be reassembled.	 *	This way we relay on the full info which	 *	stored only in first packet.	 *	 *	Note that this theoretically allows partial packet	 *	spoofing. Not very dangerous but paranoid people may	 *	wish to play with this. It also allows the so called	 *	"fragment bomb" denial of service attack on some types	 *	of system.	 */	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;	protocol = (*pskb)->nh.iph->protocol;	/*	 *	Don't allow a fragment of TCP 8 bytes in. Nobody	 *	normal causes this. Its a cracker trying to break	 *	in by doing a flag overwrite to pass the direction	 *	checks.	 */	if (offset == 1 && protocol == IPPROTO_TCP)		return FW_BLOCK;	if (offset!=0 && !(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)) &&		(protocol == IPPROTO_TCP ||		 protocol == IPPROTO_UDP ||		 protocol == IPPROTO_ICMP))		return FW_ACCEPT;	/*	 *	 Header fragment for TCP is too small to check the bits.	 */	if (protocol == IPPROTO_TCP &&	    ((*pskb)->nh.iph->ihl<<2)+16 > ntohs((*pskb)->nh.iph->tot_len))		return FW_BLOCK;	/*	 *	Too short.	 *	 *	But only too short for a packet with ports...	 */	else if ((ntohs((*pskb)->nh.iph->tot_len) <		  8 + ((*pskb)->nh.iph->ihl << 2)) &&		 (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP))		return FW_BLOCK;	src = (*pskb)->nh.iph->saddr;	dst = (*pskb)->nh.iph->daddr;	/*	 *	If we got interface from which packet came	 *	we can use the address directly. This is unlike	 *	4.4BSD derived systems that have an address chain	 *	per device. We have a device per address with dummy	 *	devices instead.	 */	dprintf1("Packet ");	switch (protocol) {		case IPPROTO_TCP:			dprintf1("TCP ");			/* ports stay 0xFFFF if it is not the first fragment */			if (!offset) {				struct tcphdr _tcph, *th;				th = skb_header_pointer(*pskb,							(*pskb)->nh.iph->ihl*4,							sizeof(_tcph), &_tcph);				if (th == NULL)					return FW_BLOCK;				src_port = ntohs(th->source);				dst_port = ntohs(th->dest);				if(!th->ack && !th->rst)					/* We do NOT have ACK, value TRUE */					notcpack = 1;				if(!th->syn || !notcpack)					/* We do NOT have SYN, value TRUE */					notcpsyn = 1;			}			prt = IP_FW_F_TCP;			break;		case IPPROTO_UDP:			dprintf1("UDP ");			/* ports stay 0xFFFF if it is not the first fragment */			if (!offset) {				struct udphdr _udph, *uh;				uh = skb_header_pointer(*pskb,							(*pskb)->nh.iph->ihl*4,							sizeof(_udph), &_udph);				if (uh == NULL)					return FW_BLOCK;				src_port = ntohs(uh->source);				dst_port = ntohs(uh->dest);			}			prt = IP_FW_F_UDP;			break;		case IPPROTO_ICMP:			/* icmp_type stays 255 if it is not the first fragment */			if (!offset) {				struct icmphdr _icmph, *ic;				ic = skb_header_pointer(*pskb,							(*pskb)->nh.iph->ihl*4,							sizeof(_icmph),							&_icmph);				if (ic == NULL)					return FW_BLOCK;				icmp_type = (__u16) ic->type;			}			dprintf2("ICMP:%d ", icmp_type);			prt = IP_FW_F_ICMP;			break;		default:			dprintf2("p=%d ", protocol);			prt = IP_FW_F_ALL;			break;	}#ifdef DEBUG_IP_FIREWALL	dprint_ip(src);	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)		/* This will print 65535 when it is not the first fragment! */		dprintf2(":%d ", src_port);	dprint_ip(dst);	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)		/* This will print 65535 when it is not the first fragment! */		dprintf2(":%d ", dst_port);	dprintf1("\n");#endif	if (mode == IP_FW_MODE_CHK)		READ_LOCK(&ip_fw_lock);	else

⌨️ 快捷键说明

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