FreeBSD kernel IPv4 code
alias_db.h
Go to the documentation of this file.
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(). */
190static 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 */
221 u_long ack_old;
222 u_long ack_new;
223 int delta;
225};
226
227/* Information about TCP connection */
228struct 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 */
234};
235
236/* Number of distinct ACK number changes
237 * saved for a modified TCP stream */
238#define N_LINK_TCP_DATA 3
239struct tcp_dat {
242 /* Which firewall record is used for this hole? */
244};
245
246/* LSNAT server pool (circular list) */
247struct server {
248 struct in_addr addr;
249 u_short port;
250 struct server *next;
251};
252
253/* Main data structure */
255 struct libalias *la;
256 /* Address and port information */
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 */
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;
296 struct {
297 LIST_ENTRY (alias_link) list;
299 };
300 struct {
302 int time; /* Expire time for link */
304 /* Auxiliary data */
305 union {
306 char *frag_ptr;
308 struct tcp_dat *tcp;
310};
311
312/* Clean up procedure. */
313static void finishoff(void);
314
315/* Internal utility routines (used only in alias_db.c)
316
317Lookup 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
323Miscellaneous:
324 SeqDiff() -- difference between two TCP sequences
325 ShowAliasStats() -- send alias statistics to a monitor file
326*/
327
328/* Local prototypes */
329static struct group_in *
330StartPointIn(struct libalias *, struct in_addr, u_short, int, int);
331static int SeqDiff(u_long, u_long);
332
333#ifndef NO_FW_PUNCH
334/* Firewall control */
335static void InitPunchFW(struct libalias *);
336static void UninitPunchFW(struct libalias *);
337static void ClearFWHole(struct alias_link *);
338
339#endif
340
341/* Log file control */
342static void ShowAliasStats(struct libalias *);
343static int InitPacketAliasLog(struct libalias *);
344static void UninitPacketAliasLog(struct libalias *);
345
346void SctpShowAliasStats(struct libalias *la);
347
348
349/* Splay handling */
350static inline int
351cmp_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}
363SPLAY_PROTOTYPE(splay_out, alias_link, all.out, cmp_out);
364
365static inline int
366cmp_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}
376
377/* Internal routines for finding, deleting and adding links
378
379Port Allocation:
380 GetNewPort() -- find and reserve new alias port number
381 GetSocket() -- try to allocate a socket for a given port
382
383Link 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
390Link search:
391 FindLinkOut() - find link for outgoing packets
392 FindLinkIn() - find link for incoming packets
393
394Port search:
395 FindNewPortGroup() - find an available group of ports
396*/
397
398/* Local prototypes */
399static int GetNewPort(struct libalias *, struct alias_link *, int);
400#ifndef NO_USE_SOCKETS
401static u_short GetSocket(struct libalias *, u_short, int *, int);
402#endif
403static void CleanupAliasData(struct libalias *, int);
404static void CleanupLink(struct libalias *, struct alias_link **, int);
405static void DeleteLink(struct alias_link **, int);
406static struct alias_link *
407UseLink(struct libalias *, struct alias_link *);
408
409static struct alias_link *
411 struct in_addr, struct in_addr, struct in_addr,
412 u_short, u_short, int, int, int);
413
414static struct alias_link *
415FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
416
417static struct alias_link *
418FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
419
420static u_short _RandomPort(struct libalias *la);
421
422#define GET_NEW_PORT_MAX_ATTEMPTS 20
423
424
425#ifndef NO_FW_PUNCH
426
427static void ClearAllFWHoles(struct libalias *la);
428
429#define fw_setfield(la, field, num) \
430do { \
431 (field)[(num) - la->fireWallBaseNum] = 1; \
432} /*lint -save -e717 */ while(0)/* lint -restore */
433
434#define fw_clrfield(la, field, num) \
435do { \
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_ */
SPLAY_PROTOTYPE(splay_out, alias_link, all.out, cmp_out)
static void ClearFWHole(struct alias_link *)
static void UninitPunchFW(struct libalias *)
static int InitPacketAliasLog(struct libalias *)
static void ShowAliasStats(struct libalias *)
static struct alias_link * UseLink(struct libalias *, struct alias_link *)
static void InitPunchFW(struct libalias *)
static void DeleteLink(struct alias_link **, int)
static void CleanupAliasData(struct libalias *, int)
static void ClearAllFWHoles(struct libalias *la)
static void UninitPacketAliasLog(struct libalias *)
void SctpShowAliasStats(struct libalias *la)
Definition: alias_db.c:185
static struct in_addr const ANY_ADDR
Definition: alias_db.h:190
static u_short _RandomPort(struct libalias *la)
static int cmp_out(struct alias_link *a, struct alias_link *b)
Definition: alias_db.h:351
static int cmp_in(struct group_in *a, struct group_in *b)
Definition: alias_db.h:366
static struct alias_link * FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int)
static u_short GetSocket(struct libalias *, u_short, int *, int)
static struct alias_link * FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int)
static void finishoff(void)
static int GetNewPort(struct libalias *, struct alias_link *, int)
static int SeqDiff(u_long, u_long)
static void CleanupLink(struct libalias *, struct alias_link **, int)
#define N_LINK_TCP_DATA
Definition: alias_db.h:238
static struct group_in * StartPointIn(struct libalias *, struct in_addr, u_short, int, int)
static struct alias_link * ReLink(struct alias_link *, struct in_addr, struct in_addr, struct in_addr, u_short, u_short, int, int, int)
#define INADDR_ANY
Definition: in.h:48
u_long ack_new
Definition: alias_db.h:222
u_long ack_old
Definition: alias_db.h:221
u_short alias_port
Definition: alias_local.h:83
struct in_addr alias_addr
Definition: alias_local.h:82
int link_type
Definition: alias_local.h:84
Definition: in.h:83
in_addr_t s_addr
Definition: in.h:84
struct in_addr addr
Definition: alias_db.h:248
u_short port
Definition: alias_db.h:249
struct server * next
Definition: alias_db.h:250
int fwhole
Definition: alias_db.h:243
struct ack_data_record ack[N_LINK_TCP_DATA]
Definition: alias_db.h:241
struct tcp_state state
Definition: alias_db.h:240
int index
Definition: alias_db.h:231
int in
Definition: alias_db.h:229
int out
Definition: alias_db.h:230
int ack_modified
Definition: alias_db.h:233
TAILQ_ENTRY(bbr_sendmap) r_next