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

📄 natftpalg.c

📁 vxworks下ppp的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* natFtpAlg.c *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//* WindNet NAT "installable" FTP Application Level Gateway (ALG) *//*modification history--------------------01b,24apr03,zhu  updated copyright01a,21apr03,myz replaced swap(_long) with the ntohs(l) and htons(l) macros,                replaced RWOS list functions with ones in dllLib.c040903  vks updated Copyright info040303  vks replaced table_malloc and table_free with calloc and free respectively092002  vvv fixed Diab warning102201  tk  Fix code to find start of FTP payload to take into account the            option field in the IP header.092101  tk  Modify due to changes in the natGetTransportBind() format.  Problem			found due to NAT changes to work with mib.  Also, bug fixes for			multiple FTP clients session with local FTP server.071301	tk	Redo entire implementation of ALG to use the upgraded version of NAT			ALG API to interact with NAT.  The new implementation is based on the			assumption that the IP/TCP headers have been translated by NAT (i.e.			post NAT translation).  The TCP sequence adjustment code is now			modularized in a separate subroutine.060701	tk	Fix Linux FTP problem.  Linux FTP uses the options field in the TCP			header while the code always assumed the TCP header was always 20			bytes long (SPR#67124).051501	tk	Fix handling of reply to PASV command (SPR#67123).030901	tk	Fix synchronization problem with NAT initialization.*//*#define		FTP_DEBUG*//* ANSI headers */#include <stdio.h>			/* printf */#include <string.h>			/* memset *//* VxWorks headers */#include <in.h>				/* IPPROTO_TCP *//* NAT-specific headers */#include <nat/natAlgApi.h>#include "nat.h"			/* IP_ADDRESS */#include "natFtpAlg.h"static const char* ftp_alg_desc 	= "WindNet NAT - FTP ALG v1.0 - Copyright 2000-2003 Wind River Systems, Inc.";static const char* ftp_alg_name = "FTP ALG";static	NAT_ID_INFO		nat_id;static	NAT_AGENT_INFO	agent_info;/*****************************************************************************************Function:	natFtpPacketDescription: 	******************************************************************************************/BOOL natFtpPacket(u_long nat_id, u_long agent_id, u_long session_id, 	NAT_DIRECTION direction, void* packet){	USHORT local_port_number;	USHORT global_port_number;	char *cptr_port_string;	char *cptr_end_port_string;	char *end_of_tcp_header;		USHORT tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;	IP_ADDRESS local_address;	IP_ADDRESS global_address;	BYTE *bptr_local_address;	BYTE *bptr_global_address;	char port_string[FTP_MAXIMUM_PORT_STRING_LENGTH];	/* also for PASV string */	ULONG new_port_string_length;	ULONG old_port_string_length;		TCP_TRANSLATION_ENTRY *sptr_tcp_translation_entry = NULL;	int dummy_value;	TCP_PACKET *sptr_tcp_packet;	NAT_TRANSPORT transport;	TCP_HEADER *tcp_start;	if (direction != NAT_OUTBOUND)		{		return(TRUE);		}	sptr_tcp_packet = (TCP_PACKET*)packet;	memset(&transport, 0, sizeof(NAT_TRANSPORT));	/* need to look for the port or pasv command.  Then have to look for the IP address and	   the port address.  Then must create a TCP control block and spoof the port	   number, and change the ip address, and do the sequence number setting.	*/	/* find the start of TCP payload */	cptr_port_string = (char *) (&sptr_tcp_packet->ip_header);	cptr_port_string += (sptr_tcp_packet->ip_header.version_header_length.header_length << 2);	tcp_start = (TCP_HEADER *) cptr_port_string;	cptr_port_string += (tcp_start->header_length_byte.header_length << 2);	end_of_tcp_header = cptr_port_string; 	/***************************************************/	/* PASV Section (for FTP servers "behind" the NAT) */	/***************************************************/	if (sscanf (cptr_port_string, FTP_PASV_PARAMETER_STRING, &dummy_value, &tmp1, &tmp2, &tmp3, &tmp4, &tmp5, &tmp6) == 		FTP_PASV_PARAMETER_COUNT)		{		nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP Reply for PASV command\n");		sprintf (port_string, FTP_PASV_PARAMETER_STRING, FTP_PASV_RETURN_CODE, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);		nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP old PASV string: %s\n", port_string);		cptr_end_port_string = strchr (cptr_port_string, FTP_PASV_STRING_END_MARKER);		if (cptr_end_port_string == NULL)			{			return(TRUE);	/* incomplete PASV command, disregard */			}		++cptr_end_port_string;		old_port_string_length = (ULONG) (cptr_end_port_string - cptr_port_string);		/* tk:  The global (remote) port is still unknown now, so just set it to 0.		   The remote port will be set to the right port number when the data connection 		   is initiated by the local FTP client.		*/		global_port_number = 0x0000;		local_port_number = (USHORT) (tmp5 * 0x100 + tmp6);		bptr_local_address = (BYTE *) &local_address;					bptr_local_address[3] = (BYTE) (tmp4 & 0x00FF);		bptr_local_address[2] = (BYTE) (tmp3 & 0x00FF);		bptr_local_address[1] = (BYTE) (tmp2 & 0x00FF);		bptr_local_address[0] = (BYTE) (tmp1 & 0x00FF);		local_address = ntohl (local_address);		nat_printf (NAT_PRINTF_DATA, "FTP ALG: FTP PASV IP address: %x\n", local_address);		if (nat.single_global_address_enabled == false)				{	/* basic NAT */				if (ftp_get_tcp_entry((ULONG)local_address, (char *) sptr_tcp_packet,						&transport) != OK)					{					nat_printf(NAT_PRINTF_ERROR, "natFtpPacket: ftp_get_tcp_entry returns ERROR\n");					return (FALSE);					}				sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) transport.tcp_block_ptr;				}			else				{	/* NAPT */				if (ftp_get_global_transport(local_address, local_port_number,					(char *) sptr_tcp_packet, &transport) != OK)					{					nat_printf(NAT_PRINTF_ERROR, "natFtpPacket: ftp_get_tcp_entry returns ERROR\n");					return (FALSE);					}				sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) transport.tcp_block_ptr;				local_port_number = transport.global_port;				tmp5 = (USHORT) (local_port_number/0x100);				tmp6 = (USHORT) (local_port_number % 0x100);				}					global_address = transport.global_address;		global_address = htonl (global_address);						bptr_global_address = (BYTE *) &global_address;		tmp4 = bptr_global_address[3];		tmp3 = bptr_global_address[2];		tmp2 = bptr_global_address[1];		tmp1 = bptr_global_address[0];		sprintf (port_string, FTP_PASV_PARAMETER_STRING, FTP_PASV_RETURN_CODE, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);		nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP new PASV string: %s\n", port_string);#ifdef	FTP_DEBUG			printf ("FTP PASV IP address: 0x%lx\n", local_address);			printf ("FTP PASV translated IP Address 0x%lx\n", ntohl(global_address));			printf ("FTP translated PASV string: %.*s\n", 						strlen(port_string)-2, port_string);#endif		new_port_string_length = (ULONG) strlen (port_string);		if (adjust_tcp_sequence(					(char *)sptr_tcp_packet, 					cptr_port_string, 					port_string,					old_port_string_length, 					new_port_string_length, 					(char *)sptr_tcp_translation_entry) == ERROR)			{			return (FALSE);			}		}	/****************/	/* PORT Section */	/****************/	else		{		if (sscanf (cptr_port_string, FTP_PORT_PARAMETER_STRING, 				&tmp1, &tmp2, &tmp3, &tmp4, &tmp5, &tmp6) == FTP_PORT_PARAMETER_COUNT)					{			nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP PORT command found\n");			cptr_end_port_string = strchr (cptr_port_string, FTP_PORT_STRING_END_MARKER);			if (cptr_end_port_string == NULL)				{				nat_printf (NAT_PRINTF_ERROR, "natFtpPacket: Incomplete PORT command, disregard\n");				return(TRUE);	/* incomplete PORT command, disregard */				}			++cptr_end_port_string;			old_port_string_length = (ULONG) (cptr_end_port_string - cptr_port_string);			nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP PORT command: %.*s\n"					,old_port_string_length-2, cptr_port_string);			/* tk:  The global (remote) port is still unknown now, so just set it to 0.			   The remote port will be set to the right port number when the data connection 			   is initiated by the remote FTP server.			*/			global_port_number = 0x0000;			local_port_number = (USHORT) (tmp5 * 0x100 + tmp6);				bptr_local_address = (BYTE *) &local_address;					bptr_local_address[3] = (BYTE) (tmp4 & 0x00FF);			bptr_local_address[2] = (BYTE) (tmp3 & 0x00FF);			bptr_local_address[1] = (BYTE) (tmp2 & 0x00FF);			bptr_local_address[0] = (BYTE) (tmp1 & 0x00FF);			sprintf (port_string, FTP_PORT_PARAMETER_STRING, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);			nat_printf (NAT_PRINTF_DATA, "FTP ALG: FTP original PORT string: %.*s\n", 						strlen(port_string)-2, port_string);			local_address = ntohl (local_address);			if (nat.single_global_address_enabled == false)				{	/* basic NAT */				if (ftp_get_tcp_entry((ULONG)local_address, (char *) sptr_tcp_packet,						&transport) != OK)					{					return (FALSE);					}				sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) transport.tcp_block_ptr;				}			else				{	/* NAPT */				if (ftp_get_global_transport(local_address, local_port_number,					(char *) sptr_tcp_packet, &transport) != OK)					{					return (FALSE);					}				sptr_tcp_translation_entry = (TCP_TRANSLATION_ENTRY *) transport.tcp_block_ptr;				local_port_number = transport.global_port;				tmp5 = (USHORT) (local_port_number/0x100);				tmp6 = (USHORT) (local_port_number % 0x100);				}			global_address = transport.global_address;			global_address = htonl (global_address);						bptr_global_address = (BYTE *) &global_address;						tmp4 = bptr_global_address[3];			tmp3 = bptr_global_address[2];			tmp2 = bptr_global_address[1];			tmp1 = bptr_global_address[0];						sprintf (port_string, FTP_PORT_PARAMETER_STRING, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);			nat_printf (NAT_PRINTF_TRACE, "FTP ALG: FTP translated PORT string: %.*s\n", 						strlen(port_string)-2, port_string);#ifdef	FTP_DEBUG			printf ("FTP PORT IP address: 0x%lx\n", local_address);			printf ("FTP PORT translated IP Address 0x%lx\n", ntohl(global_address));			printf ("FTP translated PORT string: %.*s\n", 						strlen(port_string)-2, port_string);#endif			new_port_string_length = (ULONG) strlen (port_string);			if (adjust_tcp_sequence(	/* adjust TCP sequence number */					(char *)sptr_tcp_packet, 					cptr_port_string, 					port_string,					old_port_string_length, 					new_port_string_length, 					(char *)sptr_tcp_translation_entry) == ERROR)				{				return (FALSE);				}			}		}					return (TRUE);}/*****************************************************************************************Function:	natFtpInitDescription: 	******************************************************************************************/STATUS natFtpInit(u_short ftp_port){	STATUS			status;	semTake (natInitSync, WAIT_FOREVER);    /* wait for event */	nat_printf(NAT_PRINTF_INIT, "FTP initialization: port = %u\n", ftp_port);	memset(&nat_id, 0, sizeof(nat_id));	status = natGetID(&nat_id);

⌨️ 快捷键说明

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