alias_local.h revision 188294
1/*-
2 * Copyright (c) 2001 Charles Mott <cm@linktel.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/netinet/libalias/alias_local.h 188294 2009-02-07 18:49:42Z piso $
27 */
28
29/*
30 * Alias_local.h contains the function prototypes for alias.c,
31 * alias_db.c, alias_util.c and alias_ftp.c, alias_irc.c (as well
32 * as any future add-ons).  It also includes macros, globals and
33 * struct definitions shared by more than one alias*.c file.
34 *
35 * This include file is intended to be used only within the aliasing
36 * software.  Outside world interfaces are defined in alias.h
37 *
38 * This software is placed into the public domain with no restrictions
39 * on its distribution.
40 *
41 * Initial version:  August, 1996  (cjm)
42 *
43 * <updated several times by original author and Eivind Eklund>
44 */
45
46#ifndef _ALIAS_LOCAL_H_
47#define	_ALIAS_LOCAL_H_
48
49#include <sys/types.h>
50#include <sys/sysctl.h>
51
52#ifdef _KERNEL
53#include <sys/malloc.h>
54#include <sys/param.h>
55#include <sys/lock.h>
56#include <sys/mutex.h>
57
58/* XXX: LibAliasSetTarget() uses this constant. */
59#define	INADDR_NONE	0xffffffff
60
61#include <netinet/libalias/alias_sctp.h>
62#else
63#include "alias_sctp.h"
64#endif
65
66/* Sizes of input and output link tables */
67#define LINK_TABLE_OUT_SIZE        4001
68#define LINK_TABLE_IN_SIZE         4001
69
70struct proxy_entry;
71
72struct libalias {
73	LIST_ENTRY(libalias) instancelist;
74
75	int		packetAliasMode;	/* Mode flags                      */
76	/* - documented in alias.h  */
77
78	struct in_addr	aliasAddress;	/* Address written onto source     */
79	/* field of IP packet.           */
80
81	struct in_addr	targetAddress;	/* IP address incoming packets     */
82	/* are sent to if no aliasing    */
83	/* link already exists           */
84
85	struct in_addr	nullAddress;	/* Used as a dummy parameter for   */
86	/* some function calls           */
87
88			LIST_HEAD     (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
89	/* Lookup table of pointers to     */
90	/* chains of link records. Each  */
91
92			LIST_HEAD     (, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
93	/* link record is doubly indexed */
94	/* into input and output lookup  */
95	/* tables.                       */
96
97	/* Link statistics                 */
98	int		icmpLinkCount;
99	int		udpLinkCount;
100	int		tcpLinkCount;
101	int		pptpLinkCount;
102	int		protoLinkCount;
103	int		fragmentIdLinkCount;
104	int		fragmentPtrLinkCount;
105	int		sockCount;
106
107	int		cleanupIndex;	/* Index to chain of link table    */
108	/* being inspected for old links   */
109
110	int		timeStamp;	/* System time in seconds for      */
111	/* current packet                  */
112
113	int		lastCleanupTime;	/* Last time
114						 * IncrementalCleanup()  */
115	/* was called                      */
116
117	int		deleteAllLinks;	/* If equal to zero, DeleteLink()  */
118	/* will not remove permanent links */
119
120	/* log descriptor        */
121#ifdef  _KERNEL
122	char           *logDesc;
123#else
124	FILE           *logDesc;
125#endif
126	/* statistics monitoring */
127
128	int		newDefaultLink;	/* Indicates if a new aliasing     */
129	/* link has been created after a   */
130	/* call to PacketAliasIn/Out().    */
131
132#ifndef NO_FW_PUNCH
133	int		fireWallFD;	/* File descriptor to be able to   */
134	/* control firewall.  Opened by    */
135	/* PacketAliasSetMode on first     */
136	/* setting the PKT_ALIAS_PUNCH_FW  */
137	/* flag.                           */
138	int		fireWallBaseNum;	/* The first firewall entry
139						 * free for our use */
140	int		fireWallNumNums;	/* How many entries can we
141						 * use? */
142	int		fireWallActiveNum;	/* Which entry did we last
143						 * use? */
144	char           *fireWallField;	/* bool array for entries */
145#endif
146
147	unsigned int	skinnyPort;	/* TCP port used by the Skinny     */
148	/* protocol.                       */
149
150	struct proxy_entry *proxyList;
151
152	struct in_addr	true_addr;	/* in network byte order. */
153	u_short		true_port;	/* in host byte order. */
154
155	/*
156	 * sctp code support
157	 */
158
159	/* counts associations that have progressed to UP and not yet removed */
160	int		sctpLinkCount;
161#ifdef  _KERNEL
162	/* timing queue for keeping track of association timeouts */
163	struct sctp_nat_timer sctpNatTimer;
164
165	/* size of hash table used in this instance */
166	u_int sctpNatTableSize;
167
168/*
169 * local look up table sorted by l_vtag/l_port
170 */
171	LIST_HEAD(sctpNatTableL, sctp_nat_assoc) *sctpTableLocal;
172/*
173 * global look up table sorted by g_vtag/g_port
174 */
175	LIST_HEAD(sctpNatTableG, sctp_nat_assoc) *sctpTableGlobal;
176
177	/*
178	 * avoid races in libalias: every public function has to use it.
179	 */
180	struct mtx mutex;
181#endif
182};
183
184/* Macros */
185
186#ifdef _KERNEL
187#define LIBALIAS_LOCK_INIT(l) \
188        mtx_init(&l->mutex, "per-instance libalias mutex", NULL, MTX_DEF)
189#define LIBALIAS_LOCK_ASSERT(l) mtx_assert(&l->mutex, MA_OWNED)
190#define LIBALIAS_LOCK(l) mtx_lock(&l->mutex)
191#define LIBALIAS_UNLOCK(l) mtx_unlock(&l->mutex)
192#define LIBALIAS_LOCK_DESTROY(l)	mtx_destroy(&l->mutex)
193#else
194#define LIBALIAS_LOCK_INIT(l)
195#define LIBALIAS_LOCK_ASSERT(l)
196#define LIBALIAS_LOCK(l)
197#define LIBALIAS_UNLOCK(l)
198#define LIBALIAS_LOCK_DESTROY(l)
199#endif
200
201/*
202 * The following macro is used to update an
203 * internet checksum.  "delta" is a 32-bit
204 * accumulation of all the changes to the
205 * checksum (adding in new 16-bit words and
206 * subtracting out old words), and "cksum"
207 * is the checksum value to be updated.
208 */
209#define	ADJUST_CHECKSUM(acc, cksum) \
210	do { \
211		acc += cksum; \
212		if (acc < 0) { \
213			acc = -acc; \
214			acc = (acc >> 16) + (acc & 0xffff); \
215			acc += acc >> 16; \
216			cksum = (u_short) ~acc; \
217		} else { \
218			acc = (acc >> 16) + (acc & 0xffff); \
219			acc += acc >> 16; \
220			cksum = (u_short) acc; \
221		} \
222	} while (0)
223
224
225/* Prototypes */
226
227/*
228 * SctpFunction prototypes
229 *
230 */
231void AliasSctpInit(struct libalias *la);
232void AliasSctpTerm(struct libalias *la);
233int SctpAlias(struct libalias *la, struct ip *ip, int direction);
234
235/*
236 * We do not calculate TCP checksums when libalias is a kernel
237 * module, since it has no idea about checksum offloading.
238 * If TCP data has changed, then we just set checksum to zero,
239 * and caller must recalculate it himself.
240 * In case if libalias will edit UDP data, the same approach
241 * should be used.
242 */
243#ifndef _KERNEL
244u_short		IpChecksum(struct ip *_pip);
245u_short		TcpChecksum(struct ip *_pip);
246#endif
247void
248DifferentialChecksum(u_short * _cksum, void * _new, void * _old, int _n);
249
250/* Internal data access */
251struct alias_link *
252FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
253    u_short _id_alias, int _create);
254struct alias_link *
255FindIcmpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
256    u_short _id, int _create);
257struct alias_link *
258FindFragmentIn1(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
259    u_short _ip_id);
260struct alias_link *
261FindFragmentIn2(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
262    u_short _ip_id);
263struct alias_link *
264		AddFragmentPtrLink(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
265struct alias_link *
266		FindFragmentPtr(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
267struct alias_link *
268FindProtoIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
269    u_char _proto);
270struct alias_link *
271FindProtoOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
272    u_char _proto);
273struct alias_link *
274FindUdpTcpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
275    u_short _dst_port, u_short _alias_port, u_char _proto, int _create);
276struct alias_link *
277FindUdpTcpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
278    u_short _src_port, u_short _dst_port, u_char _proto, int _create);
279struct alias_link *
280AddPptp(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
281    struct in_addr _alias_addr, u_int16_t _src_call_id);
282struct alias_link *
283FindPptpOutByCallId(struct libalias *la, struct in_addr _src_addr,
284    struct in_addr _dst_addr, u_int16_t _src_call_id);
285struct alias_link *
286FindPptpInByCallId(struct libalias *la, struct in_addr _dst_addr,
287    struct in_addr _alias_addr, u_int16_t _dst_call_id);
288struct alias_link *
289FindPptpOutByPeerCallId(struct libalias *la, struct in_addr _src_addr,
290    struct in_addr _dst_addr, u_int16_t _dst_call_id);
291struct alias_link *
292FindPptpInByPeerCallId(struct libalias *la, struct in_addr _dst_addr,
293    struct in_addr _alias_addr, u_int16_t _alias_call_id);
294struct alias_link *
295FindRtspOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
296    u_short _src_port, u_short _alias_port, u_char _proto);
297struct in_addr
298		FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
299struct in_addr
300		FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
301struct in_addr
302FindSctpRedirectAddress(struct libalias *la,  struct sctp_nat_msg *sm);
303
304/* External data access/modification */
305int
306FindNewPortGroup(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
307    u_short _src_port, u_short _dst_port, u_short _port_count,
308    u_char _proto, u_char _align);
309void		GetFragmentAddr(struct alias_link *_lnk, struct in_addr *_src_addr);
310void		SetFragmentAddr(struct alias_link *_lnk, struct in_addr _src_addr);
311void		GetFragmentPtr(struct alias_link *_lnk, char **_fptr);
312void		SetFragmentPtr(struct alias_link *_lnk, char *fptr);
313void		SetStateIn(struct alias_link *_lnk, int _state);
314void		SetStateOut(struct alias_link *_lnk, int _state);
315int		GetStateIn (struct alias_link *_lnk);
316int		GetStateOut(struct alias_link *_lnk);
317struct in_addr
318		GetOriginalAddress(struct alias_link *_lnk);
319struct in_addr
320		GetDestAddress(struct alias_link *_lnk);
321struct in_addr
322		GetAliasAddress(struct alias_link *_lnk);
323struct in_addr
324		GetDefaultAliasAddress(struct libalias *la);
325void		SetDefaultAliasAddress(struct libalias *la, struct in_addr _alias_addr);
326u_short		GetOriginalPort(struct alias_link *_lnk);
327u_short		GetAliasPort(struct alias_link *_lnk);
328struct in_addr
329		GetProxyAddress(struct alias_link *_lnk);
330void		SetProxyAddress(struct alias_link *_lnk, struct in_addr _addr);
331u_short		GetProxyPort(struct alias_link *_lnk);
332void		SetProxyPort(struct alias_link *_lnk, u_short _port);
333void		SetAckModified(struct alias_link *_lnk);
334int		GetAckModified(struct alias_link *_lnk);
335int		GetDeltaAckIn(u_long, struct alias_link *_lnk);
336int             GetDeltaSeqOut(u_long, struct alias_link *lnk);
337void            AddSeq(struct alias_link *lnk, int delta, u_int ip_hl,
338		    u_short ip_len, u_long th_seq, u_int th_off);
339void		SetExpire (struct alias_link *_lnk, int _expire);
340void		ClearCheckNewLink(struct libalias *la);
341void		SetProtocolFlags(struct alias_link *_lnk, int _pflags);
342int		GetProtocolFlags(struct alias_link *_lnk);
343void		SetDestCallId(struct alias_link *_lnk, u_int16_t _cid);
344
345#ifndef NO_FW_PUNCH
346void		PunchFWHole(struct alias_link *_lnk);
347
348#endif
349
350/* Housekeeping function */
351void		HouseKeeping(struct libalias *);
352
353/* Tcp specfic routines */
354/* lint -save -library Suppress flexelint warnings */
355
356/* Transparent proxy routines */
357int
358ProxyCheck(struct libalias *la, struct in_addr *proxy_server_addr,
359    u_short * proxy_server_port, struct in_addr src_addr,
360    struct in_addr dst_addr, u_short dst_port, u_char ip_p);
361void
362ProxyModify(struct libalias *la, struct alias_link *_lnk, struct ip *_pip,
363    int _maxpacketsize, int _proxy_type);
364
365enum alias_tcp_state {
366	ALIAS_TCP_STATE_NOT_CONNECTED,
367	ALIAS_TCP_STATE_CONNECTED,
368	ALIAS_TCP_STATE_DISCONNECTED
369};
370
371#if defined(_NETINET_IP_H_)
372static __inline void *
373ip_next(struct ip *iphdr)
374{
375	char *p = (char *)iphdr;
376	return (&p[iphdr->ip_hl * 4]);
377}
378#endif
379
380#if defined(_NETINET_TCP_H_)
381static __inline void *
382tcp_next(struct tcphdr *tcphdr)
383{
384	char *p = (char *)tcphdr;
385	return (&p[tcphdr->th_off * 4]);
386}
387#endif
388
389#if defined(_NETINET_UDP_H_)
390static __inline void *
391udp_next(struct udphdr *udphdr)
392{
393	return ((void *)(udphdr + 1));
394}
395#endif
396
397#endif				/* !_ALIAS_LOCAL_H_ */
398