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

📄 nat_util.c

📁 vxworks下ppp的实现源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* nat_util.c *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01c,24apr03,zhu  updated copyright01b,21apr03,myz  replaced swap(_long) with the ntohs(l) macros,                 replaced RWOS list functions with ones in dllLib.c.01a,15apr03,zhu  fix for deleting static port mapping040903  vks     updated Copyright info040303  vks     replaced table_malloc with calloc110802  zhu     fixed a bug for basic NAT tcp translation entry comparison092302  vvv     unconditionally include fix for SPR #65740120601	tk		Fix SPR72007: Inbound session to non-standard port failed.112601	tk		Fix SPR65740: ARP problem with Basic-NAT.101901  tk		Fix data type to avoid warning in T3 compiler.100301  tk      Provide semaphore locks on match functions to access respective.				translation lists to prevent race condition with the NAT Timer task.				Add match_sa_with_static_entry() function to match address in				IP static entry table.092401	tk		Fix bug.  Changed match_spoofed_port_with_tcp_entry() and 				match_spoofed_port_with_udp_entry() to return entry pointer found				only for static entry created by ALG or dynamic entry created by				session started outbound..  082301	tk		Add registerStaticEntryToTranslationList() to enter static TCP/UDP				entry to translation list and bind list.080701	tk		Add match_ports_with_udp_entry_global() and 				match_ports_with_tcp_entry_global() for H.323 handling.072601	tk		Fix bug. Remove match_ports_with_tcp_entry() and create 2 functions:					match_ports_with_tcp_entry_inbound() and 					match_ports_with_tcp_entry_outbound() 				to look for matching TCP entry for inbound and outbound TCP packet.				Similarly, Remove match_ports_with_udp_entry() and create 2 functions:					match_ports_with_udp_entry_inbound() and 					match_ports_with_udp_entry_outbound() 				to look for matching UDP entry for inbound and outbound UDP packet.071001	tk		Create a new function create_static_ip_entry() for creating a new				static IP entry in the IP translation list.060401	tk		Fix the logic in new_ip_translation_entry if called in NAPT mode.				No new IP entry should be created in NAPT mode, so just return NULL.				Fix in match_sa_with_global_address() to return NULL if static entry				match found but the static entry is disabled.  This fixes SPR#67129:				Disabling static entry doesn't disable IP static mapping immediately.050701	tk		Update nat_packet_discriminator to handle ICMP time_exceeded message				as a datagram rather than a transaction.042101	tk		Update nat_packet_discriminator to handle ICMP redirect message as				a unique type as NAT should not translate it per RFC# 1631. *//*#define CS_DEBUG*/#include <string.h>#include <stdio.h>#include "nat.h"#include <arpLib.h>/************************************************************************************/enum NAT_PORT_TYPE get_nat_port_type (USHORT port_number){	enum NAT_PORT_TYPE nat_port_type;	if (nat.port[port_number].type == NAT_GLOBAL_PORT)		{		nat_port_type = NAT_GLOBAL_PORT;		}	else		{		nat_port_type = NAT_LOCAL_PORT;		}	return (nat_port_type);}/*****************************************************************************************Function:	match_sa_with_global_addressDescription:This function looks for a global address match in the IP translation list.*****************************************************************************************/IP_TRANSLATION_ENTRY *match_sa_with_global_address (IP_ADDRESS global_address, 								IP_TRANSLATION_HEADER *sptr_ip_translation_list){	IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;	semTake(ipListLock, WAIT_FOREVER);	for (sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_ip_translation_list);		sptr_ip_translation_entry != NULL;		sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_ip_translation_entry))		{		if (global_address == sptr_ip_translation_entry->sa_global_address)			{			if (sptr_ip_translation_entry->static_entry == true &&				nat.static_entries_enabled == false)				{				nat_printf (NAT_PRINTF_DATA, 					"matched_sa_with_global_address: static address 0x%lx disabled\n",					global_address);				semGive (ipListLock);				return (NULL);				}			nat_printf (NAT_PRINTF_TRACE, 				"Found match for global address %x in IP list\n", global_address);			semGive (ipListLock);			return (sptr_ip_translation_entry);			}		}	nat_printf (NAT_PRINTF_TRACE, 		"No match for global address %x in IP list\n", global_address);	semGive (ipListLock);	return (NULL);}/*****************************************************************************************Function:Description:This function looks for a local address match in the IP translation list.*****************************************************************************************/IP_TRANSLATION_ENTRY *match_sa_with_local_address (IP_ADDRESS source_address, 												   IP_TRANSLATION_HEADER *sptr_ip_translation_list){	IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;	semTake(ipListLock, WAIT_FOREVER);	for (sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_ip_translation_list);		sptr_ip_translation_entry != NULL;		sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_ip_translation_entry))		{		if (source_address == sptr_ip_translation_entry->sa_local_address)			{			nat_printf (NAT_PRINTF_TRACE, 				"Found match for local address %x in IP list\n", source_address);			semGive (ipListLock);						return (sptr_ip_translation_entry);			}		}	nat_printf (NAT_PRINTF_TRACE, 		"No match for local address %x in IP list\n", source_address);	semGive (ipListLock);	return (NULL);}/************************************************************************/ULONG_ENUM (NAT_PACKET_TYPES) nat_packet_discriminator (IP_PACKET *sptr_ip_packet){	ICMP_PACKET *sptr_icmp_packet;	UDP_PACKET *sptr_udp_packet;	switch (sptr_ip_packet->header.protocol)		{		case ICMP_PROTOCOL:			sptr_icmp_packet = (ICMP_PACKET *) sptr_ip_packet;			if ((sptr_icmp_packet->header.type == ICMP_ECHO_REPLY_TYPE) ||				(sptr_icmp_packet->header.type == ICMP_ECHO_REQUEST_TYPE) ||				(sptr_icmp_packet->header.type == ICMP_TIMESTAMP_TYPE) ||				(sptr_icmp_packet->header.type == ICMP_TIMESTAMP_REPLY_TYPE) ||				(sptr_icmp_packet->header.type == ICMP_ADDRESS_MASK_TYPE) ||				(sptr_icmp_packet->header.type == ICMP_ADDR_MASK_REPLY_TYPE))				{				return (NAT_ICMP_TRANSACTION);				}			else	/* tk - per RFC 1631: NAT doesn't handle ICMP Redirect message */			if (sptr_icmp_packet->header.type == ICMP_REDIRECT_TYPE)				{				return (NAT_ICMP_REDIRECT);				}			else				{								return (NAT_ICMP_DATAGRAM);				}									case TCP_PROTOCOL:			return (NAT_TCP);		case UDP_PROTOCOL:			sptr_udp_packet = (UDP_PACKET *) sptr_ip_packet;						if (ntohs (sptr_udp_packet->header.destination_port) == RIP_PORT)				{				return (NAT_RIP);				}			return (NAT_UDP);		case OSPF_PROTOCOL:			return (NAT_OSPF);		default:			return (NAT_UNKNOWN_PROTOCOL);		}}/*****************************************************************************Function:	match_ports_with_tcp_entry_outboundDescription:Look for TCP entry with matching local address, local port, and remote port.This check is made for outbound packets.*****************************************************************************/TCP_TRANSLATION_ENTRY *match_ports_with_tcp_entry_outbound (	USHORT remote_port, 	USHORT local_port, 	IP_ADDRESS local_address, 	TCP_TRANSLATION_HEADER *sptr_tcp_translation_list){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	semTake (tcpListLock, WAIT_FOREVER);	for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_FIRST ((DL_LIST *) sptr_tcp_translation_list);		sptr_tcp_translation_entry != NULL;		sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_NEXT ((DL_NODE *) sptr_tcp_translation_entry))		{			if ((sptr_tcp_translation_entry->local_port == local_port) &&				(sptr_tcp_translation_entry->remote_port == remote_port) &&				(sptr_tcp_translation_entry->local_address == local_address))				{				nat_printf (NAT_PRINTF_TRACE, 					"Found match for local_addr/port = %08lx:%d, remote port = %d in TCP list\n",					local_address, local_port, remote_port);				semGive (tcpListLock);				return (sptr_tcp_translation_entry);				}						}	semGive (tcpListLock);	nat_printf (NAT_PRINTF_TRACE, 		"No match for local_addr/port = %08lx:%d, remote port=%d in TCP list\n",		local_address, local_port, remote_port);	return (NULL);}/*****************************************************************************Function:	match_ports_with_tcp_entry_inboundDescription:Look for TCP entry with matching local port, remote address and remote port.This check is made for inbound packets.*****************************************************************************/TCP_TRANSLATION_ENTRY *match_ports_with_tcp_entry_inbound (	USHORT remote_port, 	USHORT global_port, 	IP_ADDRESS remote_address, 	TCP_TRANSLATION_HEADER *sptr_tcp_translation_list){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	semTake (tcpListLock, WAIT_FOREVER);	for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_FIRST ((DL_LIST *) sptr_tcp_translation_list);		sptr_tcp_translation_entry != NULL;		sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_NEXT ((DL_NODE *) sptr_tcp_translation_entry))		{                if (nat.single_global_address_enabled == FALSE)		    {			if ((sptr_tcp_translation_entry->local_port == global_port) &&			(sptr_tcp_translation_entry->remote_port == remote_port) &&				(sptr_tcp_translation_entry->remote_address == remote_address))				{				nat_printf (NAT_PRINTF_TRACE, 					"Found match for remote addr/port = %08lx:%d, global port=%d in TCP list\n",					remote_address, remote_port, global_port);				semGive (tcpListLock);				return (sptr_tcp_translation_entry);				}		    }		    else		    {			if ((sptr_tcp_translation_entry->spoofed_local_port == global_port) &&				(sptr_tcp_translation_entry->remote_port == remote_port) &&				(sptr_tcp_translation_entry->remote_address == remote_address))				{				nat_printf (NAT_PRINTF_TRACE, 					"Found match for remote addr/port = %08lx:%d, global port=%d in TCP list\n",					remote_address, remote_port, global_port);				semGive (tcpListLock);				return (sptr_tcp_translation_entry);				}						    }		}	semGive (tcpListLock);	nat_printf (NAT_PRINTF_TRACE, 		"No match for remote addr/port = %08lx:%d, global port=%d in TCP list\n",		remote_address, remote_port, global_port);	return (NULL);}/*****************************************************************************Function:	match_ports_with_tcp_entry_globalDescription:Look for TCP entry with matching local address, local port, and global portthat has the same value as its local port.  This matching routine may berequired by some protocols (e.g. H.323).This check is made for outbound packets.*****************************************************************************/TCP_TRANSLATION_ENTRY *match_ports_with_tcp_entry_global (	USHORT local_port, 	IP_ADDRESS local_address, 	TCP_TRANSLATION_HEADER *sptr_tcp_translation_list){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	semTake (tcpListLock, WAIT_FOREVER);	for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 		DLL_FIRST ((DL_LIST *) sptr_tcp_translation_list);		sptr_tcp_translation_entry != NULL;		sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_NEXT ((DL_NODE *) sptr_tcp_translation_entry))		{			if ((sptr_tcp_translation_entry->local_port == local_port) &&				(sptr_tcp_translation_entry->spoofed_local_port == local_port) &&				(sptr_tcp_translation_entry->local_address == local_address))				{				nat_printf (NAT_PRINTF_TRACE, 					"Found match for local address/port = %08lx:%d, global port=%d in TCP list\n",					local_address, local_port, local_port);				semGive (tcpListLock);				return (sptr_tcp_translation_entry);				}						}	nat_printf (NAT_PRINTF_TRACE, 		"No match for local address/port = %08lx:%d, global port=%d in TCP list\n",		local_address, local_port, local_port);	semGive (tcpListLock);	return (NULL);}/*****************************************************************************Function:	match_spoofed_port_with_tcp_entryDescription:Look for TCP entry with matching spoofed port.  There can be up to four typesof TCP entries in the TCP translation list:1. Dummy static entries created from static table.2. Real static entries created by external agent (e.g. ALG)3. Dynamic entries created from a static entry.  In this case, the spoofed   port may not be unique.4. Dynamic entries created by outbound session.  Here, the spoofed port is   unique.Return the entry pointer only if either the matching spoofed port belongs toan entry of type 2 or 4 mentioned above.*****************************************************************************/TCP_TRANSLATION_ENTRY *match_spoofed_port_with_tcp_entry (	USHORT spoofed_port,	TCP_TRANSLATION_HEADER *sptr_tcp_translation_list,	BOOL findDummyStatic){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	NAT_BIND_INFO    *bind_id;	semTake (tcpListLock, WAIT_FOREVER);	for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 		DLL_FIRST ((DL_LIST *) sptr_tcp_translation_list);		sptr_tcp_translation_entry != NULL;		sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) 			DLL_NEXT ((DL_NODE *) sptr_tcp_translation_entry))		{		/* If looking for dummy static entry (to delete), skip dynamic entries. */		if(findDummyStatic && (sptr_tcp_translation_entry->static_entry == FALSE) )			continue;		if (sptr_tcp_translation_entry->spoofed_local_port == spoofed_port)			{			nat_printf (NAT_PRINTF_TRACE, 				"Found match for spoofed port %d in TCP list\n", spoofed_port);			if (sptr_tcp_translation_entry->static_entry == TRUE)				{				bind_id = (NAT_BIND_INFO *) sptr_tcp_translation_entry->bind_id;				if (bind_id->agent_id == 0)					{

⌨️ 快捷键说明

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