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

📄 ipchains_core.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			}			else {				ret = ip_fw_check(ip, new->fwt_packet.fwp_vianame,						  NULL, chain,						  NULL, SLOT_NUMBER(), 1);				switch (ret) {				case FW_ACCEPT:					ret = 0; break;				case FW_REDIRECT:					ret = ECONNABORTED; break;				case FW_MASQUERADE:					ret = ECONNRESET; break;				case FW_REJECT:					ret = ECONNREFUSED; break;					/* Hack to help diag; these only get					   returned when testing. */				case FW_SKIP+1:					ret = ELOOP; break;				case FW_SKIP:					ret = ENFILE; break;				default: /* FW_BLOCK */					ret = ETIMEDOUT; break;				}			}		}		FWC_READ_UNLOCK(&ip_fw_lock);		return ret;	}	case IP_FW_MASQ_TIMEOUTS: {		ret = ip_fw_masq_timeouts(m, len);	}	break;	case IP_FW_REPLACE: {		struct ip_fwkernel *ip_fwkern;		struct ip_fwnew *new = m;		if (len != sizeof(struct ip_fwnew)		    || !check_label(new->fwn_label))			ret = EINVAL;		else if ((chain = find_label(new->fwn_label)) == NULL)			ret = ENOENT;		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))			 != NULL)			ret = replace_in_chain(chain, ip_fwkern,					       new->fwn_rulenum);	}	break;	case IP_FW_APPEND: {		struct ip_fwchange *new = m;		struct ip_fwkernel *ip_fwkern;		if (len != sizeof(struct ip_fwchange)		    || !check_label(new->fwc_label))			ret = EINVAL;		else if ((chain = find_label(new->fwc_label)) == NULL)			ret = ENOENT;		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))			 != NULL)			ret = append_to_chain(chain, ip_fwkern);	}	break;	case IP_FW_INSERT: {		struct ip_fwkernel *ip_fwkern;		struct ip_fwnew *new = m;		if (len != sizeof(struct ip_fwnew)		    || !check_label(new->fwn_label))			ret = EINVAL;		else if ((chain = find_label(new->fwn_label)) == NULL)			ret = ENOENT;		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))			 != NULL)			ret = insert_in_chain(chain, ip_fwkern,					      new->fwn_rulenum);	}	break;	case IP_FW_DELETE: {		struct ip_fwchange *new = m;		struct ip_fwkernel *ip_fwkern;		if (len != sizeof(struct ip_fwchange)		    || !check_label(new->fwc_label))			ret = EINVAL;		else if ((chain = find_label(new->fwc_label)) == NULL)			ret = ENOENT;		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))			 != NULL) {			ret = del_rule_from_chain(chain, ip_fwkern);			kfree(ip_fwkern);		}	}	break;	case IP_FW_DELETE_NUM: {		struct ip_fwdelnum *new = m;		if (len != sizeof(struct ip_fwdelnum)		    || !check_label(new->fwd_label))			ret = EINVAL;		else if ((chain = find_label(new->fwd_label)) == NULL)			ret = ENOENT;		else ret = del_num_from_chain(chain, new->fwd_rulenum);	}	break;	case IP_FW_CREATECHAIN: {		if (len != sizeof(ip_chainlabel)) {			duprintf("create_chain: bad size %i\n", len);			ret = EINVAL;		}		else ret = create_chain(m);	}	break;	case IP_FW_DELETECHAIN: {		if (len != sizeof(ip_chainlabel)) {			duprintf("delete_chain: bad size %i\n", len);			ret = EINVAL;		}		else ret = del_chain(m);	}	break;	case IP_FW_POLICY: {		struct ip_fwpolicy *new = m;		if (len != sizeof(struct ip_fwpolicy)		    || !check_label(new->fwp_label))			ret = EINVAL;		else if ((chain = find_label(new->fwp_label)) == NULL)			ret = ENOENT;		else if (chain != IP_FW_INPUT_CHAIN			 && chain != IP_FW_FORWARD_CHAIN			 && chain != IP_FW_OUTPUT_CHAIN) {			duprintf("change_policy: can't change policy on user"				 " defined chain.\n");			ret = EINVAL;		}		else {		        int pol = FW_SKIP;			find_special(new->fwp_policy, &pol);			switch(pol) {			case FW_MASQUERADE:				if (chain != IP_FW_FORWARD_CHAIN) {					ret = EINVAL;					break;				}				/* Fall thru... */			case FW_BLOCK:			case FW_ACCEPT:			case FW_REJECT:				ret = change_policy(chain, pol);				break;			default:			        duprintf("change_policy: bad policy `%s'\n",					 new->fwp_policy);				ret = EINVAL;			}		}		break;	}	default:		duprintf("ip_fw_ctl:  unknown request %d\n",cmd);		ret = ENOPROTOOPT;	}	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);	return ret;}/* Returns bytes used - doesn't NUL terminate */static int dump_rule(char *buffer,		     const char *chainlabel,		     const struct ip_fwkernel *rule){	int len;	unsigned int i;	__u64 packets = 0, bytes = 0;	FWC_HAVE_LOCK(fwc_wlocks);	for (i = 0; i < NUM_SLOTS; i++) {		packets += rule->counters[i].pcnt;		bytes += rule->counters[i].bcnt;	}	len=sprintf(buffer,		    "%9s "			/* Chain name */		    "%08X/%08X->%08X/%08X "	/* Source & Destination IPs */		    "%.16s "			/* Interface */		    "%X %X "			/* fw_flg and fw_invflg fields */		    "%u "			/* Protocol */		    "%-9u %-9u %-9u %-9u "	/* Packet & byte counters */		    "%u-%u %u-%u "		/* Source & Dest port ranges */		    "A%02X X%02X "		/* TOS and and xor masks */		    "%08X "			/* Redirection port */		    "%u "			/* fw_mark field */		    "%u "			/* output size */		    "%9s\n",			/* Target */		    chainlabel,		    ntohl(rule->ipfw.fw_src.s_addr),		    ntohl(rule->ipfw.fw_smsk.s_addr),		    ntohl(rule->ipfw.fw_dst.s_addr),		    ntohl(rule->ipfw.fw_dmsk.s_addr),		    (rule->ipfw.fw_vianame)[0] ? rule->ipfw.fw_vianame : "-",		    rule->ipfw.fw_flg,		    rule->ipfw.fw_invflg,		    rule->ipfw.fw_proto,		    (__u32)(packets >> 32), (__u32)packets,		    (__u32)(bytes >> 32), (__u32)bytes,		    rule->ipfw.fw_spts[0], rule->ipfw.fw_spts[1],		    rule->ipfw.fw_dpts[0], rule->ipfw.fw_dpts[1],		    rule->ipfw.fw_tosand, rule->ipfw.fw_tosxor,		    rule->ipfw.fw_redirpt,		    rule->ipfw.fw_mark,		    rule->ipfw.fw_outputsize,		    branchname(rule->branch,rule->simplebranch));	duprintf("dump_rule: %i bytes done.\n", len);	return len;}/* File offset is actually in records, not bytes. */static int ip_chain_procinfo(char *buffer, char **start,			     off_t offset, int length#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)			     , int reset#endif	){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */	int reset = 0;#endif	struct ip_chain *i;	struct ip_fwkernel *j = ip_fw_chains->chain;	unsigned long flags;	int len = 0;	int last_len = 0;	off_t upto = 0;	duprintf("Offset starts at %lu\n", offset);	duprintf("ip_fw_chains is 0x%0lX\n", (unsigned long int)ip_fw_chains);	/* Need a write lock to lock out ``readers'' which update counters. */	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);	for (i = ip_fw_chains; i; i = i->next) {	    for (j = i->chain; j; j = j->next) {		if (upto == offset) break;		duprintf("Skipping rule in chain `%s'\n",			 i->label);		upto++;	    }	    if (upto == offset) break;	}	/* Don't init j first time, or once i = NULL */	for (; i; (void)((i = i->next) && (j = i->chain))) {		duprintf("Dumping chain `%s'\n", i->label);		for (; j; j = j->next, upto++, last_len = len)		{			len += dump_rule(buffer+len, i->label, j);			if (len > length) {				duprintf("Dumped to %i (past %i).  "					 "Moving back to %i.\n",					 len, length, last_len);				len = last_len;				goto outside;			}			else if (reset)				memset(j->counters, 0,				       sizeof(struct ip_counters)*NUM_SLOTS);		}	}outside:	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);	buffer[len] = '\0';	duprintf("ip_chain_procinfo: Length = %i (of %i).  Offset = %li.\n",		 len, length, upto);	/* `start' hack - see fs/proc/generic.c line ~165 */	*start=(char *)((unsigned int)upto-offset);	return len;}static int ip_chain_name_procinfo(char *buffer, char **start,				  off_t offset, int length){	struct ip_chain *i;	int len = 0,last_len = 0;	off_t pos = 0,begin = 0;	unsigned long flags;	/* Need a write lock to lock out ``readers'' which update counters. */	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);	for (i = ip_fw_chains; i; i = i->next)	{		unsigned int j;		__u32 packetsHi = 0, packetsLo = 0, bytesHi = 0, bytesLo = 0;		for (j = 0; j < NUM_SLOTS; j++) {			packetsLo += i->reent[j].counters.pcnt & 0xFFFFFFFF;			packetsHi += ((i->reent[j].counters.pcnt >> 32)				      & 0xFFFFFFFF);			bytesLo += i->reent[j].counters.bcnt & 0xFFFFFFFF;			bytesHi += ((i->reent[j].counters.bcnt >> 32)				    & 0xFFFFFFFF);		}		/* print the label and the policy */		len+=sprintf(buffer+len,"%s %s %i %u %u %u %u\n",			     i->label,branchname(NULL, i->policy),i->refcount,			     packetsHi, packetsLo, bytesHi, bytesLo);		pos=begin+len;		if(pos<offset) {			len=0;			begin=pos;		}		else if(pos>offset+length) {			len = last_len;			break;		}		last_len = len;	}	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);	*start = buffer+(offset-begin);	len-=(offset-begin);	if(len>length)		len=length;	return len;}/* *	Interface to the generic firewall chains. */int ipfw_input_check(struct firewall_ops *this, int pf,		     struct net_device *dev, void *phdr, void *arg,		     struct sk_buff **pskb){	return ip_fw_check(phdr, dev->name,			   arg, IP_FW_INPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);}int ipfw_output_check(struct firewall_ops *this, int pf,		      struct net_device *dev, void *phdr, void *arg,		      struct sk_buff **pskb){	/* Locally generated bogus packets by root. <SIGH>. */	if (((struct iphdr *)phdr)->ihl * 4 < sizeof(struct iphdr)	    || (*pskb)->len < sizeof(struct iphdr))		return FW_ACCEPT;	return ip_fw_check(phdr, dev->name,			   arg, IP_FW_OUTPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);}int ipfw_forward_check(struct firewall_ops *this, int pf,		       struct net_device *dev, void *phdr, void *arg,		       struct sk_buff **pskb){	return ip_fw_check(phdr, dev->name,			   arg, IP_FW_FORWARD_CHAIN, *pskb, SLOT_NUMBER(), 0);}struct firewall_ops ipfw_ops={	NULL,	ipfw_forward_check,	ipfw_input_check,	ipfw_output_check,	NULL,	NULL};int ipfw_init_or_cleanup(int init){	struct proc_dir_entry *proc;	int ret = 0;	unsigned long flags;	if (!init) goto cleanup;#ifdef DEBUG_IP_FIREWALL_LOCKING	fwc_wlocks = fwc_rlocks = 0;#endif#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);	if (ipfwsk == NULL)		goto cleanup_nothing;#endif	ret = register_firewall(PF_INET, &ipfw_ops);	if (ret < 0)		goto cleanup_netlink;	proc = proc_net_create(IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR,			       ip_chain_procinfo);	if (proc) proc->owner = THIS_MODULE;	proc = proc_net_create(IP_FW_PROC_CHAIN_NAMES,			       S_IFREG | S_IRUSR | S_IWUSR,			       ip_chain_name_procinfo);	if (proc) proc->owner = THIS_MODULE;	IP_FW_INPUT_CHAIN = ip_init_chain(IP_FW_LABEL_INPUT, 1, FW_ACCEPT);	IP_FW_FORWARD_CHAIN = ip_init_chain(IP_FW_LABEL_FORWARD, 1, FW_ACCEPT);	IP_FW_OUTPUT_CHAIN = ip_init_chain(IP_FW_LABEL_OUTPUT, 1, FW_ACCEPT);	return ret; cleanup:	unregister_firewall(PF_INET, &ipfw_ops);	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);	while (ip_fw_chains) {		struct ip_chain *next = ip_fw_chains->next;		clear_fw_chain(ip_fw_chains);		kfree(ip_fw_chains);		ip_fw_chains = next;	}	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);	proc_net_remove(IP_FW_PROC_CHAINS);	proc_net_remove(IP_FW_PROC_CHAIN_NAMES); cleanup_netlink:#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)	sock_release(ipfwsk->socket); cleanup_nothing:#endif	return ret;}MODULE_LICENSE("BSD without advertisement clause");

⌨️ 快捷键说明

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