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

📄 ip_masq.c

📁 GNU Hurd 源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			case CHECKSUM_HW:				if (csum_tcpudp_magic(iph->saddr, iph->daddr, 						size, iph->protocol, skb->csum))				{					IP_MASQ_DEBUG(0, "Incoming failed %s checksum from %d.%d.%d.%d (size=%d)!\n",					       masq_proto_name(iph->protocol),					       NIPQUAD(iph->saddr),					       size);					return -1;				}			default:				/* CHECKSUM_UNNECESSARY */		}		break;	default:		return 0;	} 	IP_MASQ_DEBUG(2, "Incoming %s %08lX:%04X -> %08lX:%04X\n", 		masq_proto_name(iph->protocol), 		ntohl(iph->saddr), ntohs(h.portp[0]), 		ntohl(iph->daddr), ntohs(h.portp[1])); 	/* 	 * reroute to original host:port if found...         */        ms = ip_masq_in_get_iph(iph);	/* 	 * 	Give additional modules a chance to create an entry	 */#ifdef CONFIG_IP_MASQUERADE_MOD	if (!ms) 		ms = ip_masq_mod_in_create(skb, iph, maddr);	/* 	 * 	Call module's input update hook	 */	ip_masq_mod_in_update(skb, iph, ms);#endif        if (ms != NULL)        {                /*                 *	got reply, so clear flag                 */                ms->flags &= ~IP_MASQ_F_NO_REPLY;                		/*		 *	Set daddr,dport if not defined yet		 *	and tunnel is not setup as "dest loose"                 */		if (ms->flags & IP_MASQ_F_DLOOSE) {			/*			 *	update dest loose values			 */			ms->dport = h.portp[0];			ms->daddr = iph->saddr;		} else {                if ( ms->flags & IP_MASQ_F_NO_DPORT ) { /*  && ms->protocol == IPPROTO_TCP ) { */			write_lock(&__ip_masq_lock);			ip_masq_unhash(ms);                        ms->flags &= ~IP_MASQ_F_NO_DPORT;                        ms->dport = h.portp[0];			ip_masq_hash(ms);	/* hash on new dport */			write_unlock(&__ip_masq_lock);                        IP_MASQ_DEBUG(1, "ip_fw_demasquerade(): filled dport=%d\n",                               ntohs(ms->dport));                }                if (ms->flags & IP_MASQ_F_NO_DADDR ) { /*  && ms->protocol == IPPROTO_TCP)  { */			write_lock(&__ip_masq_lock);			ip_masq_unhash(ms);                        ms->flags &= ~IP_MASQ_F_NO_DADDR;                        ms->daddr = iph->saddr;			ip_masq_hash(ms);	/* hash on new daddr */			write_unlock(&__ip_masq_lock);                        IP_MASQ_DEBUG(1, "ip_fw_demasquerade(): filled daddr=%lX\n",                               ntohl(ms->daddr));                }		}		if ((skb=masq_skb_cow(skb_p, &iph, &h.raw)) == NULL) {			ip_masq_put(ms);			return -1;		}                iph->daddr = ms->saddr;                h.portp[1] = ms->sport;		/*		 *	Invalidate csum saving if tunnel has masq helper		 */		if (ms->app) 			csum_ok = 0;                /*                 *	Attempt ip_masq_app call.                 *	will fix ip_masq and iph ack_seq stuff                 */                if (ip_masq_app_pkt_in(ms, skb_p, maddr) != 0)                {                        /*                         *	skb has changed, update pointers.                         */                        skb = *skb_p;                        iph = skb->nh.iph;			h.raw = (char*) iph + iph->ihl*4;                        size = ntohs(iph->tot_len) - (iph->ihl * 4);                }                /*                 * Yug! adjust UDP/TCP checksums		 */		/*		 *	Transport's payload partial csum		 */		if (!csum_ok) {			csum = csum_partial(h.raw + doff, size - doff, 0);		}		skb->csum = csum;		/*		 * 	Protocol csum		 */		switch (iph->protocol) {			case IPPROTO_TCP:				h.th->check = 0;				h.th->check=csum_tcpudp_magic(iph->saddr, iph->daddr, 						size, iph->protocol, 						csum_partial(h.raw , doff, csum));				break;			case IPPROTO_UDP:				h.uh->check = 0;				h.uh->check=csum_tcpudp_magic(iph->saddr, iph->daddr, 						size, iph->protocol, 						csum_partial(h.raw , doff, csum));				if (h.uh->check == 0) 					h.uh->check = 0xFFFF;				break;		}                ip_send_check(iph);                IP_MASQ_DEBUG(2, "I-routed to %08lX:%04X\n",ntohl(iph->daddr),ntohs(h.portp[1]));		masq_set_state (ms, 0, iph, h.portp);		ip_masq_put(ms);                return 1; 	} 	/* sorry, all this trouble for a no-hit :) */ 	return 0;}void ip_masq_control_add(struct ip_masq *ms, struct ip_masq* ctl_ms){	if (ms->control) {		IP_MASQ_ERR( "request control ADD for already controlled: %d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",				NIPQUAD(ms->saddr),ntohs(ms->sport),				NIPQUAD(ms->daddr),ntohs(ms->dport));		ip_masq_control_del(ms);	}	IP_MASQ_DEBUG(1, "ADDing control for: ms.dst=%d.%d.%d.%d:%d ctl_ms.dst=%d.%d.%d.%d:%d\n",				NIPQUAD(ms->daddr),ntohs(ms->dport),				NIPQUAD(ctl_ms->daddr),ntohs(ctl_ms->dport));	ms->control = ctl_ms;	atomic_inc(&ctl_ms->n_control);}void ip_masq_control_del(struct ip_masq *ms){	struct ip_masq *ctl_ms = ms->control;	if (!ctl_ms) {		IP_MASQ_ERR( "request control DEL for uncontrolled: %d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",				NIPQUAD(ms->saddr),ntohs(ms->sport),				NIPQUAD(ms->daddr),ntohs(ms->dport));			return;	}	IP_MASQ_DEBUG(1, "DELeting control for: ms.dst=%d.%d.%d.%d:%d ctl_ms.dst=%d.%d.%d.%d:%d\n",				NIPQUAD(ms->daddr),ntohs(ms->dport),				NIPQUAD(ctl_ms->daddr),ntohs(ctl_ms->dport));	ms->control = NULL;	if (atomic_read(&ctl_ms->n_control) == 0) {		IP_MASQ_ERR( "BUG control DEL with n=0 : %d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",				NIPQUAD(ms->saddr),ntohs(ms->sport),				NIPQUAD(ms->daddr),ntohs(ms->dport));			return;			}	atomic_dec(&ctl_ms->n_control);}struct ip_masq * ip_masq_control_get(struct ip_masq *ms){	return ms->control;}#ifdef CONFIG_PROC_FS/* *	/proc/net entries *	From userspace */static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset,			      int length, int unused){	off_t pos=0, begin;	struct ip_masq *ms;	char temp[129];        int idx = 0;	int len=0;	struct list_head *l,*e;	if (offset < 128)	{		sprintf(temp,			"Prc FromIP   FPrt ToIP     TPrt Masq Init-seq  Delta PDelta Expires (free=%d,%d,%d)",			atomic_read(ip_masq_free_ports), 			atomic_read(ip_masq_free_ports+1), 			atomic_read(ip_masq_free_ports+2));		len = sprintf(buffer, "%-127s\n", temp);	}	pos = 128;        for(idx = 0; idx < IP_MASQ_TAB_SIZE; idx++) 	{	/*	 *	Lock is actually only need in next loop 	 *	we are called from uspace: must stop bh.	 */	read_lock_bh(&__ip_masq_lock);	l = &ip_masq_m_table[idx];	for (e=l->next; e!=l; e=e->next) {		ms = list_entry(e, struct ip_masq, m_list);		pos += 128;		if (pos <= offset) {			len = 0;			continue;		}		/*		 *	We have locked the tables, no need to del/add timers		 *	nor cli()  8)		 */		sprintf(temp,"%s %08X:%04X %08X:%04X %04X %08X %6d %6d %7lu",			masq_proto_name(ms->protocol),			ntohl(ms->saddr), ntohs(ms->sport),			ntohl(ms->daddr), ntohs(ms->dport),			ntohs(ms->mport),			ms->out_seq.init_seq,			ms->out_seq.delta,			ms->out_seq.previous_delta,			ms->timer.expires-jiffies);		len += sprintf(buffer+len, "%-127s\n", temp);		if(len >= length) {			read_unlock_bh(&__ip_masq_lock);			goto done;		}        }	read_unlock_bh(&__ip_masq_lock);	}done:	begin = len - (pos - offset);	*start = buffer + begin;	len -= begin;	if(len>length)		len = length;	return len;}#endif/*  *	Timeouts handling by ipfwadm/ipchains * 	From ip_fw.c */int ip_fw_masq_timeouts(void *m, int len) {	struct ip_fw_masq *masq;	int ret = EINVAL;	if (len != sizeof(struct ip_fw_masq)) {		IP_MASQ_DEBUG(1, "ip_fw_masq_timeouts: length %d, expected %d\n",				len, sizeof(struct ip_fw_masq));	} else {		masq = (struct ip_fw_masq *)m;		if (masq->tcp_timeout)			masq_timeout_table.timeout[IP_MASQ_S_ESTABLISHED]				= masq->tcp_timeout;		if (masq->tcp_fin_timeout)			masq_timeout_table.timeout[IP_MASQ_S_FIN_WAIT]				= masq->tcp_fin_timeout;		if (masq->udp_timeout)			masq_timeout_table.timeout[IP_MASQ_S_UDP]				= masq->udp_timeout;		ret = 0;	}	return ret;}/* *	Module autoloading stuff */static int ip_masq_user_check_hook(void) {#ifdef CONFIG_KMOD	if (ip_masq_user_hook == NULL) {		IP_MASQ_DEBUG(1, "About to request \"ip_masq_user\" module\n");		request_module("ip_masq_user");	}#endif /* CONFIG_KMOD */	return (ip_masq_user_hook != NULL);}/* *	user module hook- info */static int ip_masq_user_info(char *buffer, char **start, off_t offset,			      int len, int *eof, void *data){	int ret = -ENOPKG;	if (ip_masq_user_check_hook()) {		ret = ip_masq_user_hook->info(buffer, start, offset, len, (int) data);	}	return ret;}/* *	user module hook- entry mgmt */static int ip_masq_user_ctl(int optname, void *arg, int arglen){	int ret = -ENOPKG;	if (ip_masq_user_check_hook())  {		ret = ip_masq_user_hook->ctl(optname, arg, arglen);	}	return ret;}/* *	Control from ip_sockglue *	MAIN ENTRY point from userspace (apart from /proc *info entries) *	Returns errno */int ip_masq_uctl(int optname, char * optval , int optlen){	struct ip_masq_ctl masq_ctl;	int ret = -EINVAL;	if(optlen>sizeof(masq_ctl))		return -EINVAL;	if(copy_from_user(&masq_ctl,optval,optlen))		return -EFAULT;	IP_MASQ_DEBUG(1,"ip_masq_ctl(optname=%d, optlen=%d, target=%d, cmd=%d)\n",		optname, optlen, masq_ctl.m_target, masq_ctl.m_cmd);	switch (masq_ctl.m_target) {		case IP_MASQ_TARGET_USER:			ret = ip_masq_user_ctl(optname, &masq_ctl, optlen);			break;#ifdef CONFIG_IP_MASQUERADE_MOD		case IP_MASQ_TARGET_MOD:			ret = ip_masq_mod_ctl(optname, &masq_ctl, optlen);			break;#endif	}	/* 		 *	If ret>0, copy to user space 	 */	if (ret > 0 && ret <= sizeof (masq_ctl)) {		if (copy_to_user(optval, &masq_ctl, ret) )			return -EFAULT;		ret = 0;	}	return ret;}#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry	*proc_net_ip_masq = NULL;#ifdef MODULEstatic void ip_masq_proc_count(struct inode *inode, int fill){	if (fill)		MOD_INC_USE_COUNT;	else		MOD_DEC_USE_COUNT;}#endifint ip_masq_proc_register(struct proc_dir_entry *ent){	if (!proc_net_ip_masq) return -1;	IP_MASQ_DEBUG(1, "registering \"/proc/net/ip_masq/%s\" entry\n",			ent->name);	return proc_register(proc_net_ip_masq, ent);}void ip_masq_proc_unregister(struct proc_dir_entry *ent){	if (!proc_net_ip_masq) return;	IP_MASQ_DEBUG(1, "unregistering \"/proc/net/ip_masq/%s\" entry\n",			ent->name);	proc_unregister(proc_net_ip_masq, ent->low_ino);}__initfunc(static void masq_proc_init(void)){		IP_MASQ_DEBUG(1,"registering /proc/net/ip_masq\n");	if (!proc_net_ip_masq) {		struct proc_dir_entry *ent;		ent = create_proc_entry("net/ip_masq", S_IFDIR, 0);		if (ent) {#ifdef MODULE			ent->fill_inode = ip_masq_proc_count;#endif			proc_net_ip_masq = ent;		 } else {			 IP_MASQ_ERR("Could not create \"/proc/net/ip_masq\" entry\n");		 }	}}#endif	/* CONFIG_PROC_FS *//* *	Wrapper over inet_select_addr() */u32 ip_masq_select_addr(struct device *dev, u32 dst, int scope){	return inet_select_addr(dev, dst, scope);}/* *	Initialize ip masquerading */__initfunc(int ip_masq_init(void)){	int idx;        for(idx = 0; idx < IP_MASQ_TAB_SIZE; idx++)  {		INIT_LIST_HEAD(&ip_masq_s_table[idx]);		INIT_LIST_HEAD(&ip_masq_m_table[idx]);		INIT_LIST_HEAD(&ip_masq_d_table[idx]);	}#ifdef CONFIG_PROC_FS        	proc_net_register(&(struct proc_dir_entry) {		PROC_NET_IPMSQHST, 13, "ip_masquerade",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		ip_msqhst_procinfo	});	masq_proc_init();	ip_masq_proc_register(&(struct proc_dir_entry) {		0, 3, "tcp",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		NULL,	/* get_info */		NULL,	/* fill_inode */		NULL, NULL, NULL,		(char *) IPPROTO_TCP,		ip_masq_user_info	});	ip_masq_proc_register(&(struct proc_dir_entry) {		0, 3, "udp",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		NULL,	/* get_info */		NULL,	/* fill_inode */		NULL, NULL, NULL,		(char *) IPPROTO_UDP,		ip_masq_user_info	});	ip_masq_proc_registe

⌨️ 快捷键说明

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