www.pudn.com > PIPMasq.zip > ftpmgr.cpp


#include "stdafx.h" 
#include "PIPMasq.h" 
 
////////////////////////// FtpMgr ///////////////////////////////// 
 
FtpMgr::FtpMgr( 
	TableMgr*	tableMgr, 
	PortMgr*	portMgr, 
	const char* pseudIPAddr 
) 
{ 
	m_tableMgr = tableMgr; 
	m_portMgr = portMgr; 
	memcpy(m_pseudIPAddr, pseudIPAddr, 16); 
}; 
 
FtpMgr::~FtpMgr() 
{ 
	printf(".....FtpMgr is destructed.\n"); 
//	Sleep(1000);	 
} 
 
 
void 
FtpMgr::activeMode_out(char *pChar, int *dataLen, TableEntry* m_table) 
{ 
	char *_pChar = pChar; 
 
 
	_pChar += sizeof(struct ethhdr); 	 
	struct iphdr *_iphdr = (struct iphdr *)_pChar; 
 
	_pChar += sizeof(struct iphdr);  
	struct tcphdr *_tcphdr = (struct tcphdr *)_pChar; 
 
	_pChar = _pChar + sizeof(struct tcphdr); 
 
	// This "PORT" means the Port Number that the FTP server will use. 
	// See RFC 959 
	if (strncmp(_pChar, "PORT", 4) == 0) 
	{ 
		_pChar += 5;  // skip "PORT" + one space 
		char* _pChar_1 = _pChar; 
		 
		// Counter for the FTP message. 
		int _counter = 0; 
		 
		// The tail of FTP message is "\r\n" ... Maybe, 
		// I could not find the description in RFC959  
		while(1) 
		{ 
			if ((*_pChar_1 == '\r') && (*(_pChar_1 + 1) == '\n')) 
				break; 
			 
			_counter++; 
			 
			// "XXX,XXX,XXX,XXX,XXX,XXX" is the maximun data length 
			if (_counter > 23) break;  
			 
			_pChar_1++; 
		} 
		 
		char _string[30];  // 30 is bigger than 23  
		 
		memcpy(_string, _pChar, _counter); 
		_string[_counter] = '\0'; 
		 
		char seps[]   = ",."; 
		char *token[6]; 
		 
		//  (0) (1) (2) (3) (4) (5) 
		// "XXX,XXX,XXX,XXX,XXX,XXX"  
		//                  ^^^ ^^^ <- Port Number information    
		 
		token[0] = strtok( _string, seps );	 
		//	strcpy(token[0], strtok( _string, seps ));	 
		 
		for(int i=1; i<6; i++) 
		{ 
			token[i] = strtok( NULL, seps ); 
			//		strcpy(token[i], strtok( NULL, seps ));	 
		} 
		 
		int _tcpDataPortNum_h = atoi(token[4]) * 256;	// (4) 
		_tcpDataPortNum_h += atoi(token[5]);			// (5) 
		 
		 
		char _pIPAddr[16]; 
		memcpy(_pIPAddr, m_pseudIPAddr, 16); 
		 
		token[0] = strtok(_pIPAddr, seps); 
		 
		for(i=1; i<4; i++) 
		{ 
			token[i] = strtok( NULL, seps ); 
		} 
		 
		__u16 _tcpDataPortNum_n = htons(_tcpDataPortNum_h); 
		 
		// Port Number reservation 
		__u16 _masqPort_n; 
		if (! m_portMgr->reservPort(TCP, &_masqPort_n)) 
			return; 
		 
		// Table Management 
		TableEntry _entry; 
 
		_entry.diff_ack = 0; 
		 
		memcpy(&_entry, m_table, sizeof(TableEntry)); 
		 
		_entry.expireTime = time(NULL) + EXPIRE_PERIOD; 
		_entry.Protocol = TCP; 
		_entry.masqPort = _masqPort_n;  // Masq port for network 
		_entry.destPort = htons(FTP_DATA);	// ftp-data 
		_entry.srcPort = _tcpDataPortNum_n; // TCP data port for network 
		_entry.p_before = _entry.p_after = NULL; 
		 
		if (m_tableMgr->addEntry(&_entry) == false) 
			return; 
		// End of Table Management 
		 
		// Modify the packet 
		__u16 __masqPort_h = htons(_masqPort_n); 
		 
		unsigned int _upper = __masqPort_h / 256; 
		unsigned int _lower = __masqPort_h % 256; 
		 
		sprintf(_string, "%s,%s,%s,%s,%d,%d\r\n\0",  
			token[0],token[1],token[2],token[3],_upper,_lower); 
		 
		// printf("%s\n",_string); 
		 
		memcpy(_pChar, _string, strlen(_string)); 
		 
		int _diffLen = strlen(_string) - _counter -2 ; // this "2" means "\r\n\" 
		 
		_iphdr->tot_len = htons(ntohs(_iphdr->tot_len) + _diffLen); 
 
		_tcphdr->seq = htonl(ntohl(_tcphdr->seq) + m_table->diff_ack); 
		 
		m_table->diff_ack += _diffLen;  //After modification - before modification 
 
		*dataLen += _diffLen; 
 
		return; 
	 
	} 
		 
	_tcphdr->seq = htonl(ntohl(_tcphdr->seq) + m_table->diff_ack); 
 
	return; 
		 
}