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

📄 natftpalg.c

📁 vxworks下ppp的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (status != NAT_OK)		{		nat_printf(NAT_PRINTF_ERROR, "natFtpInit: natGetID failed with error %d\n", status);		return(status);		}	memset(&agent_info, 0, sizeof(agent_info));	agent_info.type = NAT_AGENT_TYPE_ALG;	agent_info.flags = NAT_FLAG_POST_XLAT;	agent_info.session_tag.protocol = IPPROTO_TCP;	agent_info.session_tag.transport = ftp_port;	agent_info.packet_callback = natFtpPacket;	sprintf(agent_info.desc, "%.*s", (int)(sizeof(agent_info.desc)-1), ftp_alg_desc);	sprintf(agent_info.name, "%.*s", (int)(sizeof(agent_info.name)-1), ftp_alg_name);	status = natRegisterAgent(nat_id.id, &agent_info);	if (status != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, "natFtpInit: natRegisterAgent failed with error %d\n", status);		return(status);		}	printf ("FTP ALG registered with NAT\n");	semGive(natInitSync);	return(OK);}/*****************************************************************************************Function:	ftp_get_tcp_entryDescription: 	Since the FTP ALG is in post NAT translation, by now the IP header already contains	the translated source address (we call it global address as opposed to local address).	Thus, the address translation must already exist in the NAT IP translation list.	This function calls the API function natGetAddrBind to find the translation entry	in the IP translation list, then use that entry to find the TCP entry spawned off	the IP translation (which is how TCP connection is handled internally by NAT when	it operates in basic NAT mode).  This TCP entry will be needed later by natFtpPacket	for TCP sequence adjustment.******************************************************************************************/STATUS ftp_get_tcp_entry(	ULONG	local_address,	char	*packet,	NAT_TRANSPORT *transport){	NAT_BIND_INFO  bind_info;	NAT_BIND_SESSION    session;	NAT_STATUS	status;	TCP_PACKET *sptr_tcp_packet;	sptr_tcp_packet = (TCP_PACKET *) packet;	/* sanity check to ensure that the bind descriptor for the IP translation already exists */	if ((status = natGetAddrBind((u_long)&nat, 					(u_long)local_address, 					ntohl(sptr_tcp_packet->ip_header.source_address), 					&bind_info)) != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, 			"ftp_get_tcp_entry: Status = %d, Bind of local address %x to global address %x not found\n", 			status, local_address, ntohl(sptr_tcp_packet->ip_header.source_address));		return (ERROR);		}	/* call natGetTransportBind to get the pointer to the TCP translation entry */	session.protocol = IPPROTO_TCP;	session.local_addr = local_address;	session.local_transport = ntohs(sptr_tcp_packet->tcp_header.source_port);;	session.global_addr = ntohl(sptr_tcp_packet->ip_header.source_address);	session.global_transport = ntohs(sptr_tcp_packet->tcp_header.source_port);	session.remote_addr = ntohl(sptr_tcp_packet->ip_header.destination_address);	session.remote_transport = ntohs(sptr_tcp_packet->tcp_header.destination_port);	if ((status = natGetTransportBind((u_long)&nat, &session, &bind_info, NAT_BIND_FULL)) != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, 			"ftp_get_tcp_entry: Status = %d, Transport Bind of address %x port %d not found\n",			status, ntohl(sptr_tcp_packet->ip_header.source_address),			ntohs(sptr_tcp_packet->tcp_header.source_port));		return(ERROR);		}	/* need this for TCP sequence adjustment later */	transport->tcp_block_ptr = (char *) bind_info.nat_transport_entry;	transport->global_address = bind_info.global_addr;	return (OK);}/************************************************************************************Function:	ftp_get_global_transportDescription: 	Since the FTP ALG is in post NAT translation, by now the TCP connection has been	established between FTP client and server.  The source address/port in IP/TCP	header has been translated.  This function calls natGetTransportBind to get the	TCP control block entry in the TCP translation list.  This entry will be needed	later by natFtpPacket for TCP sequence adjustment.  Furthermore, this function	creates a new TCP control block using the address/port pair from the FTP PORT or	PASV parameters by calling the API function natSetBind in preparation of the	upcoming data connection.  This must be done by the ALG in NAPT mode to get the	translated port number (i.e. global port number) so the natFtpPacket can put it 	in the FTP payload to replace the original port number for the establishment of 	the data connection.************************************************************************************/STATUS ftp_get_global_transport(	ULONG	local_address,	USHORT	local_port,	char	*packet,	NAT_TRANSPORT *transport){	NAT_BIND_INFO  bind_info;	NAT_BIND_SESSION    session;	NAT_STATUS	status;	TCP_PACKET *sptr_tcp_packet;	sptr_tcp_packet = (TCP_PACKET *) packet;	/* check to make sure the FTP control bind exists */	session.protocol = IPPROTO_TCP;	session.local_addr = local_address;	session.local_transport = local_port;	session.global_addr = ntohl(sptr_tcp_packet->ip_header.source_address);	session.global_transport = ntohs(sptr_tcp_packet->tcp_header.source_port);	session.remote_addr = ntohl(sptr_tcp_packet->ip_header.destination_address);	session.remote_transport = ntohs(sptr_tcp_packet->tcp_header.destination_port);	if ((status = natGetTransportBind((u_long)&nat, &session, &bind_info, NAT_BIND_FULL)) != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, 			"ftp_get_global_transport: Status = %d, Transport Bind of address %x port %d not found\n",			status, ntohl(sptr_tcp_packet->ip_header.source_address),			ntohs(sptr_tcp_packet->tcp_header.source_port));		return(ERROR);		}	/* need this for TCP sequence adjustment later */	transport->tcp_block_ptr = (char *) bind_info.nat_transport_entry;	/* create a new bind for FTP data connection (note that the data packet hasn't 	   been received yet) */					memset(&bind_info,0,sizeof(bind_info));	bind_info.id = 0;	/* request to create a new bind */	bind_info.agent_id = agent_info.id;	bind_info.type = NAT_BIND_NAPT;	bind_info.direction = NAT_OUTBOUND;	bind_info.protocol = IPPROTO_TCP;	bind_info.static_entry = FALSE;	bind_info.local_addr = (u_long)local_address;	bind_info.local_transport = local_port;	bind_info.global_addr = ntohl(sptr_tcp_packet->ip_header.source_address);	bind_info.global_transport = 0;	bind_info.remote_addr = ntohl(sptr_tcp_packet->ip_header.destination_address);	bind_info.remote_transport = 0;	/* destination port is still unknown here */	status = natSetBind((u_long)&nat, agent_info.id, &bind_info);	if(status != NAT_OK)		{		nat_printf (NAT_PRINTF_ERROR, "ftp_get_global_transport: natSetBind returned %d\n",status);		return (ERROR);		}	transport->global_address = bind_info.global_addr;	transport->global_port = bind_info.global_transport;	return (OK);}/************************************************************************************Function:	adjust_tcp_sequenceDescription: 	Adjust TCP sequence number and recompute the TCP checksum.************************************************************************************/STATUS adjust_tcp_sequence (	char	*tcp_packet,	char	*old_string,	char	*new_string,	ULONG	old_string_length,	ULONG	new_string_length,	char	*tcp_entry	){	TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry;	TCP_PACKET *sptr_tcp_packet;	int		sequence_number_delta;	ULONG	end_of_packet_length;	ULONG	data_length;	USHORT 	total_length;	USHORT	tcp_length, new_tcp_length;	char	*end_old_string;	char	*end_of_tcp_header;	long	result;	SEQUENCE_ENTRY *sptr_sequence_entry = NULL;	SEQUENCE_ENTRY *sptr_old_sequence_entry = NULL;	BYTE *bptr_end_of_packet_buffer = NULL;	sptr_tcp_packet = (TCP_PACKET *) tcp_packet;	sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) tcp_entry;	/* find the start of TCP payload */	end_of_tcp_header = (char *) (&sptr_tcp_packet->tcp_header);	end_of_tcp_header += (sptr_tcp_packet->tcp_header.header_length_byte.header_length << 2);	end_old_string = (char *)(old_string + old_string_length);		end_of_packet_length = 0x00000000L;	tcp_length = (USHORT) (sptr_tcp_packet->ip_header.total_length - 				(sptr_tcp_packet->ip_header.version_header_length.header_length << 2));	data_length = (ULONG) (sptr_tcp_packet->ip_header.total_length - 				(sptr_tcp_packet->ip_header.version_header_length.header_length << 2) - 				(sptr_tcp_packet->tcp_header.header_length_byte.header_length << 2));	sequence_number_delta = (int) (new_string_length - old_string_length);	if (sequence_number_delta != 0x0000)		{		end_of_packet_length = (ULONG) (data_length - (end_old_string - end_of_tcp_header)); 		if (end_of_packet_length != 0x00000000L)			{			bptr_end_of_packet_buffer = (BYTE *) malloc (end_of_packet_length);			if (bptr_end_of_packet_buffer == NULL)			    return (ERROR);			}		if (sptr_sequence_entry == NULL)			{			sptr_sequence_entry = (SEQUENCE_ENTRY *) calloc (1, sizeof (SEQUENCE_ENTRY));			if (sptr_sequence_entry == NULL)				{				if (bptr_end_of_packet_buffer != NULL)					{					free (bptr_end_of_packet_buffer);					}					return (ERROR);				}			sptr_sequence_entry->link.sptr_forward_link = NULL;			sptr_sequence_entry->link.sptr_backward_link = NULL;			sptr_sequence_entry->sequence_number_base_adjust = 0x00000000L;			sptr_sequence_entry->sequence_number_base = ntohl (sptr_tcp_packet->tcp_header.sequence_number);			sptr_sequence_entry->sequence_number_delta = sequence_number_delta;			}		else			{			sptr_sequence_entry->sequence_number_delta = sptr_sequence_entry->sequence_number_delta + sequence_number_delta;			}		total_length = (USHORT) (sptr_tcp_packet->ip_header.total_length + sequence_number_delta);		sptr_tcp_packet->ip_header.total_length = total_length;	/* host order */		if (end_of_packet_length != 0x00000000L)			{			memcpy (bptr_end_of_packet_buffer, end_old_string, end_of_packet_length);			}		}	checksum_fixup ((BYTE *) &sptr_tcp_packet->tcp_header.checksum,				(BYTE *) old_string, (USHORT) old_string_length,				(BYTE *) new_string, (USHORT) new_string_length);				memcpy (old_string, new_string, new_string_length);	if (sequence_number_delta != 0x0000)		{		end_old_string = old_string + new_string_length;		if (end_of_packet_length != 0x00000000L)			{			memcpy (end_old_string, bptr_end_of_packet_buffer, end_of_packet_length);			free (bptr_end_of_packet_buffer);			}		}	new_tcp_length = (USHORT) (tcp_length + sequence_number_delta);	new_tcp_length = htons (new_tcp_length);	tcp_length = htons (tcp_length);	checksum_fixup ((BYTE *) &sptr_tcp_packet->tcp_header.checksum,					(BYTE *) &tcp_length, sizeof (USHORT),					(BYTE *) &new_tcp_length, sizeof (USHORT));		sptr_old_sequence_entry = NULL;	if (sptr_sequence_entry != NULL)		{		sptr_sequence_entry->timer_enabled = FALSE;		sptr_sequence_entry->entry_timer = nat.sequence_entry_timer;		sptr_old_sequence_entry = (SEQUENCE_ENTRY *) DLL_FIRST (					(DL_LIST *) &sptr_tcp_translation_entry->local_sequence_delta_list);		if (sptr_old_sequence_entry != NULL)			{			result = sptr_sequence_entry->sequence_number_base - sptr_old_sequence_entry->sequence_number_base;			if (result > 0x00000000L)				{				sptr_sequence_entry->sequence_number_base_adjust = sptr_old_sequence_entry->sequence_number_delta +							sptr_old_sequence_entry->sequence_number_base_adjust;				sptr_old_sequence_entry->timer_enabled = TRUE;				}			else				{				free (sptr_sequence_entry);				sptr_sequence_entry = NULL;				}			}		if (sptr_sequence_entry != NULL)			{			dllInsert ((DL_LIST *) &sptr_tcp_translation_entry->local_sequence_delta_list, NULL, (DL_NODE *) sptr_sequence_entry);			}		}	return(OK);}

⌨️ 快捷键说明

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