The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/libalias/alias_db.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2001 Charles Mott <cm@linktel.net>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30     Alias_db.c encapsulates all data structures used for storing
   31     packet aliasing data.  Other parts of the aliasing software
   32     access data through functions provided in this file.
   33 
   34     Data storage is based on the notion of a "link", which is
   35     established for ICMP echo/reply packets, UDP datagrams and
   36     TCP stream connections.  A link stores the original source
   37     and destination addresses.  For UDP and TCP, it also stores
   38     source and destination port numbers, as well as an alias
   39     port number.  Links are also used to store information about
   40     fragments.
   41 
   42     There is a facility for sweeping through and deleting old
   43     links as new packets are sent through.  A simple timeout is
   44     used for ICMP and UDP links.  TCP links are left alone unless
   45     there is an incomplete connection, in which case the link
   46     can be deleted after a certain amount of time.
   47 
   48     Initial version: August, 1996  (cjm)
   49 
   50     Version 1.4: September 16, 1996 (cjm)
   51         Facility for handling incoming links added.
   52 
   53     Version 1.6: September 18, 1996 (cjm)
   54         ICMP data handling simplified.
   55 
   56     Version 1.7: January 9, 1997 (cjm)
   57         Fragment handling simplified.
   58         Saves pointers for unresolved fragments.
   59         Permits links for unspecified remote ports
   60           or unspecified remote addresses.
   61         Fixed bug which did not properly zero port
   62           table entries after a link was deleted.
   63         Cleaned up some obsolete comments.
   64 
   65     Version 1.8: January 14, 1997 (cjm)
   66         Fixed data type error in StartPoint().
   67         (This error did not exist prior to v1.7
   68         and was discovered and fixed by Ari Suutari)
   69 
   70     Version 1.9: February 1, 1997
   71         Optionally, connections initiated from packet aliasing host
   72         machine will will not have their port number aliased unless it
   73         conflicts with an aliasing port already being used. (cjm)
   74 
   75         All options earlier being #ifdef'ed are now available through
   76         a new interface, SetPacketAliasMode().  This allows run time
   77         control (which is now available in PPP+pktAlias through the
   78         'alias' keyword). (ee)
   79 
   80         Added ability to create an alias port without
   81         either destination address or port specified.
   82         port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
   83 
   84         Removed K&R style function headers
   85         and general cleanup. (ee)
   86 
   87         Added packetAliasMode to replace compiler #defines's (ee)
   88 
   89         Allocates sockets for partially specified
   90         ports if ALIAS_USE_SOCKETS defined. (cjm)
   91 
   92     Version 2.0: March, 1997
   93         SetAliasAddress() will now clean up alias links
   94         if the aliasing address is changed. (cjm)
   95 
   96         PacketAliasPermanentLink() function added to support permanent
   97         links.  (J. Fortes suggested the need for this.)
   98         Examples:
   99 
  100         (192.168.0.1, port 23)  <-> alias port 6002, unknown dest addr/port
  101 
  102         (192.168.0.2, port 21)  <-> alias port 3604, known dest addr
  103                                                      unknown dest port
  104 
  105         These permanent links allow for incoming connections to
  106         machines on the local network.  They can be given with a
  107         user-chosen amount of specificity, with increasing specificity
  108         meaning more security. (cjm)
  109 
  110         Quite a bit of rework to the basic engine.  The portTable[]
  111         array, which kept track of which ports were in use was replaced
  112         by a table/linked list structure. (cjm)
  113 
  114         SetExpire() function added. (cjm)
  115 
  116         DeleteLink() no longer frees memory association with a pointer
  117         to a fragment (this bug was first recognized by E. Eklund in
  118         v1.9).
  119 
  120     Version 2.1: May, 1997 (cjm)
  121         Packet aliasing engine reworked so that it can handle
  122         multiple external addresses rather than just a single
  123         host address.
  124 
  125         PacketAliasRedirectPort() and PacketAliasRedirectAddr()
  126         added to the API.  The first function is a more generalized
  127         version of PacketAliasPermanentLink().  The second function
  128         implements static network address translation.
  129 
  130     Version 3.2: July, 2000 (salander and satoh)
  131         Added FindNewPortGroup to get contiguous range of port values.
  132 
  133         Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing
  134         link but not actually add one.
  135 
  136         Added FindRtspOut, which is closely derived from FindUdpTcpOut,
  137         except that the alias port (from FindNewPortGroup) is provided
  138         as input.
  139 
  140     See HISTORY file for additional revisions.
  141 */
  142 
  143 #ifndef _ALIAS_DB_H_
  144 #define _ALIAS_DB_H_
  145 
  146 
  147 /*
  148    Constants (note: constants are also defined
  149               near relevant functions or structs)
  150 */
  151 
  152 /* Timeouts (in seconds) for different link types */
  153 #define ICMP_EXPIRE_TIME             60
  154 #define UDP_EXPIRE_TIME              60
  155 #define PROTO_EXPIRE_TIME            60
  156 #define FRAGMENT_ID_EXPIRE_TIME      10
  157 #define FRAGMENT_PTR_EXPIRE_TIME     30
  158 
  159 /* TCP link expire time for different cases */
  160 /* When the link has been used and closed - minimal grace time to
  161    allow ACKs and potential re-connect in FTP (XXX - is this allowed?)  */
  162 #ifndef TCP_EXPIRE_DEAD
  163 #define TCP_EXPIRE_DEAD           10
  164 #endif
  165 
  166 /* When the link has been used and closed on one side - the other side
  167    is allowed to still send data */
  168 #ifndef TCP_EXPIRE_SINGLEDEAD
  169 #define TCP_EXPIRE_SINGLEDEAD     90
  170 #endif
  171 
  172 /* When the link isn't yet up */
  173 #ifndef TCP_EXPIRE_INITIAL
  174 #define TCP_EXPIRE_INITIAL       300
  175 #endif
  176 
  177 /* When the link is up */
  178 #ifndef TCP_EXPIRE_CONNECTED
  179 #define TCP_EXPIRE_CONNECTED   86400
  180 #endif
  181 
  182 /* Dummy port number codes used for FindLinkIn/Out() and AddLink().
  183    These constants can be anything except zero, which indicates an
  184    unknown port number. */
  185 
  186 #define NO_DEST_PORT     1
  187 #define NO_SRC_PORT      1
  188 
  189 /* Matches any/unknown address in FindLinkIn/Out() and AddLink(). */
  190 static struct in_addr const ANY_ADDR = { INADDR_ANY };
  191 
  192 /* Data Structures
  193 
  194     The fundamental data structure used in this program is
  195     "struct alias_link".  Whenever a TCP connection is made,
  196     a UDP datagram is sent out, or an ICMP echo request is made,
  197     a link record is made (if it has not already been created).
  198     The link record is identified by the source address/port
  199     and the destination address/port. In the case of an ICMP
  200     echo request, the source port is treated as being equivalent
  201     with the 16-bit ID number of the ICMP packet.
  202 
  203     The link record also can store some auxiliary data.  For
  204     TCP connections that have had sequence and acknowledgment
  205     modifications, data space is available to track these changes.
  206     A state field is used to keep track in changes to the TCP
  207     connection state.  ID numbers of fragments can also be
  208     stored in the auxiliary space.  Pointers to unresolved
  209     fragments can also be stored.
  210 
  211     The link records support two independent chainings.  Lookup
  212     tables for input and out tables hold the initial pointers
  213     the link chains.  On input, the lookup table indexes on alias
  214     port and link type.  On output, the lookup table indexes on
  215     source address, destination address, source port, destination
  216     port and link type.
  217 */
  218 
  219 /* used to save changes to ACK/sequence numbers */
  220 struct ack_data_record {
  221         u_long          ack_old;
  222         u_long          ack_new;
  223         int             delta;
  224         int             active;
  225 };
  226 
  227 /* Information about TCP connection */
  228 struct tcp_state {
  229         int             in;     /* State for outside -> inside */
  230         int             out;    /* State for inside  -> outside */
  231         int             index;  /* Index to ACK data array */
  232         /* Indicates whether ACK and sequence numbers been modified */
  233         int             ack_modified;
  234 };
  235 
  236 /* Number of distinct ACK number changes
  237  * saved for a modified TCP stream */
  238 #define N_LINK_TCP_DATA   3
  239 struct tcp_dat {
  240         struct tcp_state state;
  241         struct ack_data_record ack[N_LINK_TCP_DATA];
  242         /* Which firewall record is used for this hole? */
  243         int             fwhole;
  244 };
  245 
  246 /* LSNAT server pool (circular list) */
  247 struct server {
  248         struct in_addr  addr;
  249         u_short         port;
  250         struct server  *next;
  251 };
  252 
  253 /* Main data structure */
  254 struct alias_link {
  255         struct libalias *la;
  256         /* Address and port information */
  257         struct in_addr  src_addr;
  258         struct in_addr  dst_addr;
  259         struct in_addr  alias_addr;
  260         struct in_addr  proxy_addr;
  261         u_short         src_port;
  262         u_short         dst_port;
  263         u_short         alias_port;
  264         u_short         proxy_port;
  265         struct server  *server;
  266         /* Type of link: TCP, UDP, ICMP, proto, frag */
  267         int             link_type;
  268 /* values for link_type */
  269 #define LINK_ICMP                     IPPROTO_ICMP
  270 #define LINK_UDP                      IPPROTO_UDP
  271 #define LINK_TCP                      IPPROTO_TCP
  272 #define LINK_FRAGMENT_ID              (IPPROTO_MAX + 1)
  273 #define LINK_FRAGMENT_PTR             (IPPROTO_MAX + 2)
  274 #define LINK_ADDR                     (IPPROTO_MAX + 3)
  275 #define LINK_PPTP                     (IPPROTO_MAX + 4)
  276 
  277         int             flags;  /* indicates special characteristics */
  278         int             pflags; /* protocol-specific flags */
  279 /* flag bits */
  280 #define LINK_UNKNOWN_DEST_PORT     0x01
  281 #define LINK_UNKNOWN_DEST_ADDR     0x02
  282 #define LINK_PERMANENT             0x04
  283 #define LINK_PARTIALLY_SPECIFIED   0x03 /* logical-or of first two bits */
  284 #define LINK_UNFIREWALLED          0x08
  285 
  286         int             timestamp;      /* Time link was last accessed */
  287 #ifndef NO_USE_SOCKETS
  288         int             sockfd;         /* socket descriptor */
  289 #endif
  290         /* Linked list of pointers for input and output lookup tables  */
  291         union {
  292                 struct {
  293                         SPLAY_ENTRY(alias_link) out;
  294                         LIST_ENTRY (alias_link) in;
  295                 } all;
  296                 struct {
  297                         LIST_ENTRY (alias_link) list;
  298                 } pptp;
  299         };
  300         struct {
  301                 TAILQ_ENTRY(alias_link) list;
  302                 int     time;   /* Expire time for link */
  303         } expire;
  304         /* Auxiliary data */
  305         union {
  306                 char           *frag_ptr;
  307                 struct in_addr  frag_addr;
  308                 struct tcp_dat *tcp;
  309         } data;
  310 };
  311 
  312 /* Clean up procedure. */
  313 static void finishoff(void);
  314 
  315 /* Internal utility routines (used only in alias_db.c)
  316 
  317 Lookup table starting points:
  318     StartPointIn()           -- link table initial search point for
  319                                 incoming packets
  320     StartPointOut()          -- link table initial search point for
  321                                 outgoing packets
  322 
  323 Miscellaneous:
  324     SeqDiff()                -- difference between two TCP sequences
  325     ShowAliasStats()         -- send alias statistics to a monitor file
  326 */
  327 
  328 /* Local prototypes */
  329 static struct group_in *
  330 StartPointIn(struct libalias *, struct in_addr, u_short, int, int);
  331 static int      SeqDiff(u_long, u_long);
  332 
  333 #ifndef NO_FW_PUNCH
  334 /* Firewall control */
  335 static void     InitPunchFW(struct libalias *);
  336 static void     UninitPunchFW(struct libalias *);
  337 static void     ClearFWHole(struct alias_link *);
  338 
  339 #endif
  340 
  341 /* Log file control */
  342 static void     ShowAliasStats(struct libalias *);
  343 static int      InitPacketAliasLog(struct libalias *);
  344 static void     UninitPacketAliasLog(struct libalias *);
  345 
  346 void            SctpShowAliasStats(struct libalias *la);
  347 
  348 
  349 /* Splay handling */
  350 static inline int
  351 cmp_out(struct alias_link *a, struct alias_link *b) {
  352         int i = a->src_port - b->src_port;
  353         if (i != 0) return (i);
  354         if (a->src_addr.s_addr > b->src_addr.s_addr) return (1);
  355         if (a->src_addr.s_addr < b->src_addr.s_addr) return (-1);
  356         if (a->dst_addr.s_addr > b->dst_addr.s_addr) return (1);
  357         if (a->dst_addr.s_addr < b->dst_addr.s_addr) return (-1);
  358         i = a->dst_port - b->dst_port;
  359         if (i != 0) return (i);
  360         i = a->link_type - b->link_type;
  361         return (i);
  362 }
  363 SPLAY_PROTOTYPE(splay_out, alias_link, all.out, cmp_out);
  364 
  365 static inline int
  366 cmp_in(struct group_in *a, struct group_in *b) {
  367         int i = a->alias_port - b->alias_port;
  368         if (i != 0) return (i);
  369         i = a->link_type - b->link_type;
  370         if (i != 0) return (i);
  371         if (a->alias_addr.s_addr > b->alias_addr.s_addr) return (1);
  372         if (a->alias_addr.s_addr < b->alias_addr.s_addr) return (-1);
  373         return (0);
  374 }
  375 SPLAY_PROTOTYPE(splay_in, group_in, in, cmp_in);
  376 
  377 /* Internal routines for finding, deleting and adding links
  378 
  379 Port Allocation:
  380     GetNewPort()             -- find and reserve new alias port number
  381     GetSocket()              -- try to allocate a socket for a given port
  382 
  383 Link creation and deletion:
  384     CleanupAliasData()      - remove all link chains from lookup table
  385     CleanupLink()           - look for a stale link
  386     DeleteLink()            - remove link
  387     AddLink()               - add link
  388     ReLink()                - change link
  389 
  390 Link search:
  391     FindLinkOut()           - find link for outgoing packets
  392     FindLinkIn()            - find link for incoming packets
  393 
  394 Port search:
  395     FindNewPortGroup()      - find an available group of ports
  396 */
  397 
  398 /* Local prototypes */
  399 static int      GetNewPort(struct libalias *, struct alias_link *, int);
  400 #ifndef NO_USE_SOCKETS
  401 static u_short  GetSocket(struct libalias *, u_short, int *, int);
  402 #endif
  403 static void     CleanupAliasData(struct libalias *, int);
  404 static void     CleanupLink(struct libalias *, struct alias_link **, int);
  405 static void     DeleteLink(struct alias_link **, int);
  406 static struct alias_link *
  407 UseLink(struct libalias *, struct alias_link *);
  408 
  409 static struct alias_link *
  410 ReLink(struct alias_link *,
  411     struct in_addr, struct in_addr, struct in_addr,
  412     u_short, u_short, int, int, int);
  413 
  414 static struct alias_link *
  415 FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
  416 
  417 static struct alias_link *
  418 FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
  419 
  420 static u_short _RandomPort(struct libalias *la);
  421 
  422 #define GET_NEW_PORT_MAX_ATTEMPTS       20
  423 
  424 
  425 #ifndef NO_FW_PUNCH
  426 
  427 static void ClearAllFWHoles(struct libalias *la);
  428 
  429 #define fw_setfield(la, field, num)                     \
  430 do {                                            \
  431     (field)[(num) - la->fireWallBaseNum] = 1;           \
  432 } /*lint -save -e717 */ while(0)/* lint -restore */
  433 
  434 #define fw_clrfield(la, field, num)                     \
  435 do {                                                    \
  436     (field)[(num) - la->fireWallBaseNum] = 0;           \
  437 } /*lint -save -e717 */ while(0)/* lint -restore */
  438 
  439 #define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
  440 
  441 #endif /* !NO_FW_PUNCH */
  442 
  443 #endif /* _ALIAS_DB_H_ */

Cache object: 991ee1714b20a9c4b730b31747ac28a2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.