Exemplo n.º 1
0
static void
AliasHandleFtpIn(struct libalias *la,
    struct ip *pip,		/* IP packet to examine/patch */
    struct alias_link *lnk)	/* The link to go through (aliased port) */
{
	int hlen, tlen, dlen, pflags;
	char *sptr;
	struct tcphdr *tc;

	/* Calculate data length of TCP packet */
	tc = (struct tcphdr *)ip_next(pip);
	hlen = (pip->ip_hl + tc->th_off) << 2;
	tlen = ntohs(pip->ip_len);
	dlen = tlen - hlen;

	/* Place string pointer and beginning of data */
	sptr = (char *)pip;
	sptr += hlen;

	/*
	 * Check that data length is not too long and previous message was
	 * properly terminated with CRLF.
	 */
	pflags = GetProtocolFlags(lnk);
	if (dlen <= MAX_MESSAGE_SIZE && (pflags & WAIT_CRLF) == 0 &&
	    ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER &&
	    (ParseFtpPortCommand(la, sptr, dlen) != 0 ||
	     ParseFtpEprtCommand(la, sptr, dlen) != 0)) {
		/*
		 * Alias active mode client requesting data from server
		 * behind NAT.  We need to alias server->client connection
		 * to external address client is connecting to.
		 */
		AddLink(la, GetOriginalAddress(lnk), la->true_addr,
		    GetAliasAddress(lnk), htons(FTP_CONTROL_PORT_NUMBER - 1),
		    htons(la->true_port), GET_ALIAS_PORT, IPPROTO_TCP);
	}
	/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
	if (dlen) {
		sptr = (char *)pip;		/* start over at beginning */
		tlen = ntohs(pip->ip_len);	/* recalc tlen, pkt may
						 * have grown.
						 */
		if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
			pflags &= ~WAIT_CRLF;
		else
			pflags |= WAIT_CRLF;
		SetProtocolFlags(lnk, pflags);
       }
}
Exemplo n.º 2
0
static void
AliasHandleFtpOut(
    struct libalias *la,
    struct ip *pip,		/* IP packet to examine/patch */
    struct alias_link *lnk,	/* The link to go through (aliased port) */
    int maxpacketsize		/* The maximum size this packet can grow to
	(including headers) */ )
{
	int hlen, tlen, dlen, pflags;
	char *sptr;
	struct tcphdr *tc;
	int ftp_message_type;

/* Calculate data length of TCP packet */
	tc = (struct tcphdr *)ip_next(pip);
	hlen = (pip->ip_hl + tc->th_off) << 2;
	tlen = ntohs(pip->ip_len);
	dlen = tlen - hlen;

/* Place string pointer and beginning of data */
	sptr = (char *)pip;
	sptr += hlen;

/*
 * Check that data length is not too long and previous message was
 * properly terminated with CRLF.
 */
	pflags = GetProtocolFlags(lnk);
	if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
		ftp_message_type = FTP_UNKNOWN_MESSAGE;

		if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
/*
 * When aliasing a client, check for the PORT/EPRT command.
 */
			if (ParseFtpPortCommand(la, sptr, dlen))
				ftp_message_type = FTP_PORT_COMMAND;
			else if (ParseFtpEprtCommand(la, sptr, dlen))
				ftp_message_type = FTP_EPRT_COMMAND;
		} else {
/*
 * When aliasing a server, check for the 227/229 reply.
 */
			if (ParseFtp227Reply(la, sptr, dlen))
				ftp_message_type = FTP_227_REPLY;
			else if (ParseFtp229Reply(la, sptr, dlen)) {
				ftp_message_type = FTP_229_REPLY;
				la->true_addr.s_addr = pip->ip_src.s_addr;
			}
		}

		if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
			NewFtpMessage(la, pip, lnk, maxpacketsize, ftp_message_type);
	}
/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */

	if (dlen) {		/* only if there's data */
		sptr = (char *)pip;	/* start over at beginning */
		tlen = ntohs(pip->ip_len);	/* recalc tlen, pkt may
						 * have grown */
		if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
			pflags &= ~WAIT_CRLF;
		else
			pflags |= WAIT_CRLF;
		SetProtocolFlags(lnk, pflags);
	}
}