ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Copyright (c) 2001 Charles Mott <cm@linktel.net>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * All rights reserved.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Redistribution and use in source and binary forms, with or without
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * modification, are permitted provided that the following conditions
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * 1. Redistributions of source code must retain the above copyright
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * notice, this list of conditions and the following disclaimer.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * 2. Redistributions in binary form must reproduce the above copyright
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * notice, this list of conditions and the following disclaimer in the
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * documentation and/or other materials provided with the distribution.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * SUCH DAMAGE.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync__FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_db.c,v 1.71.2.2.4.1 2009/04/15 03:14:26 kensmith Exp $");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Alias_db.c encapsulates all data structures used for storing
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync packet aliasing data. Other parts of the aliasing software
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync access data through functions provided in this file.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Data storage is based on the notion of a "link", which is
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync established for ICMP echo/reply packets, UDP datagrams and
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync TCP stream connections. A link stores the original source
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync and destination addresses. For UDP and TCP, it also stores
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync source and destination port numbers, as well as an alias
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port number. Links are also used to store information about
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync There is a facility for sweeping through and deleting old
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync links as new packets are sent through. A simple timeout is
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync used for ICMP and UDP links. TCP links are left alone unless
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync there is an incomplete connection, in which case the link
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync can be deleted after a certain amount of time.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Initial version: August, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.4: September 16, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Facility for handling incoming links added.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.6: September 18, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ICMP data handling simplified.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.7: January 9, 1997 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Fragment handling simplified.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Saves pointers for unresolved fragments.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Permits links for unspecified remote ports
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync or unspecified remote addresses.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Fixed bug which did not properly zero port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync table entries after a link was deleted.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Cleaned up some obsolete comments.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.8: January 14, 1997 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Fixed data type error in StartPoint().
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (This error did not exist prior to v1.7
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync and was discovered and fixed by Ari Suutari)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.9: February 1, 1997
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Optionally, connections initiated from packet aliasing host
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync machine will will not have their port number aliased unless it
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync conflicts with an aliasing port already being used. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync All options earlier being #ifdef'ed are now available through
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync a new interface, SetPacketAliasMode(). This allows run time
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync control (which is now available in PPP+pktAlias through the
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync 'alias' keyword). (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added ability to create an alias port without
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync either destination address or port specified.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Removed K&R style function headers
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync and general cleanup. (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added packetAliasMode to replace compiler #defines's (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Allocates sockets for partially specified
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ports if ALIAS_USE_SOCKETS defined. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 2.0: March, 1997
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetAliasAddress() will now clean up alias links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if the aliasing address is changed. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasPermanentLink() function added to support permanent
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync links. (J. Fortes suggested the need for this.)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (192.168.0.2, port 21) <-> alias port 3604, known dest addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unknown dest port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync These permanent links allow for incoming connections to
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync machines on the local network. They can be given with a
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync user-chosen amount of specificity, with increasing specificity
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync meaning more security. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Quite a bit of rework to the basic engine. The portTable[]
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync array, which kept track of which ports were in use was replaced
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync by a table/linked list structure. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetExpire() function added. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink() no longer frees memory association with a pointer
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync to a fragment (this bug was first recognized by E. Eklund in
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 2.1: May, 1997 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Packet aliasing engine reworked so that it can handle
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync multiple external addresses rather than just a single
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync host address.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectPort() and PacketAliasRedirectAddr()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync added to the API. The first function is a more generalized
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync version of PacketAliasPermanentLink(). The second function
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync implements static network address translation.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 3.2: July, 2000 (salander and satoh)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added FindNewPortGroup to get contiguous range of port values.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link but not actually add one.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added FindRtspOut, which is closely derived from FindUdpTcpOut,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync except that the alias port (from FindNewPortGroup) is provided
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync See HISTORY file for additional revisions.
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Constants (note: constants are also defined
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync near relevant functions or structs)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Parameters used for cleanup of expired links */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* NOTE: ALIAS_CLEANUP_INTERVAL_SECS must be less then LINK_TABLE_OUT_SIZE */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define ALIAS_CLEANUP_MAX_SPOKES (LINK_TABLE_OUT_SIZE/5)
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* Timeouts (in seconds) for different link types */
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* TCP link expire time for different cases */
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link has been used and closed - minimal grace time to
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync allow ACKs and potential re-connect in FTP (XXX - is this allowed?) */
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link has been used and closed on one side - the other side
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync is allowed to still send data */
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link isn't yet up */
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link is up */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync These constants can be anything except zero, which indicates an
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unknown port number. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Data Structures
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync The fundamental data structure used in this program is
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "struct alias_link". Whenever a TCP connection is made,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync a UDP datagram is sent out, or an ICMP echo request is made,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync a link record is made (if it has not already been created).
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync The link record is identified by the source address/port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync and the destination address/port. In the case of an ICMP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync echo request, the source port is treated as being equivalent
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync with the 16-bit ID number of the ICMP packet.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync The link record also can store some auxiliary data. For
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync TCP connections that have had sequence and acknowledgment
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync modifications, data space is available to track these changes.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync A state field is used to keep track in changes to the TCP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync connection state. ID numbers of fragments can also be
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync stored in the auxiliary space. Pointers to unresolved
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fragments can also be stored.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync The link records support two independent chainings. Lookup
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync tables for input and out tables hold the initial pointers
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync the link chains. On input, the lookup table indexes on alias
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port and link type. On output, the lookup table indexes on
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync source address, destination address, source port, destination
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port and link type.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct ack_data_record { /* used to save changes to ACK/sequence
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct tcp_state { /* Information about TCP connection */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * sequence numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* been modified */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define N_LINK_TCP_DATA 3 /* Number of distinct ACK number changes
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * saved for a modified TCP stream */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int fwhole; /* Which firewall record is used for this
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct server { /* LSNAT server pool (circular list) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr src_addr; /* Address and port information */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * proto, frag */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* values for link_type */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* flag bits */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */
3b53e98860b3ca54c6843fba6c49ea53407cf0a5vboxsync# define LINK_UNFIREWALLED 0x08 /* This macro definition isn't used in this revision of libalias */
3b53e98860b3ca54c6843fba6c49ea53407cf0a5vboxsync#else /* VBOX */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync unsigned int timestamp; /* Time link was last accessed */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync unsigned int expire_time; /* Expire time for link */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_ENTRY (alias_link) list_out; /* Linked list of
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * pointers for */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_ENTRY (alias_link) list_in; /* input and output
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * lookup tables */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync union { /* Auxiliary data */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Clean up procedure. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void finishoff(void);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Kernel module definition. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncMALLOC_DEFINE(M_ALIAS, "libalias", "packet aliasing");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncalias_mod_handler(module_t mod, int type, void *data)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncDECLARE_MODULE(alias, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Internal utility routines (used only in alias_db.c)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLookup table starting points:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync StartPointIn() -- link table initial search point for
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync incoming packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync StartPointOut() -- link table initial search point for
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync outgoing packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncMiscellaneous:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SeqDiff() -- difference between two TCP sequences
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ShowAliasStats() -- send alias statistics to a monitor file
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Local prototypes */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_int StartPointIn(struct in_addr, u_short, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Firewall control */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Log file control */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void UninitPacketAliasLog(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncStartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Return the difference between two TCP sequence numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync This function is encapsulated in case there are any unusual
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync arithmetic conditions that need to be considered.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*make it grepable */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Used for debugging */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync AliasLog(la->logDesc, " (sock=%u)\n", la->sockCount);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Internal routines for finding, deleting and adding links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncPort Allocation:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetNewPort() -- find and reserve new alias port number
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetSocket() -- try to allocate a socket for a given port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLink creation and deletion:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync CleanupAliasData() - remove all link chains from lookup table
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync IncrementalCleanup() - look for stale links in a single chain
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink() - remove link
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync AddLink() - add link
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ReLink() - change link
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLink search:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkOut() - find link for outgoing packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkIn() - find link for incoming packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncPort search:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindNewPortGroup() - find an available group of ports
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Local prototypes */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int GetNewPort(struct libalias *, struct alias_link *, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_short GetSocket(struct libalias *, u_short, int *, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddLink(struct libalias *, struct in_addr, struct in_addr, struct in_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkOut (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkIn (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* GetNewPort() allocates port numbers. Note that if a port number
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync is already in use, that does not mean that it cannot be used by
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync another link concurrently. This is because GetNewPort() looks for
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unused triplets: (dest addr, dest port, alias port). */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Description of alias_port_param for GetNewPort(). When
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync this parameter is zero or positive, it precisely specifies
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync the port number. GetNewPort() will return this number
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync without check that it is in use.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync When this parameter is GET_ALIAS_PORT, it indicates to get a randomly
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync selected port number.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The aliasing port is automatically selected by one of
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * two methods below:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * When the PKT_ALIAS_SAME_PORTS option is chosen,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * the first try will be the actual source port. If
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * this is already in use, the remainder of the
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * trials will be random.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* First trial and all subsequent are random. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (alias_port_param >= 0 && alias_port_param < 0x10000) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (-1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Port number search */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < max_trials; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (-1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (err == 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* FindNewPortGroup() returns a base port number for an available
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync range of contiguous port numbers. Note that if a port number
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync is already in use, that does not mean that it cannot be used by
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync another link concurrently. This is because FindNewPortGroup()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync looks for unused triplets: (dest addr, dest port, alias port). */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Get link_type from protocol
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The aliasing port is automatically selected by one of two
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * methods below:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * When the ALIAS_SAME_PORTS option is chosen, the first
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * try will be the actual source port. If this is already
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * in use, the remainder of the trials will be random.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* First trial and all subsequent are random. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Port number search */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < max_trials; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (j = 0; j < port_count; j++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (0 != (search_result = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Found a good range, return base */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Find a new base to try */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/FindNewPortGroup(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *link_next = LIST_NEXT(lnk, list_out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH_SAFE(lnk, &la->linkTableOut[la->cleanupIndex++],
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->timeStamp - lnk->timestamp > lnk->expire_time)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Don't do anything if the link is marked permanent */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->deleteAllLinks == 0 && lnk->flags & LINK_PERMANENT)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Delete associated firewall hole, if any */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Free memory allocated for LSNAT server pool */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Adjust output table pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Adjust input table pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Close socket, if one has been allocated */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Link-type dependent cleanup */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Free memory */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Write statistics, if logging enabled */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddLink(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int alias_port_param, /* if less than zero, alias */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * If greater than */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Basic initialization */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Expiration time */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Determine alias flags */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Determine alias port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Link-type dependent initialization */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, " cannot allocate auxiliary TCP data\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Set up pointers for output lookup table */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Set up pointers for input lookup table */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync start_point = StartPointIn(alias_addr, lnk->alias_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int alias_port_param, /* if less than zero, alias */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * If greater than */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *new_lnk; /* zero, equal to alias port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync new_lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync_FindLinkOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Search for partially specified links. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, la->nullAddress, src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, la->nullAddress, src_port, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindLinkOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The following allows permanent links to be specified as
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * using the default source address (i.e. device interface
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * address) without knowing in advance what that address
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, la->nullAddress, dst_addr, src_port, dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Initialize pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* If either the dest addr or port is unknown, the search
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync loop will have to know about this. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Search loop */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync start_point = StartPointIn(alias_addr, alias_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (lnk->flags & LINK_PARTIALLY_SPECIFIED || lnk->server != NULL)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindLinkIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkIn(la, dst_addr, alias_addr, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The following allows permanent links to be specified as
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * using the default aliasing address (i.e. device
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * interface address) without knowing in advance what that
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * address is.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkIn(la, dst_addr, la->nullAddress, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* External routines for finding/adding links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync-- "external" means outside alias_db.c, but within alias*.c --
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindIcmpIn(), FindIcmpOut()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindFragmentIn1(), FindFragmentIn2()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync AddFragmentPtrLink(), FindFragmentPtr()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindProtoIn(), FindProtoOut()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindUdpTcpIn(), FindUdpTcpOut()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync AddPptp(), FindPptpOutByCallId(), FindPptpInByCallId(),
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindPptpOutByPeerCallId(), FindPptpInByPeerCallId()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindOriginalAddress(), FindAliasAddress()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync(prototypes in alias_local.h)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindIcmpIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindIcmpOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentIn1(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, la->nullAddress, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentIn2(struct libalias *la, struct in_addr dst_addr, /* Doesn't add a link if
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return AddLink(la, la->nullAddress, dst_addr, la->nullAddress,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentPtr(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindProtoIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindProtoOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindUdpTcpIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindUdpTcpOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type, create);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddPptp(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpOutByCallId(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpInByCallId(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindRtspOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr, src_port, 0, link_type, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindOriginalAddress(struct libalias *la, struct in_addr alias_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindAliasAddress(struct libalias *la, struct in_addr original_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, original_addr, la->nullAddress,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* External routines for getting or changing link data
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (external to alias_db.c, but internal to alias*.c)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetFragmentData(), GetFragmentData()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetFragmentPtr(), GetFragmentPtr()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetStateIn(), SetStateOut(), GetStateIn(), GetStateOut()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalAddress(), GetDestAddress(), GetAliasAddress()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalPort(), GetAliasPort()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetAckModified(), GetAckModified()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetDeltaAckIn(), GetDeltaSeqOut(), AddSeq()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetProtocolFlags(), GetProtocolFlags()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetDestCallId()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetFragmentAddr(struct alias_link *lnk, struct in_addr src_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetFragmentAddr(struct alias_link *lnk, struct in_addr *src_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP input state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP output state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP input state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP output state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetDefaultAliasAddress(struct libalias *la, struct in_addr alias_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Indicate that ACK numbers have been modified in a TCP connection */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetProxyAddress(struct alias_link *lnk, struct in_addr addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* See if ACK numbers have been modified */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDeltaAckIn(struct ip *pip, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFind out how much the ACK number has been altered for an incoming
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncTCP packet. To do this, a circular list of ACK numbers where the TCP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncpacket size was altered is searched.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDeltaSeqOut(struct ip *pip, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFind out how much the sequence number has been altered for an outgoing
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncTCP packet. To do this, a circular list of ACK numbers where the TCP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncpacket size was altered is searched.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddSeq(struct ip *pip, struct alias_link *lnk, int delta)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncWhen a TCP packet has been altered in length, save this
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncinformation in a circular list. If enough packets have
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncbeen altered, then this list will begin to overwrite itself.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (expire > 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetProtocolFlags(struct alias_link *lnk, int pflags)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetDestCallId(struct alias_link *lnk, u_int16_t cid)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ReLink(lnk, lnk->src_addr, lnk->dst_addr, lnk->alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_port, cid, lnk->alias_port, lnk->link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Miscellaneous Functions
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync HouseKeeping()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync InitPacketAliasLog()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPacketAliasLog()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Whenever an outgoing or incoming packet is handled, HouseKeeping()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync is called to find and remove timed-out aliasing links. Logic exists
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync to sweep through the entire table and linked list structure
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync every 60 seconds.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (prototype in alias_local.h)
ea79ff4df27672e01fdf0cfce6f35829e257ebedvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Save system time (seconds) in global variable timeStamp for use
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * by other functions. This is done so as not to unnecessarily
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * waste timeline by making system calls.
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
5d6de9034aa9fda1e16380ac3d7dad1a85d86867vboxsync la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Compute number of spokes (output table link chains) to cover */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n = LINK_TABLE_OUT_SIZE * (la->timeStamp - la->lastCleanupTime);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Handle different cases */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (n > 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < n; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (n < 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "something unexpected in time values\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Init the log file and enable logging */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if ((la->logDesc = fopen("/var/log/alias.log", "w")))
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync fprintf(la->logDesc, "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync Log2(("NAT: PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n"));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->logDesc = (void *)1; /* XXX: in vbox we don't use this param */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Close the log-file and disable logging. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Outside world interfaces
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync-- "outside world" means other than alias*.c routines --
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectPort()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasAddServer()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectProto()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectAddr()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectDynamic()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectDelete()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasSetAddress()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasInit()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasUninit()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasSetMode()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync(prototypes in alias.h)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Redirection from a specific public addr:port to a
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync private addr:port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "only TCP and UDP protocols allowed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Add server to the pool of servers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr addr, u_short port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Redirect packets of a given IP protocol from a specific
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync public address to a private address */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectProto(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Static address translation */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, la->nullAddress, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Mark the aliasing link dynamic */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectDynamic(struct libalias *la, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectDelete(struct libalias *la, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* This is a dangerous function to put in the API,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync because an invalid pointer can crash the program. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetAddress(struct libalias *la, struct in_addr addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetTarget(struct libalias *la, struct in_addr target_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef _KERNEL /* kernel cleans up on module unload */
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#endif /* !VBOX */
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
5d6de9034aa9fda1e16380ac3d7dad1a85d86867vboxsync la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Change mode for some operations */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncunsigned int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unsigned int flags, /* Which state to bring flags to */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unsigned int mask /* Mask of which flags to affect (use 0 to
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * do a probe for flag values) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Enable logging? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Do the enable */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* _Disable_ logging? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Start punching holes in the firewall? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Stop punching holes in the firewall? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Other flags can be set/cleared without special action */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*****************
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Code to support firewall punching. This shouldn't really be in this
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync file, but making variables global is evil too.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ****************/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Firewall include files */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * helper function, updates the pointer to cmd with the length
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * of the current command, and also cleans up the first word of
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * the new command in case it has been clobbered before.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * A function to fill simple commands of size 1.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Existing flags are preserved.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_cmd(ipfw_insn * cmd, enum ipfw_opcodes opcode, int size,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->len = ((cmd->len | flags) & (F_NOT | F_OR)) | (size & F_LEN_MASK);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_ip(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int32_t addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u32), 0, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_one_port(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int16_t port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u16), 0, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_cmd(cmd, O_PROTO, F_INSN_SIZE(ipfw_insn), 0, proto);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync rule->act_ofs = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_cmd(cmd, action, F_INSN_SIZE(ipfw_insn), 0, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync rule->cmd_len = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Make a certain link go through the firewall */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int r; /* Result code */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Don't do anything unless we are asked to */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/** Build rule **/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Find empty slot */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fwhole < la->fireWallBaseNum + la->fireWallNumNums &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (fwhole == la->fireWallBaseNum + la->fireWallNumNums) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* No rule point empty - we can't punch more holes. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "libalias: Unable to create firewall hole!\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Start next search at next position */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * generate two rules of the form
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * add fwhole accept tcp from OAddr OPort to DAddr DPort add fwhole
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * accept tcp from DAddr DPort to OAddr OPort
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (GetOriginalPort(lnk) != 0 && GetDestPort(lnk) != 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)),
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Indicate hole applied */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Remove a hole in a firewall associated with a particular alias
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk. Calling this too often is harmless. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int fwhole = lnk->data.tcp->fwhole; /* Where is the firewall
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(&rule, 0, sizeof rule); /* useless for ipfw2 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Clear out the entire range dedicated to firewall holes. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = la->fireWallBaseNum; i < la->fireWallBaseNum + la->fireWallNumNums; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL, &r, sizeof r));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* XXX: third arg correct here ? /phk */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetFWBase(struct libalias *la, unsigned int base, unsigned int num)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetSkinnyPort(struct libalias *la, unsigned int port)