nat_util.c

来自「vxworks下ppp的实现源码」· C语言 代码 · 共 1,253 行 · 第 1/3 页

C
1,253
字号
	return (NULL);}/*****************************************************************************Function:	match_sa_with_static_entryDescription:Look for matching entry in the IP static table.*****************************************************************************/STATUS match_sa_with_static_entry (IP_ADDRESS source_address){	USHORT	i;	for (i = 0; i < MAXIMUM_NUMBER_OF_IP_STATIC_ENTRIES; i++)		{		if (nat.static_entries[i].local_address == source_address)			{			return (OK);	/* found */			}		}	return (ERROR);	/* not found */}	/********************************************************************************Description:	This function creates a new IP translation entry.  It is called when a match	is not found in the current IP translation list.********************************************************************************/IP_TRANSLATION_ENTRY *new_ip_translation_entry (	IP_TRANSLATION_HEADER *sptr_ip_translation_list, 	IP_ADDRESS source_address, 	bool static_entry){	IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;	ULONG index;	/* tk - for basic NAT, find the next available IP address in the global address pool */	if (nat.single_global_address_enabled == FALSE)		{		for (index = 0; index < nat.natg.global_address_pool_size; index++ )			{			if (nat.natg.global_address_pool[index].address_in_use == FALSE)				{				break;				}			}		}	else		/* tk - if NAPT, it means that no match was found in NAPT translation lists and static			entries, and no match was found either in the IP translation list.  No new IP entry			should be created in NAPT, so we return NULL here		*/		{		return (NULL);		}	if (index >= nat.natg.global_address_pool_size)		{		nat_printf (NAT_PRINTF_ERROR, "translation address table full\n"); 		return (NULL);		}	sptr_ip_translation_entry = allocate_and_initialize_ip_translation_entry (		&nat.natg.global_address_pool[index],		source_address, nat.natg.global_address_pool[index].address, 		static_entry);	dllAdd ((DL_LIST *) sptr_ip_translation_list, (DL_NODE *) sptr_ip_translation_entry);	return (sptr_ip_translation_entry);}/********************************************************************************Description:	This function creates a new static IP translation entry given the local and	global address pair.********************************************************************************/IP_TRANSLATION_ENTRY *create_static_ip_entry (	IP_TRANSLATION_HEADER *sptr_ip_translation_list, 	IP_ADDRESS source_address, 	IP_ADDRESS global_address){	IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;	ULONG index;	/* check if the specified global address is available */	for (index = 0; index < nat.natg.global_address_pool_size; index++ )		{		if (nat.natg.global_address_pool[index].address == global_address &&			nat.natg.global_address_pool[index].address_in_use == FALSE)			{			break;			}		}	if (index >= nat.natg.global_address_pool_size)		{		nat_printf (NAT_PRINTF_ERROR, "IP translation address table full\n"); 		return (NULL);		}	sptr_ip_translation_entry = allocate_and_initialize_ip_translation_entry (		&nat.natg.global_address_pool[index],		source_address, nat.natg.global_address_pool[index].address, 		TRUE);	semTake (ipListLock, WAIT_FOREVER);	dllAdd ((DL_LIST *) sptr_ip_translation_list, (DL_NODE *) sptr_ip_translation_entry);	semGive (ipListLock);	return (sptr_ip_translation_entry);}/*********************************************************************/IP_TRANSLATION_ENTRY *allocate_and_initialize_ip_translation_entry (NAT_IP_ADDRESS_ENTRY *sptr_address_entry,		IP_ADDRESS local_address, IP_ADDRESS global_address,		bool static_entry){	IP_TRANSLATION_ENTRY *sptr_ip_translation_entry;	struct 	in_addr	iaddr;	char	asciiAddr[INET_ADDR_LEN];	sptr_ip_translation_entry = (IP_TRANSLATION_ENTRY *) calloc (1, sizeof (IP_TRANSLATION_ENTRY));	if (sptr_ip_translation_entry == NULL)		{		nat_printf (NAT_PRINTF_ERROR, 			"allocate_and_initialize_ip_translation_entry: failed calloc\n");		return (NULL);		}	if (sptr_address_entry != NULL)		{		sptr_address_entry->address_in_use = TRUE;		}	sptr_ip_translation_entry->sptr_local_address_use_entry = sptr_address_entry;		sptr_ip_translation_entry->sa_local_address = local_address;	sptr_ip_translation_entry->sa_global_address = global_address;	sptr_ip_translation_entry->time_stamp = nat.ip_translation_entry_timer;	sptr_ip_translation_entry->tcp_translation_list.sptr_forward_link = NULL;	sptr_ip_translation_entry->tcp_translation_list.sptr_backward_link = NULL;	sptr_ip_translation_entry->static_entry = static_entry;	iaddr.s_addr = ntohl(global_address);	inet_ntoa_b(iaddr, asciiAddr);	arpAdd(asciiAddr, nat.etherAddr, 0x0c);	return (sptr_ip_translation_entry);			}/**********************************************************************************Function:    registerStaticEntryToTranslationListDescription:This function registers the TCP or UDP static entries in the static table to NAT'sTCP or UDP translation list and bind list.**********************************************************************************/STATUS registerStaticEntryToTranslationList (    NAT_PORT_STATIC_ENTRY    *staticEntry, 	u_short    protocol){	TCP_TRANSLATION_ENTRY *tcpTranslationEntry;	UDP_TRANSLATION_ENTRY *udpTranslationEntry;	NAT_BIND_INFO		bind_info;	NAT_STATUS			status;	memset(&bind_info,0,sizeof(bind_info));	bind_info.agent_id = 0;		/* agent is NAT */	bind_info.type = NAT_BIND_NAPT;	bind_info.direction = NAT_INBOUND;	bind_info.protocol = protocol;	bind_info.static_entry = TRUE;	bind_info.global_transport = staticEntry->global_port_number;	bind_info.local_addr = staticEntry->local_address;	bind_info.local_transport = staticEntry->local_port_number;						status = natSetBind((u_long)&nat, 0, &bind_info);	if(status != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, 			"registerStaticEntryToTranslationList: natSetBind returned %d\n",status);		return(ERROR);		}	if (protocol == IPPROTO_TCP)		{		tcpTranslationEntry = (TCP_TRANSLATION_ENTRY *) bind_info.nat_transport_entry;		tcpTranslationEntry->spoofed_local_port = bind_info.global_transport;		tcpTranslationEntry->local_address = bind_info.local_addr;		tcpTranslationEntry->local_port = bind_info.local_transport;		}	else		{		udpTranslationEntry = (UDP_TRANSLATION_ENTRY *) bind_info.nat_transport_entry;		udpTranslationEntry->spoofed_local_port = bind_info.global_transport;		udpTranslationEntry->local_address = bind_info.local_addr;		udpTranslationEntry->local_port = bind_info.local_transport;		}					return (OK);			}/*********************************************************************//* Taken directly from RFC 1631													*//*********************************************************************/void checksum_fixup (BYTE *bptr_checksum, BYTE *bptr_old_data,		USHORT old_data_length, BYTE *bptr_new_data, USHORT new_data_length){	ULONG working_checksum;	ULONG old_data_word;	ULONG new_data_word;	working_checksum = (ULONG) ((bptr_checksum[0] * 256) + bptr_checksum[1]);	working_checksum = (~working_checksum & 0x0000FFFF);		while (old_data_length > 0x0000)		{		if (old_data_length == 0x00000001)			{			old_data_word = (ULONG) ((bptr_old_data[0] * 256) + bptr_old_data[1]);			working_checksum = working_checksum - (old_data_word & 0x0000FF00);			if ((long) working_checksum <= 0x00000000L)				{				--working_checksum;				working_checksum = working_checksum & 0x0000FFFF;				}			break;			}		else			{			old_data_word = (ULONG) ((bptr_old_data[0] * 256) + bptr_old_data[1]);			bptr_old_data = bptr_old_data + 2;			working_checksum = working_checksum - (old_data_word & 0x0000FFFF);			if ((long) working_checksum <= 0x00000000L)				{				--working_checksum;				working_checksum = working_checksum & 0x0000FFFF;				}			old_data_length = (USHORT) (old_data_length - 2);			}		}	while (new_data_length > 0x0000)		{		if (new_data_length == 0x00000001)			{			new_data_word = (ULONG) ((bptr_new_data[0] * 256) + bptr_new_data[1]);			working_checksum = working_checksum + (new_data_word & 0x0000FF00);			if (working_checksum & 0x00010000)				{				++working_checksum;				working_checksum = working_checksum & 0x0000FFFF;				}			break;			}		else			{			new_data_word = (ULONG) ((bptr_new_data[0] * 256) + bptr_new_data[1]);			bptr_new_data = bptr_new_data + 2;			working_checksum = working_checksum + (new_data_word & 0x0000FFFF);			if (working_checksum & 0x00010000)				{				++working_checksum;				working_checksum = working_checksum & 0x0000FFFF;				}			new_data_length = (USHORT) (new_data_length - 2);			}		}	working_checksum = ~working_checksum;	bptr_checksum[0] = (BYTE) (working_checksum/256);	bptr_checksum[1] = (BYTE) (working_checksum & 0x000000FF);}/*********************************************************************/enum TEST increment_nat_port_spoofing_number (USHORT *usptr_spoofing_number){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	UDP_TRANSLATION_ENTRY *sptr_udp_translation_entry;	ICMP_TRANSLATION_ENTRY *sptr_icmp_translation_entry;	USHORT index;    bool conflict;	bool first_pass;	first_pass = FALSE;	for (*usptr_spoofing_number = (USHORT) (*usptr_spoofing_number + 1); 		; *usptr_spoofing_number = (USHORT) (*usptr_spoofing_number +1))		{		if (*usptr_spoofing_number > UPPER_EPHEMERAL_PORT_VALUE)			{			*usptr_spoofing_number = LOWER_EPHEMERAL_PORT_VALUE;			if (first_pass == FALSE)				{				first_pass = TRUE;				}			else				{				return (FAIL);				}			}      conflict = FALSE;		for (index = 0x0000; (index < MAXIMUM_NUMBER_OF_TCP_STATIC_ENTRIES) && !conflict; ++index)			{			if (nat.tcp_static_entries[index].global_port_number == *usptr_spoofing_number)				{            conflict = TRUE;				break;				}			}   		if (conflict == TRUE)			{			continue;			}			for (index = 0x0000; (index < MAXIMUM_NUMBER_OF_UDP_STATIC_ENTRIES) && !conflict; ++index)			{			if (nat.udp_static_entries[index].global_port_number == *usptr_spoofing_number)				{            conflict = TRUE;				break;				}			}		if (conflict == TRUE)			{			continue;			}		if (nat.single_global_address_enabled == TRUE)			{			for (sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.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->spoofed_local_port == *usptr_spoofing_number)					{					conflict = TRUE;					break;					}				}			if (conflict == TRUE)				{				continue;				}			for (sptr_udp_translation_entry = (UDP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.udp_translation_list);				sptr_udp_translation_entry != NULL;				sptr_udp_translation_entry = (UDP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_udp_translation_entry))				{				if (sptr_udp_translation_entry->spoofed_local_port == *usptr_spoofing_number)					{					conflict = TRUE;					break;					}				}			if (conflict == TRUE)				{				continue;				}			for (sptr_icmp_translation_entry = (ICMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) &nat.nats.icmp_translation_list);				sptr_icmp_translation_entry != NULL;				sptr_icmp_translation_entry = (ICMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_icmp_translation_entry))				{				if (sptr_icmp_translation_entry->spoofed_icmp_identifier == *usptr_spoofing_number)					{					conflict = TRUE;					break;					}				}			if (conflict == TRUE)				{				continue;				}			}			  		break;		}	return (PASS);}

⌨️ 快捷键说明

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