alias_ftp.c revision 1a074ca60647580af3ac625d40694bbcf83a18c9
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*-
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Copyright (c) 2001 Charles Mott <cm@linktel.net>
42576743851c3c956ad7e867e74df1084c30d434vboxsync * All rights reserved.
42576743851c3c956ad7e867e74df1084c30d434vboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Redistribution and use in source and binary forms, with or without
42576743851c3c956ad7e867e74df1084c30d434vboxsync * modification, are permitted provided that the following conditions
42576743851c3c956ad7e867e74df1084c30d434vboxsync * are met:
42576743851c3c956ad7e867e74df1084c30d434vboxsync * 1. Redistributions of source code must retain the above copyright
42576743851c3c956ad7e867e74df1084c30d434vboxsync * notice, this list of conditions and the following disclaimer.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * 2. Redistributions in binary form must reproduce the above copyright
42576743851c3c956ad7e867e74df1084c30d434vboxsync * notice, this list of conditions and the following disclaimer in the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * documentation and/or other materials provided with the distribution.
42576743851c3c956ad7e867e74df1084c30d434vboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42576743851c3c956ad7e867e74df1084c30d434vboxsync * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42576743851c3c956ad7e867e74df1084c30d434vboxsync * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42576743851c3c956ad7e867e74df1084c30d434vboxsync * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
42576743851c3c956ad7e867e74df1084c30d434vboxsync * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42576743851c3c956ad7e867e74df1084c30d434vboxsync * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42576743851c3c956ad7e867e74df1084c30d434vboxsync * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42576743851c3c956ad7e867e74df1084c30d434vboxsync * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42576743851c3c956ad7e867e74df1084c30d434vboxsync * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42576743851c3c956ad7e867e74df1084c30d434vboxsync * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42576743851c3c956ad7e867e74df1084c30d434vboxsync * SUCH DAMAGE.
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync#ifndef VBOX
42576743851c3c956ad7e867e74df1084c30d434vboxsync#include <sys/cdefs.h>
42576743851c3c956ad7e867e74df1084c30d434vboxsync__FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_ftp.c,v 1.29.2.1.4.1 2009/04/15 03:14:26 kensmith Exp $");
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*
42576743851c3c956ad7e867e74df1084c30d434vboxsync Alias_ftp.c performs special processing for FTP sessions under
42576743851c3c956ad7e867e74df1084c30d434vboxsync TCP. Specifically, when a PORT/EPRT command from the client
42576743851c3c956ad7e867e74df1084c30d434vboxsync side or 227/229 reply from the server is sent, it is intercepted
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync and modified. The address is changed to the gateway machine
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync and an aliasing port is used.
42576743851c3c956ad7e867e74df1084c30d434vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync For this routine to work, the message must fit entirely into a
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync single TCP packet. This is typically the case, but exceptions
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync can easily be envisioned under the actual specifications.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync Probably the most troubling aspect of the approach taken here is
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync that the new message will typically be a different length, and
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync this causes a certain amount of bookkeeping to keep track of the
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync changes of sequence and acknowledgment numbers, since the client
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync machine is totally unaware of the modification to the TCP stream.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync References: RFC 959, RFC 2428.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync Initial version: August, 1996 (cjm)
42576743851c3c956ad7e867e74df1084c30d434vboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync Version 1.6
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync Brian Somers and Martin Renters identified an IP checksum
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync error for modified IP packets.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Version 1.7: January 9, 1996 (cjm)
cfeffc352a20376569f3feb9c5b4918ffe4c73c6vboxsync Differential checksum computation for change
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync in IP packet length.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Version 2.1: May, 1997 (cjm)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Very minor changes to conform with
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync local/global/function naming conventions
42576743851c3c956ad7e867e74df1084c30d434vboxsync within the packet aliasing module.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync Version 3.1: May, 2000 (eds)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync Add support for passive mode, alias the 227 replies.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync See HISTORY file for record of revisions.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync*/
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Includes */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifdef _KERNEL
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/param.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/ctype.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/systm.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/kernel.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/module.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <errno.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <sys/types.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <stdio.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <string.h>
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#endif
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#include <netinet/in_systm.h>
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#include <netinet/in.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <netinet/ip.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <netinet/tcp.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifdef _KERNEL
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <netinet/libalias/alias.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <netinet/libalias/alias_local.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include <netinet/libalias/alias_mod.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include "alias_local.h"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#include "alias_mod.h"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else /* VBOX */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync# include <iprt/ctype.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync# include <slirp.h>
1379dfd407ada5fab15655776896f13b61a951fdvboxsync# include "alias_local.h"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync# include "alias_mod.h"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif /* VBOX */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#define FTP_CONTROL_PORT_NUMBER 21
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic void
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncAliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int maxpacketsize);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncfingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
42576743851c3c956ad7e867e74df1084c30d434vboxsync
cb70b5cc08e3b666361766188f99cc86ed1626fbvboxsync if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
cb70b5cc08e3b666361766188f99cc86ed1626fbvboxsync ah->maxpktsize == 0)
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (-1);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync || ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER)
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (-1);
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic int
42576743851c3c956ad7e867e74df1084c30d434vboxsyncprotohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync AliasHandleFtpOut(la, pip, ah->lnk, ah->maxpktsize);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync return (0);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync}
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#ifndef VBOX
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstruct proto_handler handlers[] = {
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync {
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync .pri = 80,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync .dir = OUT,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync .proto = TCP,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync .fingerprint = &fingerprint,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync .protohandler = &protohandler
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync },
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync { EOH }
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync};
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#else /* !VBOX */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#define handlers pData->ftp_module
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif /* VBOX */
42576743851c3c956ad7e867e74df1084c30d434vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync#ifndef VBOX
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncmod_handler(module_t mod, int type, void *data)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int ftp_alias_handler(PNATState pData, int type);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncint
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncftp_alias_load(PNATState pData)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return ftp_alias_handler(pData, MOD_LOAD);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncint
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncftp_alias_unload(PNATState pData)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return ftp_alias_handler(pData, MOD_UNLOAD);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncftp_alias_handler(PNATState pData, int type)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync int error;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#ifdef VBOX
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (handlers == NULL)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers = RTMemAllocZ(2 * sizeof(struct proto_handler));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[0].pri = 80;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[0].dir = OUT;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[0].proto = TCP;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[0].fingerprint = &fingerprint;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[0].protohandler = &protohandler;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync handlers[1].pri = EOH;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif /* VBOX */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync switch (type) {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case MOD_LOAD:
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync error = 0;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync#ifdef VBOX
42576743851c3c956ad7e867e74df1084c30d434vboxsync LibAliasAttachHandlers(pData, handlers);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync LibAliasAttachHandlers(handlers);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case MOD_UNLOAD:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync error = 0;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync#ifdef VBOX
42576743851c3c956ad7e867e74df1084c30d434vboxsync LibAliasDetachHandlers(pData, handlers);
42576743851c3c956ad7e867e74df1084c30d434vboxsync RTMemFree(handlers);
42576743851c3c956ad7e867e74df1084c30d434vboxsync handlers = NULL;
42576743851c3c956ad7e867e74df1084c30d434vboxsync#else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync LibAliasDetachHandlers(handlers);
42576743851c3c956ad7e867e74df1084c30d434vboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
42576743851c3c956ad7e867e74df1084c30d434vboxsync default:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync error = EINVAL;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync }
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (error);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#ifndef VBOX
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifdef _KERNEL
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsyncstatic
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsyncmoduledata_t alias_mod = {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync "alias_ftp", mod_handler, NULL
1379dfd407ada5fab15655776896f13b61a951fdvboxsync};
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif /*!VBOX*/
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#ifdef _KERNEL
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncDECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncMODULE_VERSION(alias_ftp, 1);
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncMODULE_DEPEND(alias_ftp, libalias, 1, 1, 1);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync#endif
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
074ccc67396b8d3dbf725e280c6a9ab1a0610083vboxsync#define FTP_CONTROL_PORT_NUMBER 21
06b49f334535705aeae0ac0572fc5142dc589153vboxsync#define MAX_MESSAGE_SIZE 128
06b49f334535705aeae0ac0572fc5142dc589153vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/* FTP protocol flags. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define WAIT_CRLF 0x01
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncenum ftp_message_type {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync FTP_PORT_COMMAND,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync FTP_EPRT_COMMAND,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync FTP_227_REPLY,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync FTP_229_REPLY,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync FTP_UNKNOWN_MESSAGE
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync};
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int ParseFtpPortCommand(struct libalias *la, char *, int);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int ParseFtpEprtCommand(struct libalias *la, char *, int);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int ParseFtp227Reply(struct libalias *la, char *, int);
06b49f334535705aeae0ac0572fc5142dc589153vboxsyncstatic int ParseFtp229Reply(struct libalias *la, char *, int);
06b49f334535705aeae0ac0572fc5142dc589153vboxsyncstatic void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncAliasHandleFtpOut(
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync struct libalias *la,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync struct ip *pip, /* IP packet to examine/patch */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync struct alias_link *lnk, /* The link to go through (aliased port) */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync int maxpacketsize /* The maximum size this packet can grow to
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync (including headers) */ )
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync int hlen, tlen, dlen, pflags;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync char *sptr;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync struct tcphdr *tc;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync int ftp_message_type;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync/* Calculate data length of TCP packet */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync tc = (struct tcphdr *)ip_next(pip);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync hlen = (pip->ip_hl + tc->th_off) << 2;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync tlen = ntohs(pip->ip_len);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync dlen = tlen - hlen;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/* Place string pointer and beginning of data */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync sptr = (char *)pip;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync sptr += hlen;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Check that data length is not too long and previous message was
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * properly terminated with CRLF.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pflags = GetProtocolFlags(lnk);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync ftp_message_type = FTP_UNKNOWN_MESSAGE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * When aliasing a client, check for the PORT/EPRT command.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (ParseFtpPortCommand(la, sptr, dlen))
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync ftp_message_type = FTP_PORT_COMMAND;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync else if (ParseFtpEprtCommand(la, sptr, dlen))
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync ftp_message_type = FTP_EPRT_COMMAND;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync } else {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync/*
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync * When aliasing a server, check for the 227/229 reply.
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (ParseFtp227Reply(la, sptr, dlen))
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync ftp_message_type = FTP_227_REPLY;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync else if (ParseFtp229Reply(la, sptr, dlen)) {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync ftp_message_type = FTP_229_REPLY;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync la->true_addr.s_addr = pip->ip_src.s_addr;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync NewFtpMessage(la, pip, lnk, maxpacketsize, ftp_message_type);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (dlen) { /* only if there's data */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync sptr = (char *)pip; /* start over at beginning */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * have grown */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pflags &= ~WAIT_CRLF;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pflags |= WAIT_CRLF;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync SetProtocolFlags(lnk, pflags);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic int
42576743851c3c956ad7e867e74df1084c30d434vboxsyncParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
42576743851c3c956ad7e867e74df1084c30d434vboxsync char ch;
42576743851c3c956ad7e867e74df1084c30d434vboxsync int i, state;
42576743851c3c956ad7e867e74df1084c30d434vboxsync u_int32_t addr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync u_short port;
42576743851c3c956ad7e867e74df1084c30d434vboxsync u_int8_t octet;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync /* Format: "PORT A,D,D,R,PO,RT". */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync /* Return if data length is too short. */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync if (dlen < 18)
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (strncasecmp("PORT ", sptr, 5))
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return (0);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync addr = port = octet = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync state = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync for (i = 5; i < dlen; i++) {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync ch = sptr[i];
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync switch (state) {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync case 0:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (isspace(ch))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync break;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync state++;
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 1:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 3:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 5:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 7:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 9:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 11:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (isdigit(ch)) {
42576743851c3c956ad7e867e74df1084c30d434vboxsync octet = ch - '0';
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync break;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 2:
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 4:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 6:
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case 8:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (isdigit(ch))
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync octet = 10 * octet + ch - '0';
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync else if (ch == ',') {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync addr = (addr << 8) + octet;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync state++;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync } else
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return (0);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync break;
cb70b5cc08e3b666361766188f99cc86ed1626fbvboxsync case 10:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync case 12:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (isdigit(ch))
42576743851c3c956ad7e867e74df1084c30d434vboxsync octet = 10 * octet + ch - '0';
42576743851c3c956ad7e867e74df1084c30d434vboxsync else if (ch == ',' || state == 12) {
42576743851c3c956ad7e867e74df1084c30d434vboxsync port = (port << 8) + octet;
42576743851c3c956ad7e867e74df1084c30d434vboxsync state++;
42576743851c3c956ad7e867e74df1084c30d434vboxsync } else
42576743851c3c956ad7e867e74df1084c30d434vboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
42576743851c3c956ad7e867e74df1084c30d434vboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (state == 13) {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync la->true_addr.s_addr = htonl(addr);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync la->true_port = port;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (1);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync}
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync{
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync char ch, delim;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync int i, state;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync u_int32_t addr;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync u_short port;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync u_int8_t octet;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
62eba2c4d39256b293dc23f1608c5ae26d412c0fvboxsync /* Format: "EPRT |1|A.D.D.R|PORT|". */
62eba2c4d39256b293dc23f1608c5ae26d412c0fvboxsync
06b49f334535705aeae0ac0572fc5142dc589153vboxsync /* Return if data length is too short. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (dlen < 18)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return (0);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (strncasecmp("EPRT ", sptr, 5))
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return (0);
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync addr = port = octet = 0;
20f21077abf35d7b7b618acb159267933907407fvboxsync delim = '|'; /* XXX gcc -Wuninitialized */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync state = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync for (i = 5; i < dlen; i++) {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync ch = sptr[i];
06b49f334535705aeae0ac0572fc5142dc589153vboxsync switch (state) {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case 0:
20f21077abf35d7b7b618acb159267933907407fvboxsync if (!isspace(ch)) {
42576743851c3c956ad7e867e74df1084c30d434vboxsync delim = ch;
42576743851c3c956ad7e867e74df1084c30d434vboxsync state++;
42576743851c3c956ad7e867e74df1084c30d434vboxsync }
42576743851c3c956ad7e867e74df1084c30d434vboxsync break;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 1:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync if (ch == '1') /* IPv4 address */
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync state++;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync else
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync return (0);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync break;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 2:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync if (ch == delim)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync else
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync return (0);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync break;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 3:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 5:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 7:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 9:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (isdigit(ch)) {
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync octet = ch - '0';
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync } else
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync return (0);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 4:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 6:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 8:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync case 10:
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync if (isdigit(ch))
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync octet = 10 * octet + ch - '0';
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync else if (ch == '.' || state == 10) {
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync addr = (addr << 8) + octet;
42576743851c3c956ad7e867e74df1084c30d434vboxsync state++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
42576743851c3c956ad7e867e74df1084c30d434vboxsync break;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 11:
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync if (isdigit(ch)) {
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync port = ch - '0';
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync break;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync case 12:
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync if (isdigit(ch))
074ccc67396b8d3dbf725e280c6a9ab1a0610083vboxsync port = 10 * port + ch - '0';
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync else if (ch == delim)
074ccc67396b8d3dbf725e280c6a9ab1a0610083vboxsync state++;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync else
68f6401ff0e0eac2b9dcb0c71f233cd27b289c24vboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (state == 13) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync la->true_addr.s_addr = htonl(addr);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync la->true_port = port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (1);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
68f6401ff0e0eac2b9dcb0c71f233cd27b289c24vboxsyncstatic int
20f21077abf35d7b7b618acb159267933907407fvboxsyncParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
20f21077abf35d7b7b618acb159267933907407fvboxsync{
20f21077abf35d7b7b618acb159267933907407fvboxsync char ch;
20f21077abf35d7b7b618acb159267933907407fvboxsync int i, state;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync u_int32_t addr;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync u_short port;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync u_int8_t octet;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync /* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync /* Return if data length is too short. */
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync if (dlen < 17)
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync if (strncmp("227 ", sptr, 4))
074ccc67396b8d3dbf725e280c6a9ab1a0610083vboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync addr = port = octet = 0;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync state = 0;
074ccc67396b8d3dbf725e280c6a9ab1a0610083vboxsync for (i = 4; i < dlen; i++) {
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync ch = sptr[i];
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync switch (state) {
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync case 0:
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync if (ch == '(')
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync state++;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync break;
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 1:
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync case 3:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 5:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 7:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 9:
42576743851c3c956ad7e867e74df1084c30d434vboxsync case 11:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (isdigit(ch)) {
42576743851c3c956ad7e867e74df1084c30d434vboxsync octet = ch - '0';
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync return (0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync break;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 2:
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 4:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 6:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync case 8:
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (isdigit(ch))
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync octet = 10 * octet + ch - '0';
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync else if (ch == ',') {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync addr = (addr << 8) + octet;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync state++;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return (0);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 10:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case 12:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (isdigit(ch))
1379dfd407ada5fab15655776896f13b61a951fdvboxsync octet = 10 * octet + ch - '0';
1379dfd407ada5fab15655776896f13b61a951fdvboxsync else if (ch == ',' || (state == 12 && ch == ')')) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync port = (port << 8) + octet;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (state == 13) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync la->true_port = port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync la->true_addr.s_addr = htonl(addr);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (1);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync char ch, delim;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int i, state;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync u_short port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Return if data length is too short. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (dlen < 11)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (strncmp("229 ", sptr, 4))
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync port = 0;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync delim = '|'; /* XXX gcc -Wuninitialized */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state = 0;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync for (i = 4; i < dlen; i++) {
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync ch = sptr[i];
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync switch (state) {
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case 0:
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync if (ch == '(')
1379dfd407ada5fab15655776896f13b61a951fdvboxsync state++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync case 1:
20f21077abf35d7b7b618acb159267933907407fvboxsync delim = ch;
20f21077abf35d7b7b618acb159267933907407fvboxsync state++;
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync case 2:
20f21077abf35d7b7b618acb159267933907407fvboxsync case 3:
20f21077abf35d7b7b618acb159267933907407fvboxsync if (ch == delim)
20f21077abf35d7b7b618acb159267933907407fvboxsync state++;
20f21077abf35d7b7b618acb159267933907407fvboxsync else
20f21077abf35d7b7b618acb159267933907407fvboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync case 4:
20f21077abf35d7b7b618acb159267933907407fvboxsync if (isdigit(ch)) {
20f21077abf35d7b7b618acb159267933907407fvboxsync port = ch - '0';
20f21077abf35d7b7b618acb159267933907407fvboxsync state++;
20f21077abf35d7b7b618acb159267933907407fvboxsync } else
20f21077abf35d7b7b618acb159267933907407fvboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync case 5:
20f21077abf35d7b7b618acb159267933907407fvboxsync if (isdigit(ch))
20f21077abf35d7b7b618acb159267933907407fvboxsync port = 10 * port + ch - '0';
20f21077abf35d7b7b618acb159267933907407fvboxsync else if (ch == delim)
20f21077abf35d7b7b618acb159267933907407fvboxsync state++;
20f21077abf35d7b7b618acb159267933907407fvboxsync else
20f21077abf35d7b7b618acb159267933907407fvboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync case 6:
20f21077abf35d7b7b618acb159267933907407fvboxsync if (ch == ')')
20f21077abf35d7b7b618acb159267933907407fvboxsync state++;
20f21077abf35d7b7b618acb159267933907407fvboxsync else
20f21077abf35d7b7b618acb159267933907407fvboxsync return (0);
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync }
20f21077abf35d7b7b618acb159267933907407fvboxsync }
20f21077abf35d7b7b618acb159267933907407fvboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsync if (state == 7) {
20f21077abf35d7b7b618acb159267933907407fvboxsync la->true_port = port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (1);
20f21077abf35d7b7b618acb159267933907407fvboxsync } else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return (0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic void
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncNewFtpMessage(struct libalias *la, struct ip *pip,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync struct alias_link *lnk,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int maxpacketsize,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int ftp_message_type)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync struct alias_link *ftp_lnk;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Security checks. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (pip->ip_src.s_addr != la->true_addr.s_addr)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (la->true_port < IPPORT_RESERVED)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Establish link to address and port found in FTP control message. */
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync ftp_lnk = FindUdpTcpOut(la, la->true_addr, GetDestAddress(lnk),
1379dfd407ada5fab15655776896f13b61a951fdvboxsync htons(la->true_port), 0, IPPROTO_TCP, 1);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (ftp_lnk != NULL) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int slen, hlen, tlen, dlen;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync struct tcphdr *tc;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifndef NO_FW_PUNCH
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Punch hole in firewall */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PunchFWHole(ftp_lnk);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Calculate data length of TCP packet */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tc = (struct tcphdr *)ip_next(pip);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync hlen = (pip->ip_hl + tc->th_off) << 2;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tlen = ntohs(pip->ip_len);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync dlen = tlen - hlen;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Create new FTP message. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync char stemp[MAX_MESSAGE_SIZE + 1];
1379dfd407ada5fab15655776896f13b61a951fdvboxsync char *sptr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync u_short alias_port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync u_char *ptr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int a1, a2, a3, a4, p1, p2;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync struct in_addr alias_address;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Decompose alias address into quad format */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync alias_address = GetAliasAddress(lnk);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync ptr = (u_char *) & alias_address.s_addr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1 = *ptr++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a2 = *ptr++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a3 = *ptr++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a4 = *ptr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync alias_port = GetAliasPort(ftp_lnk);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Prepare new command */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync switch (ftp_message_type) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case FTP_PORT_COMMAND:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case FTP_227_REPLY:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Decompose alias port into pair format. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync ptr = (u_char *)&alias_port;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync p1 = *ptr++;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync p2 = *ptr;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (ftp_message_type == FTP_PORT_COMMAND) {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Generate PORT command string. */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#ifndef VBOX
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1, a2, a3, a4, p1, p2);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTStrPrintf(stemp, sizeof(stemp), "PORT %d,%d,%d,%d,%d,%d\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1, a2, a3, a4, p1, p2);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } else {
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync /* Generate 227 reply string. */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#ifndef VBOX
1379dfd407ada5fab15655776896f13b61a951fdvboxsync sprintf(stemp,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync a1, a2, a3, a4, p1, p2);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTStrPrintf(stemp, sizeof(stemp),
1379dfd407ada5fab15655776896f13b61a951fdvboxsync "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1, a2, a3, a4, p1, p2);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#endif
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync case FTP_EPRT_COMMAND:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Generate EPRT command string. */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#ifndef VBOX
1379dfd407ada5fab15655776896f13b61a951fdvboxsync sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1, a2, a3, a4, ntohs(alias_port));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTStrPrintf(stemp, sizeof(stemp), "EPRT |1|%d.%d.%d.%d|%d|\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync a1, a2, a3, a4, ntohs(alias_port));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync case FTP_229_REPLY:
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* Generate 229 reply string. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifndef VBOX
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync ntohs(alias_port));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTStrPrintf(stemp, sizeof(stemp), "229 Entering Extended Passive Mode (|||%d|)\r\n",
1379dfd407ada5fab15655776896f13b61a951fdvboxsync ntohs(alias_port));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Save string length for IP header modification */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync slen = strlen(stemp);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Copy modified buffer into IP packet. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync sptr = (char *)pip;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync sptr += hlen;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync strncpy(sptr, stemp, maxpacketsize - hlen);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync/* Save information regarding modified seq and ack numbers */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int delta;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SetAckModified(lnk);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync delta = GetDeltaSeqOut(pip, lnk);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync AddSeq(pip, lnk, delta + slen - dlen);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Revise IP header */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync u_short new_len;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync new_len = htons(hlen + slen);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync DifferentialChecksum(&pip->ip_sum,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync &new_len,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync &pip->ip_len,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync 1);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pip->ip_len = new_len;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/* Compute TCP checksum for revised packet */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tc->th_sum = 0;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifdef _KERNEL
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tc->th_x2 = 1;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync tc->th_sum = TcpChecksum(pip);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync } else {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#ifdef LIBALIAS_DEBUG
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync fprintf(stderr,
42576743851c3c956ad7e867e74df1084c30d434vboxsync "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync