ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*-
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Copyright (c) 2001 Charles Mott <cm@linktel.net>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * All rights reserved.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Redistribution and use in source and binary forms, with or without
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * modification, are permitted provided that the following conditions
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * are met:
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 *
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 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/cdefs.h>
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#endif
b62055c76a56bd99f88168771d0e32ebfe37dc82vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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
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 fragments.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Initial version: August, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.4: September 16, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Facility for handling incoming links added.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 1.6: September 18, 1996 (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ICMP data handling simplified.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
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
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
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
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Removed K&R style function headers
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync and general cleanup. (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added packetAliasMode to replace compiler #defines's (ee)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Allocates sockets for partially specified
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ports if ALIAS_USE_SOCKETS defined. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 2.0: March, 1997
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetAliasAddress() will now clean up alias links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if the aliasing address is changed. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasPermanentLink() function added to support permanent
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync links. (J. Fortes suggested the need for this.)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Examples:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (192.168.0.2, port 21) <-> alias port 3604, known dest addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync unknown dest port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SetExpire() function added. (cjm)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink() no longer frees memory association with a pointer
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync to a fragment (this bug was first recognized by E. Eklund in
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync v1.9).
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Version 3.2: July, 2000 (salander and satoh)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added FindNewPortGroup to get contiguous range of port values.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link but not actually add one.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Added FindRtspOut, which is closely derived from FindUdpTcpOut,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync except that the alias port (from FindNewPortGroup) is provided
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync as input.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync See HISTORY file for additional revisions.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <machine/stdarg.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/param.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/kernel.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/module.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/syslog.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <stdarg.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <stdlib.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <stdio.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/errno.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/time.h>
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync#include <unistd.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <sys/socket.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <netinet/tcp.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <netinet/libalias/alias.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <netinet/libalias/alias_local.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <netinet/libalias/alias_mod.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <net/if.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include "alias.h"
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include "alias_local.h"
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include "alias_mod.h"
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# include <iprt/assert.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# include "alias.h"
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# include "alias_local.h"
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# include "alias_mod.h"
6de922ee8158732706074aacb20c2a5dc6d4d7a3vboxsync# include <slirp.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Constants (note: constants are also defined
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync near relevant functions or structs)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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_INTERVAL_SECS 64
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define ALIAS_CLEANUP_MAX_SPOKES (LINK_TABLE_OUT_SIZE/5)
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* Timeouts (in seconds) for different link types */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define ICMP_EXPIRE_TIME 60
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define UDP_EXPIRE_TIME 60
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define PROTO_EXPIRE_TIME 60
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define FRAGMENT_ID_EXPIRE_TIME 10
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define FRAGMENT_PTR_EXPIRE_TIME 30
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync
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?) */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifndef TCP_EXPIRE_DEAD
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define TCP_EXPIRE_DEAD 10
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#endif
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link has been used and closed on one side - the other side
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync is allowed to still send data */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifndef TCP_EXPIRE_SINGLEDEAD
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define TCP_EXPIRE_SINGLEDEAD 90
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link isn't yet up */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifndef TCP_EXPIRE_INITIAL
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define TCP_EXPIRE_INITIAL 300
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#endif
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync/* When the link is up */
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifndef TCP_EXPIRE_CONNECTED
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#define TCP_EXPIRE_CONNECTED 86400
29dd92909f1ff66f876231b55ac94e4f0c25100dvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define NO_DEST_PORT 1
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define NO_SRC_PORT 1
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Data Structures
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
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
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.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct ack_data_record { /* used to save changes to ACK/sequence
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_long ack_old;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_long ack_new;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int active;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct tcp_state { /* Information about TCP connection */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int in; /* State for outside -> inside */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int out; /* State for inside -> outside */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int index; /* Index to ACK data array */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int ack_modified; /* Indicates whether ACK and
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * sequence numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* been modified */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define N_LINK_TCP_DATA 3 /* Number of distinct ACK number changes
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * saved for a modified TCP stream */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct tcp_dat {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcp_state state;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ack_data_record ack[N_LINK_TCP_DATA];
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int fwhole; /* Which firewall record is used for this
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * hole? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct server { /* LSNAT server pool (circular list) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link { /* Main data structure */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr src_addr; /* Address and port information */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr proxy_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short proxy_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type; /* Type of link: TCP, UDP, ICMP,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * proto, frag */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* values for link_type */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_ICMP IPPROTO_ICMP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_UDP IPPROTO_UDP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_TCP IPPROTO_TCP
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_FRAGMENT_ID (IPPROTO_MAX + 1)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_FRAGMENT_PTR (IPPROTO_MAX + 2)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_ADDR (IPPROTO_MAX + 3)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_PPTP (IPPROTO_MAX + 4)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int flags; /* indicates special characteristics */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int pflags; /* protocol-specific flags */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* flag bits */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_UNKNOWN_DEST_PORT 0x01
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_UNKNOWN_DEST_ADDR 0x02
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_PERMANENT 0x04
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync#ifndef VBOX
3b53e98860b3ca54c6843fba6c49ea53407cf0a5vboxsync# define LINK_UNFIREWALLED 0x08 /* This macro definition isn't used in this revision of libalias */
3b53e98860b3ca54c6843fba6c49ea53407cf0a5vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int timestamp; /* Time link was last accessed */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int expire_time; /* Expire time for link */
3b53e98860b3ca54c6843fba6c49ea53407cf0a5vboxsync#else /* VBOX */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync unsigned int timestamp; /* Time link was last accessed */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync unsigned int expire_time; /* Expire time for link */
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync#endif
6b757000a5e484b0cf9eeffe05e50efa759b9641vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int sockfd; /* socket descriptor */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync union { /* Auxiliary data */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync char *frag_ptr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr frag_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcp_dat *tcp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } data;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Clean up procedure. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void finishoff(void);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Kernel module definition. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncMALLOC_DEFINE(M_ALIAS, "libalias", "packet aliasing");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncMODULE_VERSION(libalias, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncalias_mod_handler(module_t mod, int type, void *data)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int error;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case MOD_LOAD:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync error = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync handler_chain_init();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case MOD_QUIESCE:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case MOD_UNLOAD:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync handler_chain_destroy();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync finishoff();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync error = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync error = EINVAL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (error);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic moduledata_t alias_mod = {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "alias", alias_mod_handler, NULL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync};
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncDECLARE_MODULE(alias, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Internal utility routines (used only in alias_db.c)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncMiscellaneous:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync SeqDiff() -- difference between two TCP sequences
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ShowAliasStats() -- send alias statistics to a monitor file
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Local prototypes */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_int StartPointIn(struct in_addr, u_short, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncStartPointOut(struct in_addr, struct in_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short, u_short, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int SeqDiff(u_long, u_long);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Firewall control */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void InitPunchFW(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void UninitPunchFW(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void ClearFWHole(struct alias_link *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Log file control */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void ShowAliasStats(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int InitPacketAliasLog(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void UninitPacketAliasLog(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncStartPointIn(struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int n;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n = alias_addr.s_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (link_type != LINK_PPTP)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += alias_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (n % LINK_TABLE_IN_SIZE);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncStartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port, u_short dst_port, int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int n;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n = src_addr.s_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += dst_addr.s_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (link_type != LINK_PPTP) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += dst_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n += link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (n % LINK_TABLE_OUT_SIZE);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSeqDiff(u_long x, u_long y)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Return the difference between two TCP sequence numbers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync This function is encapsulated in case there are any unusual
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync arithmetic conditions that need to be considered.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (ntohl(y) - ntohl(x));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAliasLog(char *str, const char *format, ...)
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_list ap;
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_start(ap, format);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync vsnprintf(str, LIBALIAS_BUF_SIZE, format, ap);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_end(ap);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAliasLog(FILE *stream, const char *format, ...)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_list ap;
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_start(ap, format);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync vfprintf(stream, format, ap);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_end(ap);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fflush(stream);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_list args;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync char buffer[1024];
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync NOREF(stream);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(buffer, 0, 1024);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_start(args, format);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync RTStrPrintfV(buffer, 1024, format, args);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync va_end(args);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*make it grepable */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync Log2(("NAT:ALIAS: %s\n", buffer));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync# endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncShowAliasStats(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Used for debugging */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->logDesc) {
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync int tot = la->icmpLinkCount + la->udpLinkCount +
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->tcpLinkCount + la->pptpLinkCount +
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->protoLinkCount + la->fragmentIdLinkCount +
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentPtrLinkCount;
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync AliasLog(la->logDesc,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->icmpLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->udpLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->tcpLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->pptpLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->protoLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentIdLinkCount,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentPtrLinkCount, tot);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef _KERNEL
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync AliasLog(la->logDesc, " (sock=%u)\n", la->sockCount);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Internal routines for finding, deleting and adding links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncPort Allocation:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetNewPort() -- find and reserve new alias port number
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetSocket() -- try to allocate a socket for a given port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLink search:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkOut() - find link for outgoing packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkIn() - find link for incoming packets
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncPort search:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindNewPortGroup() - find an available group of ports
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Local prototypes */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int GetNewPort(struct libalias *, struct alias_link *, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_short GetSocket(struct libalias *, u_short, int *, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void CleanupAliasData(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void IncrementalCleanup(struct libalias *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void DeleteLink(struct alias_link *);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddLink(struct libalias *, struct in_addr, struct in_addr, struct in_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncReLink(struct alias_link *,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr, struct in_addr, struct in_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkOut (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync FindLinkIn (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define ALIAS_PORT_BASE 0x08000
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define ALIAS_PORT_MASK 0x07fff
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define ALIAS_PORT_MASK_EVEN 0x07ffe
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define GET_NEW_PORT_MAX_ATTEMPTS 20
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define GET_ALIAS_PORT -1
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define GET_ALIAS_ID GET_ALIAS_PORT
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define FIND_EVEN_ALIAS_BASE 1
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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). */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int max_trials;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short port_sys;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short port_net;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync When this parameter is GET_ALIAS_PORT, it indicates to get a randomly
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync selected port number.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (alias_port_param == GET_ALIAS_PORT) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The aliasing port is automatically selected by one of
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * two methods below:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
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 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_net = lnk->src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = ntohs(port_net);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* First trial and all subsequent are random. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys += ALIAS_PORT_BASE;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_net = htons(port_sys);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (alias_port_param >= 0 && alias_port_param < 0x10000) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->alias_port = (u_short) alias_port_param;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/GetNewPort(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "input parameter error\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (-1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Port number search */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < max_trials; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int go_ahead;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *search_result;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_port, port_net,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->link_type, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (search_result == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync go_ahead = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else if (!(lnk->flags & LINK_PARTIALLY_SPECIFIED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync go_ahead = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync go_ahead = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (go_ahead) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && (lnk->flags & LINK_PARTIALLY_SPECIFIED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && ((lnk->link_type == LINK_TCP) ||
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (lnk->link_type == LINK_UDP))) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->alias_port = port_net;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->alias_port = port_net;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys += ALIAS_PORT_BASE;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_net = htons(port_sys);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/GetnewPort(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "could not find free port\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (-1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_short
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int err;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int sock;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct sockaddr_in sock_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (link_type == LINK_TCP)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync sock = socket(AF_INET, SOCK_STREAM, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else if (link_type == LINK_UDP)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync sock = socket(AF_INET, SOCK_DGRAM, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/GetSocket(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "incorrect link type\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (sock < 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/GetSocket(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "socket() error %d\n", *sockfd);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
b62055c76a56bd99f88168771d0e32ebfe37dc82vboxsync
96461dddc5218f3eb8d402a153168f5b51f15504vboxsync memset(&sock_addr, 0, sizeof(struct sockaddr_in));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync sock_addr.sin_family = AF_INET;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
b62055c76a56bd99f88168771d0e32ebfe37dc82vboxsync sock_addr.sin_port = port_net;
0851bca74f2d98e16a0fd26fc1eb731cb492a5aevboxsync#ifdef RT_OS_DARWIN
0851bca74f2d98e16a0fd26fc1eb731cb492a5aevboxsync sock_addr.sin_len = sizeof(struct sockaddr_in);
0851bca74f2d98e16a0fd26fc1eb731cb492a5aevboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
a4706f180d7f34f71a5ff472dcb11012c3e4103avboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync err = bind(sock,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (struct sockaddr *)&sock_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync sizeof(sock_addr));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (err == 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->sockCount++;
00aed0d8f30995d59dcafe83006d6a0c08b662a6vboxsync *sockfd = sock;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
b62055c76a56bd99f88168771d0e32ebfe37dc82vboxsync closesocket(sock);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindNewPortGroup(struct libalias *la,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short port_count,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char align)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i, j;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int max_trials;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short port_sys;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Get link_type from protocol
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (proto) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_UDP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_TCP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * The aliasing port is automatically selected by one of two
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * methods below:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
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 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = ntohs(src_port);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* First trial and all subsequent are random. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (align == FIND_EVEN_ALIAS_BASE)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK_EVEN;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys += ALIAS_PORT_BASE;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Port number search */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < max_trials; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *search_result;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (j = 0; j < port_count; j++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (0 != (search_result = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync dst_port, htons(port_sys + j),
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, 0)))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Found a good range, return base */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (j == port_count)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (htons(port_sys));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Find a new base to try */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (align == FIND_EVEN_ALIAS_BASE)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK_EVEN;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys = arc4random() & ALIAS_PORT_MASK;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync port_sys += ALIAS_PORT_BASE;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/FindNewPortGroup(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "could not find free port(s)\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncCleanupAliasData(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = LIST_FIRST(&la->linkTableOut[i]);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *link_next = LIST_NEXT(lnk, list_out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = link_next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->cleanupIndex = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncIncrementalCleanup(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk, *lnk_tmp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH_SAFE(lnk, &la->linkTableOut[la->cleanupIndex++],
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync list_out, lnk_tmp) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->timeStamp - lnk->timestamp > lnk->expire_time)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->cleanupIndex == LINK_TABLE_OUT_SIZE)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->cleanupIndex = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncDeleteLink(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la = lnk->la;
00a53b4993f57f31afd0e8a21db04ecab34ad9edvboxsync LogFlowFuncEnter();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Don't do anything if the link is marked permanent */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->deleteAllLinks == 0 && lnk->flags & LINK_PERMANENT)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Delete associated firewall hole, if any */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ClearFWHole(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Free memory allocated for LSNAT server pool */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->server != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *head, *curr, *next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync head = curr = lnk->server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync do {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync next = curr->next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(curr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } while ((curr = next) != head);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Adjust output table pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_REMOVE(lnk, list_out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Adjust input table pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_REMOVE(lnk, list_in);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Close socket, if one has been allocated */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->sockfd != -1) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->sockCount--;
b62055c76a56bd99f88168771d0e32ebfe37dc82vboxsync closesocket(lnk->sockfd);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Link-type dependent cleanup */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (lnk->link_type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ICMP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->icmpLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->udpLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->tcpLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(lnk->data.tcp);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_PPTP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->pptpLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_ID:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentIdLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_PTR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentPtrLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.frag_ptr != NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(lnk->data.frag_ptr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ADDR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->protoLinkCount--;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Free memory */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Write statistics, if logging enabled */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_LOG) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ShowAliasStats(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
fec07fa72c074f1768bb40051edb1dc5509fa0e8vboxsync LogFlowFuncLeave();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddLink(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int alias_port_param, /* if less than zero, alias */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{ /* port will be automatically *//* chosen.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * If greater than */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int start_point; /* zero, equal to alias port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = malloc(sizeof(struct alias_link));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Basic initialization */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->la = la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_addr = src_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_addr = dst_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->alias_addr = alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->proxy_addr.s_addr = INADDR_ANY;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_port = src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_port = dst_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->proxy_port = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->server = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->link_type = link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->sockfd = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->pflags = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->timestamp = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Expiration time */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (link_type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ICMP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = ICMP_EXPIRE_TIME;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = UDP_EXPIRE_TIME;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_INITIAL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_PPTP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_PERMANENT; /* no timeout. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_ID:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = FRAGMENT_ID_EXPIRE_TIME;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_PTR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ADDR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = PROTO_EXPIRE_TIME;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Determine alias flags */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_UNKNOWN_DEST_ADDR;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_port == 0)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_UNKNOWN_DEST_PORT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Determine alias port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (GetNewPort(la, lnk, alias_port_param) != 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Link-type dependent initialization */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (link_type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcp_dat *aux_tcp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ICMP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->icmpLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->udpLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp = malloc(sizeof(struct tcp_dat));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (aux_tcp != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->tcpLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->state.index = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->state.ack_modified = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->ack[i].active = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync aux_tcp->fwhole = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp = aux_tcp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/AddLink: ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, " cannot allocate auxiliary TCP data\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_PPTP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->pptpLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_ID:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentIdLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_FRAGMENT_PTR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentPtrLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case LINK_ADDR:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->protoLinkCount++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Set up pointers for output lookup table */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync start_point = StartPointOut(src_addr, dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/AddLink(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "malloc() call failed.\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_LOG) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ShowAliasStats(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncReLink(struct alias_link *old_lnk,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int alias_port_param, /* if less than zero, alias */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{ /* port will be automatically *//* chosen.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * If greater than */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *new_lnk; /* zero, equal to alias port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la = old_lnk->la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync new_lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, alias_port_param,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (new_lnk != NULL &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync old_lnk->link_type == LINK_TCP &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync old_lnk->data.tcp->fwhole > 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PunchFWHole(new_lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink(old_lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (new_lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync_FindLinkOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int replace_partial_links)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->dst_addr.s_addr == dst_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_addr.s_addr == src_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_port == src_port &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_port == dst_port &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->link_type == link_type &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->server == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->timestamp = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Search for partially specified links. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && replace_partial_links) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, la->nullAddress, src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync dst_port, link_type, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, la->nullAddress, src_port, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = ReLink(lnk,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr, dst_addr, lnk->alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, lnk->alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindLinkOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int replace_partial_links)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, replace_partial_links);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
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 * is.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->aliasAddress.s_addr != INADDR_ANY &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr.s_addr == la->aliasAddress.s_addr) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkOut(la, la->nullAddress, dst_addr, src_port, dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, replace_partial_links);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int replace_partial_links)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int flags_in;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int start_point;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk_fully_specified;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk_unknown_all;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk_unknown_dst_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk_unknown_dst_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Initialize pointers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_fully_specified = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_all = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_dst_addr = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_dst_port = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* If either the dest addr or port is unknown, the search
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync loop will have to know about this. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync flags_in = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync flags_in |= LINK_UNKNOWN_DEST_ADDR;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (dst_port == 0)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync flags_in |= LINK_UNKNOWN_DEST_PORT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Search loop */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync start_point = StartPointIn(alias_addr, alias_port, link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int flags;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync flags = flags_in | lnk->flags;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (!(flags & LINK_PARTIALLY_SPECIFIED)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == alias_addr.s_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->alias_port == alias_port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->dst_addr.s_addr == dst_addr.s_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->dst_port == dst_port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->link_type == link_type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_fully_specified = lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if ((flags & LINK_UNKNOWN_DEST_ADDR)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && (flags & LINK_UNKNOWN_DEST_PORT)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == alias_addr.s_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->alias_port == alias_port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->link_type == link_type) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk_unknown_all == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_all = lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (flags & LINK_UNKNOWN_DEST_ADDR) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == alias_addr.s_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->alias_port == alias_port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->link_type == link_type
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->dst_port == dst_port) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk_unknown_dst_addr == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_dst_addr = lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (flags & LINK_UNKNOWN_DEST_PORT) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == alias_addr.s_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->alias_port == alias_port
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->link_type == link_type
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && lnk->dst_addr.s_addr == dst_addr.s_addr) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk_unknown_dst_port == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_unknown_dst_port = lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk_fully_specified != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk_fully_specified->timestamp = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = lnk_fully_specified;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (lnk_unknown_dst_port != NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = lnk_unknown_dst_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else if (lnk_unknown_dst_addr != NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = lnk_unknown_dst_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else if (lnk_unknown_all != NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = lnk_unknown_all;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (replace_partial_links &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (lnk->flags & LINK_PARTIALLY_SPECIFIED || lnk->server != NULL)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr src_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->server != NULL) { /* LSNAT link */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr = lnk->server->addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port = lnk->server->port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->server = lnk->server->next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr = lnk->src_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port = lnk->src_port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = ReLink(lnk,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic struct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindLinkIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int replace_partial_links)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkIn(la, dst_addr, alias_addr, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, replace_partial_links);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
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 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->aliasAddress.s_addr != INADDR_ANY &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_addr.s_addr == la->aliasAddress.s_addr) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = _FindLinkIn(la, dst_addr, la->nullAddress, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, replace_partial_links);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* External routines for finding/adding links
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync-- "external" means outside alias_db.c, but within alias*.c --
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync(prototypes in alias_local.h)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindIcmpIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short id_alias,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int create)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_DEST_PORT, id_alias,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_ICMP, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr target_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync target_addr = FindOriginalAddress(la, alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync id_alias, NO_DEST_PORT, id_alias,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_ICMP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindIcmpOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int create)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync id, NO_DEST_PORT,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_ICMP, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_addr = FindAliasAddress(la, src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync id, NO_DEST_PORT, GET_ALIAS_ID,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_ICMP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentIn1(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short ip_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_DEST_PORT, ip_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_FRAGMENT_ID, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, la->nullAddress, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT, ip_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_FRAGMENT_ID);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentIn2(struct libalias *la, struct in_addr dst_addr, /* Doesn't add a link if
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * one */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr, /* is not found. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short ip_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_DEST_PORT, ip_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_FRAGMENT_ID, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short ip_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return AddLink(la, la->nullAddress, dst_addr, la->nullAddress,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT, ip_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_FRAGMENT_PTR);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindFragmentPtr(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short ip_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return FindLinkIn(la, dst_addr, la->nullAddress,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_DEST_PORT, ip_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_FRAGMENT_PTR, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindProtoIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_DEST_PORT, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync proto, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr target_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync target_addr = FindOriginalAddress(la, alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync proto);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindProtoOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync proto, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_addr = FindAliasAddress(la, src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync proto);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindUdpTcpIn(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int create)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (proto) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_UDP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_TCP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type, create);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr target_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync target_addr = FindOriginalAddress(la, alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, target_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_port, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindUdpTcpOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int create)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (proto) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_UDP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_TCP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type, create);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL && create) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_addr = FindAliasAddress(la, src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, GET_ALIAS_PORT,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddPptp(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int16_t src_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_call_id, 0, GET_ALIAS_PORT,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpOutByCallId(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int16_t src_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->link_type == LINK_PPTP &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_addr.s_addr == src_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_addr.s_addr == dst_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_port == src_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int16_t dst_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->link_type == LINK_PPTP &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_addr.s_addr == src_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_addr.s_addr == dst_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_port == dst_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpInByCallId(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int16_t dst_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = StartPointIn(alias_addr, 0, LINK_PPTP);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_FOREACH(lnk, &la->linkTableIn[i], list_in)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->link_type == LINK_PPTP &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_addr.s_addr == dst_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->alias_addr.s_addr == alias_addr.s_addr &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->dst_port == dst_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int16_t alias_call_id)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync 0 /* any */ , alias_call_id,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_PPTP, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindRtspOut(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (proto) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_UDP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_TCP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (NULL);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, src_addr, dst_addr, src_port, 0, link_type, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync alias_addr = FindAliasAddress(la, src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, 0, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindOriginalAddress(struct libalias *la, struct in_addr alias_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkIn(la, la->nullAddress, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync 0, 0, LINK_ADDR, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->newDefaultLink = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->targetAddress.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else if (la->targetAddress.s_addr == INADDR_NONE)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->aliasAddress.s_addr != INADDR_ANY) ?
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress : alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->targetAddress);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->server != NULL) { /* LSNAT link */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr src_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_addr = lnk->server->addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->server = lnk->server->next;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (lnk->src_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->aliasAddress.s_addr != INADDR_ANY) ?
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress : alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncFindAliasAddress(struct libalias *la, struct in_addr original_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = FindLinkOut(la, original_addr, la->nullAddress,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync 0, 0, LINK_ADDR, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->aliasAddress.s_addr != INADDR_ANY) ?
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress : original_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->aliasAddress.s_addr != INADDR_ANY) ?
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress : original_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* External routines for getting or changing link data
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (external to alias_db.c, but internal to alias*.c)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetFragmentAddr(struct alias_link *lnk, struct in_addr src_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.frag_addr = src_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetFragmentAddr(struct alias_link *lnk, struct in_addr *src_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync *src_addr = lnk->data.frag_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetFragmentPtr(struct alias_link *lnk, char *fptr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.frag_ptr = fptr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetFragmentPtr(struct alias_link *lnk, char **fptr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync *fptr = lnk->data.frag_ptr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetStateIn(struct alias_link *lnk, int state)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP input state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (state) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case ALIAS_TCP_STATE_DISCONNECTED:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_DEAD;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case ALIAS_TCP_STATE_CONNECTED:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_CONNECTED;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync panic("libalias:SetStateIn() unknown state");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync abort();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->state.in = state;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetStateOut(struct alias_link *lnk, int state)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP output state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (state) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case ALIAS_TCP_STATE_DISCONNECTED:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_DEAD;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case ALIAS_TCP_STATE_CONNECTED:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = TCP_EXPIRE_CONNECTED;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync panic("libalias:SetStateOut() unknown state");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync abort();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->state.out = state;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetStateIn(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP input state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->data.tcp->state.in);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetStateOut(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* TCP output state */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->data.tcp->state.out);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetOriginalAddress(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->src_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->la->aliasAddress);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->src_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDestAddress(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->dst_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetAliasAddress(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->alias_addr.s_addr == INADDR_ANY)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->la->aliasAddress);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->alias_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDefaultAliasAddress(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la->aliasAddress);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetDefaultAliasAddress(struct libalias *la, struct in_addr alias_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress = alias_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncu_short
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetOriginalPort(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->src_port);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncu_short
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetAliasPort(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->alias_port);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic u_short
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDestPort(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->dst_port);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetAckModified(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Indicate that ACK numbers have been modified in a TCP connection */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->state.ack_modified = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct in_addr
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetProxyAddress(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->proxy_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetProxyAddress(struct alias_link *lnk, struct in_addr addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->proxy_addr = addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncu_short
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetProxyPort(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->proxy_port);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetProxyPort(struct alias_link *lnk, u_short port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->proxy_port = port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetAckModified(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* See if ACK numbers have been modified */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->data.tcp->state.ack_modified);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDeltaAckIn(struct ip *pip, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcphdr *tc;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int delta, ack_diff_min;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_long ack;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync tc = ip_next(pip);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ack = tc->th_ack;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ack_diff_min = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ack_data_record x;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x = lnk->data.tcp->ack[i];
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (x.active == 1) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int ack_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ack_diff = SeqDiff(x.ack_new, ack);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (ack_diff >= 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (ack_diff_min >= 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (ack_diff < ack_diff_min) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = x.delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ack_diff_min = ack_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = x.delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ack_diff_min = ack_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (delta);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetDeltaSeqOut(struct ip *pip, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcphdr *tc;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int delta, seq_diff_min;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_long seq;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync tc = ip_next(pip);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync seq = tc->th_seq;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync seq_diff_min = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < N_LINK_TCP_DATA; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ack_data_record x;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x = lnk->data.tcp->ack[i];
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (x.active == 1) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int seq_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync seq_diff = SeqDiff(x.ack_old, seq);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (seq_diff >= 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (seq_diff_min >= 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (seq_diff < seq_diff_min) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = x.delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync seq_diff_min = seq_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync delta = x.delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync seq_diff_min = seq_diff;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (delta);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncAddSeq(struct ip *pip, struct alias_link *lnk, int delta)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct tcphdr *tc;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ack_data_record x;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int hlen, tlen, dlen;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync tc = ip_next(pip);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync hlen = (pip->ip_hl + tc->th_off) << 2;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync tlen = ntohs(pip->ip_len);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync dlen = tlen - hlen;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x.ack_old = htonl(ntohl(tc->th_seq) + dlen);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x.delta = delta;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync x.active = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = lnk->data.tcp->state.index;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->ack[i] = x;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i++;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (i == N_LINK_TCP_DATA)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->state.index = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->state.index = i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetExpire(struct alias_link *lnk, int expire)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (expire == 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags &= ~LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (expire == -1) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (expire > 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->expire_time = expire;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/SetExpire(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "error in expire parameter\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncClearCheckNewLink(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->newDefaultLink = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetProtocolFlags(struct alias_link *lnk, int pflags)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->pflags = pflags;;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncGetProtocolFlags(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk->pflags);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncSetDestCallId(struct alias_link *lnk, u_int16_t cid)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la = lnk->la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ReLink(lnk, lnk->src_addr, lnk->dst_addr, lnk->alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->src_port, cid, lnk->alias_port, lnk->link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Miscellaneous Functions
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync HouseKeeping()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync InitPacketAliasLog()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPacketAliasLog()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (prototype in alias_local.h)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncHouseKeeping(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i, n;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifndef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct timeval tv;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct timezone tz;
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#endif
ea79ff4df27672e01fdf0cfce6f35829e257ebedvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
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.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ea79ff4df27672e01fdf0cfce6f35829e257ebedvboxsync#ifndef VBOX
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->timeStamp = time_uptime;
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync gettimeofday(&tv, &tz);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->timeStamp = tv.tv_sec;
713dab9c86f4b5c19571e0c9cadf242af32be5ecvboxsync#endif
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
5d6de9034aa9fda1e16380ac3d7dad1a85d86867vboxsync la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Compute number of spokes (output table link chains) to cover */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n = LINK_TABLE_OUT_SIZE * (la->timeStamp - la->lastCleanupTime);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n /= ALIAS_CLEANUP_INTERVAL_SECS;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Handle different cases */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (n > 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (n > ALIAS_CLEANUP_MAX_SPOKES)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync n = ALIAS_CLEANUP_MAX_SPOKES;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->lastCleanupTime = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < n; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync IncrementalCleanup(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else if (n < 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAlias/HouseKeeping(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "something unexpected in time values\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->lastCleanupTime = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Init the log file and enable logging */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncInitPacketAliasLog(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (~la->packetAliasMode & PKT_ALIAS_LOG) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if ((la->logDesc = malloc(LIBALIAS_BUF_SIZE)))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ;
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if ((la->logDesc = fopen("/var/log/alias.log", "w")))
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync fprintf(la->logDesc, "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
5045ab9ca39fa0b301f4020b7a072406eb0ecea2vboxsync else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (ENOMEM); /* log initialization failed */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
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#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode |= PKT_ALIAS_LOG;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Close the log-file and disable logging. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncUninitPacketAliasLog(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->logDesc) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(la->logDesc);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fclose(la->logDesc);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->logDesc = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode &= ~PKT_ALIAS_LOG;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Outside world interfaces
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync-- "outside world" means other than alias*.c routines --
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectPort()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasAddServer()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectProto()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectAddr()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectDynamic()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasRedirectDelete()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasSetAddress()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasInit()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasUninit()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync PacketAliasSetMode()
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync(prototypes in alias.h)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync*/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Redirection from a specific public addr:port to a
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync private addr:port */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr, u_short dst_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr, u_short alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int link_type;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync switch (proto) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_UDP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_UDP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync case IPPROTO_TCP:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type = LINK_TCP;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync break;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync default:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAliasRedirectPort(): ");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "only TCP and UDP protocols allowed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync goto getout;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync src_port, dst_port, alias_port,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync link_type);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAliasRedirectPort(): "
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncgetout:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Add server to the pool of servers */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr addr, u_short port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int res;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (void)la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync server = malloc(sizeof(struct server));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (server != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *head;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync server->addr = addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync server->port = port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync head = lnk->server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (head == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync server->next = server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct server *s;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (s = head; s->next != head; s = s->next);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync s->next = server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync server->next = head;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->server = server;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (res);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Redirect packets of a given IP protocol from a specific
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync public address to a private address */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectProto(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr dst_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_char proto)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, dst_addr, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync NO_SRC_PORT, NO_DEST_PORT, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync proto);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAliasRedirectProto(): "
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Static address translation */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct alias_link *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr alias_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct alias_link *lnk;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk = AddLink(la, src_addr, la->nullAddress, alias_addr,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync 0, 0, 0,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LINK_ADDR);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk != NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags |= LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "PacketAliasRedirectAddr(): "
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync "call to AddLink() failed\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Mark the aliasing link dynamic */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectDynamic(struct libalias *la, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int res;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (void)la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->flags & LINK_PARTIALLY_SPECIFIED)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->flags &= ~LINK_PERMANENT;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (res);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasRedirectDelete(struct libalias *la, struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* This is a dangerous function to put in the API,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync because an invalid pointer can crash the program. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync DeleteLink(lnk);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetAddress(struct libalias *la, struct in_addr addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync && la->aliasAddress.s_addr != addr.s_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync CleanupAliasData(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress = addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetTarget(struct libalias *la, struct in_addr target_addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->targetAddress = target_addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfinishoff(void)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (!LIST_EMPTY(&instancehead))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LibAliasUninit(LIST_FIRST(&instancehead));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstruct libalias *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasInit(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasInit(PNATState pData, struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct timeval tv;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct timezone tz;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la == NULL) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la = calloc(sizeof *la, 1);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la == NULL)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef _KERNEL /* kernel cleans up on module unload */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (LIST_EMPTY(&instancehead))
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync atexit(finishoff);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#endif /* !VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INSERT_HEAD(&instancehead, la, instancelist);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef VBOX
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->timeStamp = time_uptime;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->lastCleanupTime = time_uptime;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync gettimeofday(&tv, &tz);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->timeStamp = tv.tv_sec;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->lastCleanupTime = tv.tv_sec;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
4dd5020158b69719fd7942ff7b996df2d4535bb4vboxsync#else /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->pData = pData;
5d6de9034aa9fda1e16380ac3d7dad1a85d86867vboxsync la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
5d6de9034aa9fda1e16380ac3d7dad1a85d86867vboxsync la->lastCleanupTime = la->timeStamp;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif /* VBOX */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INIT(&la->linkTableOut[i]);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_INIT(&la->linkTableIn[i]);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_INIT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync CleanupAliasData(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->aliasAddress.s_addr = INADDR_ANY;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->targetAddress.s_addr = INADDR_ANY;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->icmpLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->udpLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->tcpLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->pptpLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->protoLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentIdLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fragmentPtrLinkCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->sockCount = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->cleanupIndex = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode = PKT_ALIAS_SAME_PORTS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync | PKT_ALIAS_USE_SOCKETS
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallFD = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef _KERNEL
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LibAliasRefreshModules();
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasUninit(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync CleanupAliasData(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->deleteAllLinks = 0;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPacketAliasLog(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPunchFW(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIST_REMOVE(la, instancelist);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_DESTROY(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Change mode for some operations */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncunsigned int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetMode(
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la,
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)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int res = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Enable logging? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (flags & mask & PKT_ALIAS_LOG) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Do the enable */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (InitPacketAliasLog(la) == ENOMEM)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync goto getout;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* _Disable_ logging? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (~flags & mask & PKT_ALIAS_LOG) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPacketAliasLog(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Start punching holes in the firewall? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (flags & mask & PKT_ALIAS_PUNCH_FW) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync InitPunchFW(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync } else
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Stop punching holes in the firewall? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync UninitPunchFW(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Other flags can be set/cleared without special action */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = la->packetAliasMode;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncgetout:
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (res);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncint
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasCheckNewLink(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int res;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync res = la->newDefaultLink;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (res);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Firewall include files */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <net/if.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <netinet/ip_fw.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <string.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#include <err.h>
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
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 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic ipfw_insn *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncnext_cmd(ipfw_insn * cmd)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd += F_LEN(cmd);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync bzero(cmd, sizeof(*cmd));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return (cmd);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * A function to fill simple commands of size 1.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * Existing flags are preserved.
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic ipfw_insn *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_cmd(ipfw_insn * cmd, enum ipfw_opcodes opcode, int size,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int flags, u_int16_t arg)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->opcode = opcode;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->len = ((cmd->len | flags) & (F_NOT | F_OR)) | (size & F_LEN_MASK);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->arg1 = arg;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return next_cmd(cmd);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic ipfw_insn *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_ip(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int32_t addr)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ipfw_insn_ip *cmd = (ipfw_insn_ip *) cmd1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->addr.s_addr = addr;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u32), 0, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic ipfw_insn *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_one_port(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int16_t port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ipfw_insn_u16 *cmd = (ipfw_insn_u16 *) cmd1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd->ports[0] = cmd->ports[1] = port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u16), 0, 0);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic int
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncfill_rule(void *buf, int bufsize, int rulenum,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync enum ipfw_opcodes action, int proto,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ip_fw *rule = (struct ip_fw *)buf;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ipfw_insn *cmd = (ipfw_insn *) rule->cmd;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync bzero(buf, bufsize);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync rule->rulenum = rulenum;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_cmd(cmd, O_PROTO, F_INSN_SIZE(ipfw_insn), 0, proto);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_ip(cmd, O_IP_SRC, sa.s_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_one_port(cmd, O_IP_SRCPORT, sp);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_ip(cmd, O_IP_DST, da.s_addr);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync cmd = fill_one_port(cmd, O_IP_DSTPORT, dp);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
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
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync rule->cmd_len = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return ((char *)cmd - (char *)buf);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void ClearAllFWHoles(struct libalias *la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define fw_setfield(la, field, num) \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncdo { \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (field)[(num) - la->fireWallBaseNum] = 1; \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync} /*lint -save -e717 */ while(0)/* lint -restore */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define fw_clrfield(la, field, num) \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncdo { \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync (field)[(num) - la->fireWallBaseNum] = 0; \
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync} /*lint -save -e717 */ while(0)/* lint -restore */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncInitPunchFW(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallField = malloc(la->fireWallNumNums);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->fireWallField) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(la->fireWallField, 0, la->fireWallNumNums);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->fireWallFD < 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ClearAllFWHoles(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallActiveNum = la->fireWallBaseNum;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncUninitPunchFW(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync ClearAllFWHoles(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->fireWallFD >= 0)
ebb89e9be21793fe7a9eba190f805a669f283ac3vboxsync closesocket(la->fireWallFD);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallFD = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->fireWallField)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync free(la->fireWallField);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallField = NULL;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->packetAliasMode &= ~PKT_ALIAS_PUNCH_FW;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Make a certain link go through the firewall */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncPunchFWHole(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int r; /* Result code */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ip_fw rule; /* On-the-fly built rule */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int fwhole; /* Where to punch hole */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la = lnk->la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Don't do anything unless we are asked to */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (!(la->packetAliasMode & PKT_ALIAS_PUNCH_FW) ||
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallFD < 0 ||
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->link_type != LINK_TCP)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(&rule, 0, sizeof rule);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/** Build rule **/
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Find empty slot */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (fwhole = la->fireWallActiveNum;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fwhole < la->fireWallBaseNum + la->fireWallNumNums &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fw_tstfield(la, la->fireWallField, fwhole);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fwhole++);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (fwhole == la->fireWallBaseNum + la->fireWallNumNums) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (fwhole = la->fireWallBaseNum;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fwhole < la->fireWallActiveNum &&
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fw_tstfield(la, la->fireWallField, fwhole);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fwhole++);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (fwhole == la->fireWallActiveNum) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* No rule point empty - we can't punch more holes. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallActiveNum = la->fireWallBaseNum;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifdef LIBALIAS_DEBUG
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fprintf(stderr, "libalias: Unable to create firewall hole!\n");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* Start next search at next position */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallActiveNum = fwhole + 1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /*
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * generate two rules of the form
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync *
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * add fwhole accept tcp from OAddr OPort to DAddr DPort add fwhole
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * accept tcp from DAddr DPort to OAddr OPort
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (GetOriginalPort(lnk) != 0 && GetDestPort(lnk) != 0) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync u_int32_t rulebuf[255];
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync O_ACCEPT, IPPROTO_TCP,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)),
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetDestAddress(lnk), ntohs(GetDestPort(lnk)));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (r)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync O_ACCEPT, IPPROTO_TCP,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetDestAddress(lnk), ntohs(GetDestPort(lnk)),
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (r)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Indicate hole applied */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->fwhole = fwhole;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fw_setfield(la, la->fireWallField, fwhole);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Remove a hole in a firewall associated with a particular alias
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk. Calling this too often is harmless. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncClearFWHole(struct alias_link *lnk)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct libalias *la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la = lnk->la;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (lnk->link_type == LINK_TCP) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int fwhole = lnk->data.tcp->fwhole; /* Where is the firewall
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync * hole? */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ip_fw rule;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (fwhole < 0)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(&rule, 0, sizeof rule); /* useless for ipfw2 */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL,
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync &fwhole, sizeof fwhole));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync fw_clrfield(la, la->fireWallField, fwhole);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync lnk->data.tcp->fwhole = -1;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync/* Clear out the entire range dedicated to firewall holes. */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncstatic void
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncClearAllFWHoles(struct libalias *la)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync struct ip_fw rule; /* On-the-fly built rule */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK_ASSERT(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync if (la->fireWallFD < 0)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync return;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(&rule, 0, sizeof rule);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync for (i = la->fireWallBaseNum; i < la->fireWallBaseNum + la->fireWallNumNums; i++) {
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync int r = i;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL, &r, sizeof r));
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync }
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync /* XXX: third arg correct here ? /phk */
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync memset(la->fireWallField, 0, la->fireWallNumNums);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetFWBase(struct libalias *la, unsigned int base, unsigned int num)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync#ifdef VBOX
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync NOREF(la);
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync NOREF(base);
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync NOREF(num);
f428c820be00a88cb87e3f70f666ca7b3513fd82vboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#ifndef NO_FW_PUNCH
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallBaseNum = base;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->fireWallNumNums = num;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync#endif
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncvoid
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsyncLibAliasSetSkinnyPort(struct libalias *la, unsigned int port)
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync{
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_LOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync la->skinnyPort = port;
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync LIBALIAS_UNLOCK(la);
ae9ed83297460a052aeae98394d473e83aeafd1fvboxsync}