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

📄 ip_masq_mfw.c

📁 GNU Hurd 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				h = list_entry(e, struct ip_masq_mfw_host, list);				pos += 64;				if (pos <= offset) {					len = 0;					continue;				}				sprintf(temp,"0x%x > %08lX %5u %5d %5d",						h->fwmark,						ntohl(h->addr), ntohs(h->port),						atomic_read(&h->pref_cnt), h->pref);				len += sprintf(buffer+len, "%-63s\n", temp);				if(len >= length) {					read_unlock_bh(&mfw->lock);					read_unlock(&mfw_lock);					goto done;				}			}			read_unlock_bh(&mfw->lock);		}		read_unlock(&mfw_lock);	}done:	if (len) {		begin = len - (pos - offset);		*start = buffer + begin;		len -= begin;	}	if(len>length)		len = length;	MOD_DEC_USE_COUNT;	return len;}static struct proc_dir_entry mfw_proc_entry = {/* 		0, 0, NULL", */		0, 3, "mfw",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		mfw_procinfo};#define proc_ent &mfw_proc_entry#else /* !CONFIG_PROC_FS */#define proc_ent NULL#endifstatic void mfw_flush(void){	struct ip_masq_mfw *mfw, *local_table[IP_MASQ_MFW_HSIZE];	struct ip_masq_mfw_host *h;	struct ip_masq_mfw *mfw_next;	int idx;	struct list_head *l,*e;	write_lock_bh(&mfw_lock);	memcpy(local_table, ip_masq_mfw_table, sizeof ip_masq_mfw_table);	memset(ip_masq_mfw_table, 0, sizeof ip_masq_mfw_table);	write_unlock_bh(&mfw_lock);	/*	 *	For every hash table row ...	 */	for(idx=0;idx<IP_MASQ_MFW_HSIZE;idx++) {		/*		 *	For every m-entry in row ...		 */		for(mfw=local_table[idx];mfw;mfw=mfw_next) {			/*			 *	For every m.host in m-entry ...			 */			l=&mfw->hosts;			while((e=l->next) != l) {				h = list_entry(e, struct ip_masq_mfw_host, list);				atomic_dec(&mfw->nhosts);				list_del(&h->list);				kfree_s(h, sizeof(*h));				MOD_DEC_USE_COUNT;			}			if (atomic_read(&mfw->nhosts)) {				IP_MASQ_ERR("mfw_flush(): after flushing row nhosts=%d\n",						atomic_read(&mfw->nhosts));			}			mfw_next = mfw->next;			kfree_s(mfw, sizeof(*mfw));				MOD_DEC_USE_COUNT;			ip_masq_mod_dec_nent(mmod_self);		}	}}/* *	User space control entry point */static int mfw_ctl(int optname, struct ip_masq_ctl *mctl, int optlen){        struct ip_mfw_user *mu =  &mctl->u.mfw_user;	struct ip_masq_mfw *mfw;	int ret = EINVAL;	int arglen = optlen - IP_MASQ_CTL_BSIZE;	int cmd;	IP_MASQ_DEBUG(1-debug, "ip_masq_user_ctl(len=%d/%d|%d/%d)\n",		arglen,		sizeof (*mu),		optlen,		sizeof (*mctl));	/*	 *	checks ...	 */	if (arglen != sizeof(*mu) && optlen != sizeof(*mctl)) 		return -EINVAL; 	/* 	 *	Don't trust the lusers - plenty of error checking! 	 */	cmd = mctl->m_cmd;	IP_MASQ_DEBUG(1-debug, "ip_masq_mfw_ctl(cmd=%d, fwmark=%d)\n",			cmd, mu->fwmark);	switch(cmd) {		case IP_MASQ_CMD_NONE:			return 0;		case IP_MASQ_CMD_FLUSH:			break;		case IP_MASQ_CMD_ADD:		case IP_MASQ_CMD_INSERT:		case IP_MASQ_CMD_SET:			if (mu->fwmark == 0) {				IP_MASQ_DEBUG(1-debug, "invalid fwmark==0\n");				return -EINVAL;			}			if (mu->pref < 0) {				IP_MASQ_DEBUG(1-debug, "invalid pref==%d\n",					mu->pref);				return -EINVAL;			}			break;	}	ret = -EINVAL;	switch(cmd) {	case IP_MASQ_CMD_ADD:	case IP_MASQ_CMD_INSERT:		if (!mu->raddr) {			IP_MASQ_DEBUG(0-debug, "ip_masq_mfw_ctl(ADD): invalid redirect 0x%x:%d\n",					mu->raddr, mu->rport);			goto out;		}		/*		 *	Cannot just use mfw_lock because below		 *	are allocations that can sleep; so		 *	to assure "new entry" atomic creation		 *	I use a semaphore.		 *		 */		down(&mfw_sema);		read_lock(&mfw_lock);		mfw = __mfw_get(mu->fwmark);		read_unlock(&mfw_lock);				/*		 *	If first host, create m-entry		 */		if (mfw == NULL) {			mfw = mfw_new(mu->fwmark);			if (mfw == NULL) 				ret = -ENOMEM;		} 		if (mfw) {			/*			 *	Put m.host in m-entry.			 */			ret = mfw_addhost(mfw, mu, cmd == IP_MASQ_CMD_ADD);			/*			 *	If first host, link m-entry to hash table.			 *	Already protected by global lock.			 */			if (ret == 0 && atomic_read(&mfw->nhosts) == 1)  {				write_lock_bh(&mfw_lock);				__mfw_add(mfw);				write_unlock_bh(&mfw_lock);			} 			if (atomic_read(&mfw->nhosts) == 0) {				mfw_destroy(mfw);			}		}		up(&mfw_sema);		break;	case IP_MASQ_CMD_DEL:		down(&mfw_sema);		read_lock(&mfw_lock);		mfw = __mfw_get(mu->fwmark);		read_unlock(&mfw_lock);		if (mfw) {			ret = mfw_delhost(mfw, mu);			/*			 *	Last lease will free			 *	XXX check logic XXX			 */			if (atomic_read(&mfw->nhosts) == 0) {				write_lock_bh(&mfw_lock);				__mfw_del(mfw);				write_unlock_bh(&mfw_lock);				mfw_destroy(mfw);			}		} else 			ret = -ESRCH;		up(&mfw_sema);		break;	case IP_MASQ_CMD_FLUSH:		down(&mfw_sema);		mfw_flush();		up(&mfw_sema);		ret = 0;		break;	case IP_MASQ_CMD_SET:		/*		 *	No need to semaphorize here, main list is not 		 *	modified.		 */		read_lock(&mfw_lock);				mfw = __mfw_get(mu->fwmark);		if (mfw) {			write_lock_bh(&mfw->lock);						if (mu->flags & IP_MASQ_MFW_SCHED) {				struct ip_masq_mfw_host *h;				if ((h=__mfw_sched(mfw, 1))) {					mfw_host_to_user(h, mu);					ret = 0;				} 			} else {				ret = __mfw_edithost(mfw, mu);			}							write_unlock_bh(&mfw->lock);		}		read_unlock(&mfw_lock);		break;	}out:		return ret;}/* *	Module stubs called from ip_masq core module */ /* *	Input rule stub, called very early for each incoming packet,  *	to see if this module has "interest" in packet. */static int mfw_in_rule(const struct sk_buff *skb, const struct iphdr *iph){	int val;	read_lock(&mfw_lock);	val = ( __mfw_get(skb->fwmark) != 0);	read_unlock(&mfw_lock);	return val;}/* *	Input-create stub, called to allow "custom" masq creation */static struct ip_masq * mfw_in_create(const struct sk_buff *skb, const struct iphdr *iph, __u32 maddr){	union ip_masq_tphdr tph;	struct ip_masq *ms = NULL;	struct ip_masq_mfw_host *h = NULL;	tph.raw = (char*) iph + iph->ihl * 4;	switch (iph->protocol) {		case IPPROTO_TCP:			/* 				 *	Only open TCP tunnel if SYN+!ACK packet			 */			if (!tph.th->syn || tph.th->ack)				return NULL;		case IPPROTO_UDP:			break;		default:			return NULL;	}	/* 	 *	If no entry exists in the masquerading table 	 * 	and the port is involved	 *  	in port forwarding, create a new masq entry 	 */	if ((h=mfw_lookup(skb->fwmark))) {		ms = ip_masq_new(iph->protocol,				iph->daddr, tph.portp[1],					/* if no redir-port, use packet dest port */				h->addr, h->port? h->port : tph.portp[1],				iph->saddr, tph.portp[0],				0);		if (ms != NULL)			ip_masq_listen(ms);	}	return ms;}#define mfw_in_update	NULL#define mfw_out_rule	NULL#define mfw_out_create	NULL#define mfw_out_update	NULLstatic struct ip_masq_mod mfw_mod = {	NULL,			/* next */	NULL,			/* next_reg */	"mfw",		/* name */	ATOMIC_INIT(0),		/* nent */	ATOMIC_INIT(0),		/* refcnt */	proc_ent,	mfw_ctl,	NULL,			/* masq_mod_init */	NULL,			/* masq_mod_done */	mfw_in_rule,	mfw_in_update,	mfw_in_create,	mfw_out_rule,	mfw_out_update,	mfw_out_create,};__initfunc(int ip_mfw_init(void)){	return register_ip_masq_mod ((mmod_self=&mfw_mod));}int ip_mfw_done(void){	return unregister_ip_masq_mod(&mfw_mod);}#ifdef MODULEEXPORT_NO_SYMBOLS;int init_module(void){	if (ip_mfw_init() != 0)		return -EIO;	return 0;}void cleanup_module(void){	if (ip_mfw_done() != 0)		printk(KERN_INFO "can't remove module");}#endif /* MODULE */

⌨️ 快捷键说明

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