Deleted Added
full compact
alias_db.c (124621) alias_db.c (127094)
1/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */
2
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 unchanged lines hidden (view full) ---

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#include <sys/cdefs.h>
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

--- 11 unchanged lines hidden (view full) ---

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
27#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_db.c 124621 2004-01-17 10:52:21Z phk $");
28__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias_db.c 127094 2004-03-16 21:30:41Z des $");
31
32/*
33 Alias_db.c encapsulates all data structures used for storing
34 packet aliasing data. Other parts of the aliasing software
35 access data through functions provided in this file.
36
37 Data storage is based on the notion of a "link", which is
38 established for ICMP echo/reply packets, UDP datagrams and

--- 123 unchanged lines hidden (view full) ---

162#include <netinet/ip.h>
163#include <netinet/tcp.h>
164#include <arpa/inet.h>
165
166#include "alias.h"
167#include "alias_local.h"
168
169
29
30/*
31 Alias_db.c encapsulates all data structures used for storing
32 packet aliasing data. Other parts of the aliasing software
33 access data through functions provided in this file.
34
35 Data storage is based on the notion of a "link", which is
36 established for ICMP echo/reply packets, UDP datagrams and

--- 123 unchanged lines hidden (view full) ---

160#include <netinet/ip.h>
161#include <netinet/tcp.h>
162#include <arpa/inet.h>
163
164#include "alias.h"
165#include "alias_local.h"
166
167
170static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
168static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
171
172
173/*
174 Constants (note: constants are also defined
175 near relevant functions or structs)
176*/
177
178/* Parameters used for cleanup of expired links */

--- 6 unchanged lines hidden (view full) ---

185#define PROTO_EXPIRE_TIME 60
186#define FRAGMENT_ID_EXPIRE_TIME 10
187#define FRAGMENT_PTR_EXPIRE_TIME 30
188
189/* TCP link expire time for different cases */
190/* When the link has been used and closed - minimal grace time to
191 allow ACKs and potential re-connect in FTP (XXX - is this allowed?) */
192#ifndef TCP_EXPIRE_DEAD
169
170
171/*
172 Constants (note: constants are also defined
173 near relevant functions or structs)
174*/
175
176/* Parameters used for cleanup of expired links */

--- 6 unchanged lines hidden (view full) ---

183#define PROTO_EXPIRE_TIME 60
184#define FRAGMENT_ID_EXPIRE_TIME 10
185#define FRAGMENT_PTR_EXPIRE_TIME 30
186
187/* TCP link expire time for different cases */
188/* When the link has been used and closed - minimal grace time to
189 allow ACKs and potential re-connect in FTP (XXX - is this allowed?) */
190#ifndef TCP_EXPIRE_DEAD
193# define TCP_EXPIRE_DEAD 10
191#define TCP_EXPIRE_DEAD 10
194#endif
195
196/* When the link has been used and closed on one side - the other side
197 is allowed to still send data */
198#ifndef TCP_EXPIRE_SINGLEDEAD
192#endif
193
194/* When the link has been used and closed on one side - the other side
195 is allowed to still send data */
196#ifndef TCP_EXPIRE_SINGLEDEAD
199# define TCP_EXPIRE_SINGLEDEAD 90
197#define TCP_EXPIRE_SINGLEDEAD 90
200#endif
201
202/* When the link isn't yet up */
203#ifndef TCP_EXPIRE_INITIAL
198#endif
199
200/* When the link isn't yet up */
201#ifndef TCP_EXPIRE_INITIAL
204# define TCP_EXPIRE_INITIAL 300
202#define TCP_EXPIRE_INITIAL 300
205#endif
206
207/* When the link is up */
208#ifndef TCP_EXPIRE_CONNECTED
203#endif
204
205/* When the link is up */
206#ifndef TCP_EXPIRE_CONNECTED
209# define TCP_EXPIRE_CONNECTED 86400
207#define TCP_EXPIRE_CONNECTED 86400
210#endif
211
212
213/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
214 These constants can be anything except zero, which indicates an
215 unknown port number. */
216
217#define NO_DEST_PORT 1

--- 23 unchanged lines hidden (view full) ---

241 The link records support two independent chainings. Lookup
242 tables for input and out tables hold the initial pointers
243 the link chains. On input, the lookup table indexes on alias
244 port and link type. On output, the lookup table indexes on
245 source address, destination address, source port, destination
246 port and link type.
247*/
248
208#endif
209
210
211/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
212 These constants can be anything except zero, which indicates an
213 unknown port number. */
214
215#define NO_DEST_PORT 1

--- 23 unchanged lines hidden (view full) ---

239 The link records support two independent chainings. Lookup
240 tables for input and out tables hold the initial pointers
241 the link chains. On input, the lookup table indexes on alias
242 port and link type. On output, the lookup table indexes on
243 source address, destination address, source port, destination
244 port and link type.
245*/
246
249struct ack_data_record /* used to save changes to ACK/sequence numbers */
250{
251 u_long ack_old;
252 u_long ack_new;
253 int delta;
254 int active;
247struct ack_data_record { /* used to save changes to ACK/sequence
248 * numbers */
249 u_long ack_old;
250 u_long ack_new;
251 int delta;
252 int active;
255};
256
253};
254
257struct tcp_state /* Information about TCP connection */
258{
259 int in; /* State for outside -> inside */
260 int out; /* State for inside -> outside */
261 int index; /* Index to ACK data array */
262 int ack_modified; /* Indicates whether ACK and sequence numbers */
263 /* been modified */
255struct tcp_state { /* Information about TCP connection */
256 int in; /* State for outside -> inside */
257 int out; /* State for inside -> outside */
258 int index; /* Index to ACK data array */
259 int ack_modified; /* Indicates whether ACK and
260 * sequence numbers */
261 /* been modified */
264};
265
262};
263
266#define N_LINK_TCP_DATA 3 /* Number of distinct ACK number changes
267 saved for a modified TCP stream */
268struct tcp_dat
269{
270 struct tcp_state state;
271 struct ack_data_record ack[N_LINK_TCP_DATA];
272 int fwhole; /* Which firewall record is used for this hole? */
264#define N_LINK_TCP_DATA 3 /* Number of distinct ACK number changes
265 * saved for a modified TCP stream */
266struct tcp_dat {
267 struct tcp_state state;
268 struct ack_data_record ack[N_LINK_TCP_DATA];
269 int fwhole; /* Which firewall record is used for this
270 * hole? */
273};
274
271};
272
275struct server /* LSNAT server pool (circular list) */
276{
277 struct in_addr addr;
278 u_short port;
279 struct server *next;
273struct server { /* LSNAT server pool (circular list) */
274 struct in_addr addr;
275 u_short port;
276 struct server *next;
280};
281
277};
278
282struct alias_link /* Main data structure */
283{
284 struct libalias *la;
285 struct in_addr src_addr; /* Address and port information */
286 struct in_addr dst_addr;
287 struct in_addr alias_addr;
288 struct in_addr proxy_addr;
289 u_short src_port;
290 u_short dst_port;
291 u_short alias_port;
292 u_short proxy_port;
293 struct server *server;
279struct alias_link { /* Main data structure */
280 struct libalias *la;
281 struct in_addr src_addr; /* Address and port information */
282 struct in_addr dst_addr;
283 struct in_addr alias_addr;
284 struct in_addr proxy_addr;
285 u_short src_port;
286 u_short dst_port;
287 u_short alias_port;
288 u_short proxy_port;
289 struct server *server;
294
290
295 int link_type; /* Type of link: TCP, UDP, ICMP, proto, frag */
291 int link_type; /* Type of link: TCP, UDP, ICMP,
292 * proto, frag */
296
297/* values for link_type */
298#define LINK_ICMP IPPROTO_ICMP
299#define LINK_UDP IPPROTO_UDP
300#define LINK_TCP IPPROTO_TCP
301#define LINK_FRAGMENT_ID (IPPROTO_MAX + 1)
302#define LINK_FRAGMENT_PTR (IPPROTO_MAX + 2)
303#define LINK_ADDR (IPPROTO_MAX + 3)
304#define LINK_PPTP (IPPROTO_MAX + 4)
305
293
294/* values for link_type */
295#define LINK_ICMP IPPROTO_ICMP
296#define LINK_UDP IPPROTO_UDP
297#define LINK_TCP IPPROTO_TCP
298#define LINK_FRAGMENT_ID (IPPROTO_MAX + 1)
299#define LINK_FRAGMENT_PTR (IPPROTO_MAX + 2)
300#define LINK_ADDR (IPPROTO_MAX + 3)
301#define LINK_PPTP (IPPROTO_MAX + 4)
302
306 int flags; /* indicates special characteristics */
307 int pflags; /* protocol-specific flags */
303 int flags; /* indicates special characteristics */
304 int pflags; /* protocol-specific flags */
308
309/* flag bits */
310#define LINK_UNKNOWN_DEST_PORT 0x01
311#define LINK_UNKNOWN_DEST_ADDR 0x02
312#define LINK_PERMANENT 0x04
305
306/* flag bits */
307#define LINK_UNKNOWN_DEST_PORT 0x01
308#define LINK_UNKNOWN_DEST_ADDR 0x02
309#define LINK_PERMANENT 0x04
313#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */
310#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */
314#define LINK_UNFIREWALLED 0x08
315
311#define LINK_UNFIREWALLED 0x08
312
316 int timestamp; /* Time link was last accessed */
317 int expire_time; /* Expire time for link */
313 int timestamp; /* Time link was last accessed */
314 int expire_time; /* Expire time for link */
318
315
319 int sockfd; /* socket descriptor */
316 int sockfd; /* socket descriptor */
320
317
321 LIST_ENTRY(alias_link) list_out; /* Linked list of pointers for */
322 LIST_ENTRY(alias_link) list_in; /* input and output lookup tables */
318 LIST_ENTRY (alias_link) list_out; /* Linked list of
319 * pointers for */
320 LIST_ENTRY (alias_link) list_in; /* input and output
321 * lookup tables */
323
322
324 union /* Auxiliary data */
325 {
326 char *frag_ptr;
327 struct in_addr frag_addr;
328 struct tcp_dat *tcp;
329 } data;
323 union { /* Auxiliary data */
324 char *frag_ptr;
325 struct in_addr frag_addr;
326 struct tcp_dat *tcp;
327 } data;
330};
331
332/* Internal utility routines (used only in alias_db.c)
333
334Lookup table starting points:
335 StartPointIn() -- link table initial search point for
336 incoming packets
337 StartPointOut() -- link table initial search point for
338 outgoing packets
339
340Miscellaneous:
341 SeqDiff() -- difference between two TCP sequences
342 ShowAliasStats() -- send alias statistics to a monitor file
343*/
344
345
346/* Local prototypes */
328};
329
330/* Internal utility routines (used only in alias_db.c)
331
332Lookup table starting points:
333 StartPointIn() -- link table initial search point for
334 incoming packets
335 StartPointOut() -- link table initial search point for
336 outgoing packets
337
338Miscellaneous:
339 SeqDiff() -- difference between two TCP sequences
340 ShowAliasStats() -- send alias statistics to a monitor file
341*/
342
343
344/* Local prototypes */
347static u_int StartPointIn(struct in_addr, u_short, int);
345static u_int StartPointIn(struct in_addr, u_short, int);
348
346
349static u_int StartPointOut(struct in_addr, struct in_addr,
350 u_short, u_short, int);
347static u_int
348StartPointOut(struct in_addr, struct in_addr,
349 u_short, u_short, int);
351
350
352static int SeqDiff(u_long, u_long);
351static int SeqDiff(u_long, u_long);
353
352
354static void ShowAliasStats(struct libalias *);
353static void ShowAliasStats(struct libalias *);
355
356#ifndef NO_FW_PUNCH
357/* Firewall control */
354
355#ifndef NO_FW_PUNCH
356/* Firewall control */
358static void InitPunchFW(struct libalias *la);
359static void UninitPunchFW(struct libalias *la);
360static void ClearFWHole(struct alias_link *link);
357static void InitPunchFW(struct libalias *la);
358static void UninitPunchFW(struct libalias *la);
359static void ClearFWHole(struct alias_link *link);
360
361#endif
362
363/* Log file control */
361#endif
362
363/* Log file control */
364static void InitPacketAliasLog(struct libalias *la);
365static void UninitPacketAliasLog(struct libalias *la);
364static void InitPacketAliasLog(struct libalias *la);
365static void UninitPacketAliasLog(struct libalias *la);
366
366
367static u_int
367static u_int
368StartPointIn(struct in_addr alias_addr,
368StartPointIn(struct in_addr alias_addr,
369 u_short alias_port,
370 int link_type)
369 u_short alias_port,
370 int link_type)
371{
371{
372 u_int n;
372 u_int n;
373
373
374 n = alias_addr.s_addr;
375 if (link_type != LINK_PPTP)
376 n += alias_port;
377 n += link_type;
378 return(n % LINK_TABLE_IN_SIZE);
374 n = alias_addr.s_addr;
375 if (link_type != LINK_PPTP)
376 n += alias_port;
377 n += link_type;
378 return (n % LINK_TABLE_IN_SIZE);
379}
380
381
379}
380
381
382static u_int
382static u_int
383StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
383StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
384 u_short src_port, u_short dst_port, int link_type)
384 u_short src_port, u_short dst_port, int link_type)
385{
385{
386 u_int n;
386 u_int n;
387
387
388 n = src_addr.s_addr;
389 n += dst_addr.s_addr;
390 if (link_type != LINK_PPTP) {
391 n += src_port;
392 n += dst_port;
393 }
394 n += link_type;
388 n = src_addr.s_addr;
389 n += dst_addr.s_addr;
390 if (link_type != LINK_PPTP) {
391 n += src_port;
392 n += dst_port;
393 }
394 n += link_type;
395
395
396 return(n % LINK_TABLE_OUT_SIZE);
396 return (n % LINK_TABLE_OUT_SIZE);
397}
398
399
400static int
401SeqDiff(u_long x, u_long y)
402{
403/* Return the difference between two TCP sequence numbers */
404
405/*
406 This function is encapsulated in case there are any unusual
407 arithmetic conditions that need to be considered.
408*/
409
397}
398
399
400static int
401SeqDiff(u_long x, u_long y)
402{
403/* Return the difference between two TCP sequence numbers */
404
405/*
406 This function is encapsulated in case there are any unusual
407 arithmetic conditions that need to be considered.
408*/
409
410 return (ntohl(y) - ntohl(x));
410 return (ntohl(y) - ntohl(x));
411}
412
413
414static void
415ShowAliasStats(struct libalias *la)
416{
417/* Used for debugging */
418
411}
412
413
414static void
415ShowAliasStats(struct libalias *la)
416{
417/* Used for debugging */
418
419 if (la->monitorFile)
420 {
421 fprintf(la->monitorFile,
422 "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d",
423 la->icmpLinkCount,
424 la->udpLinkCount,
425 la->tcpLinkCount,
426 la->pptpLinkCount,
427 la->protoLinkCount,
428 la->fragmentIdLinkCount,
429 la->fragmentPtrLinkCount);
419 if (la->monitorFile) {
420 fprintf(la->monitorFile,
421 "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d",
422 la->icmpLinkCount,
423 la->udpLinkCount,
424 la->tcpLinkCount,
425 la->pptpLinkCount,
426 la->protoLinkCount,
427 la->fragmentIdLinkCount,
428 la->fragmentPtrLinkCount);
430
429
431 fprintf(la->monitorFile, " / tot=%d (sock=%d)\n",
432 la->icmpLinkCount + la->udpLinkCount
433 + la->tcpLinkCount
434 + la->pptpLinkCount
435 + la->protoLinkCount
436 + la->fragmentIdLinkCount
437 + la->fragmentPtrLinkCount,
438 la->sockCount);
430 fprintf(la->monitorFile, " / tot=%d (sock=%d)\n",
431 la->icmpLinkCount + la->udpLinkCount
432 + la->tcpLinkCount
433 + la->pptpLinkCount
434 + la->protoLinkCount
435 + la->fragmentIdLinkCount
436 + la->fragmentPtrLinkCount,
437 la->sockCount);
439
438
440 fflush(la->monitorFile);
441 }
439 fflush(la->monitorFile);
440 }
442}
443
444
445
446
447
448/* Internal routines for finding, deleting and adding links
449

--- 12 unchanged lines hidden (view full) ---

462 FindLinkOut() - find link for outgoing packets
463 FindLinkIn() - find link for incoming packets
464
465Port search:
466 FindNewPortGroup() - find an available group of ports
467*/
468
469/* Local prototypes */
441}
442
443
444
445
446
447/* Internal routines for finding, deleting and adding links
448

--- 12 unchanged lines hidden (view full) ---

461 FindLinkOut() - find link for outgoing packets
462 FindLinkIn() - find link for incoming packets
463
464Port search:
465 FindNewPortGroup() - find an available group of ports
466*/
467
468/* Local prototypes */
470static int GetNewPort(struct libalias *, struct alias_link *, int);
469static int GetNewPort(struct libalias *, struct alias_link *, int);
471
470
472static u_short GetSocket(struct libalias *, u_short, int *, int);
471static u_short GetSocket(struct libalias *, u_short, int *, int);
473
472
474static void CleanupAliasData(struct libalias *);
473static void CleanupAliasData(struct libalias *);
475
474
476static void IncrementalCleanup(struct libalias *);
475static void IncrementalCleanup(struct libalias *);
477
476
478static void DeleteLink(struct alias_link *);
477static void DeleteLink(struct alias_link *);
479
480static struct alias_link *
481AddLink(struct libalias *, struct in_addr, struct in_addr, struct in_addr,
478
479static struct alias_link *
480AddLink(struct libalias *, struct in_addr, struct in_addr, struct in_addr,
482 u_short, u_short, int, int);
481 u_short, u_short, int, int);
483
484static struct alias_link *
485ReLink(struct alias_link *,
482
483static struct alias_link *
484ReLink(struct alias_link *,
486 struct in_addr, struct in_addr, struct in_addr,
487 u_short, u_short, int, int);
485 struct in_addr, struct in_addr, struct in_addr,
486 u_short, u_short, int, int);
488
489static struct alias_link *
487
488static struct alias_link *
490FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
489 FindLinkOut (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
491
492static struct alias_link *
490
491static struct alias_link *
493FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
492 FindLinkIn (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
494
495
496#define ALIAS_PORT_BASE 0x08000
497#define ALIAS_PORT_MASK 0x07fff
498#define ALIAS_PORT_MASK_EVEN 0x07ffe
499#define GET_NEW_PORT_MAX_ATTEMPTS 20
500
501#define GET_ALIAS_PORT -1

--- 4 unchanged lines hidden (view full) ---

506/* GetNewPort() allocates port numbers. Note that if a port number
507 is already in use, that does not mean that it cannot be used by
508 another link concurrently. This is because GetNewPort() looks for
509 unused triplets: (dest addr, dest port, alias port). */
510
511static int
512GetNewPort(struct libalias *la, struct alias_link *link, int alias_port_param)
513{
493
494
495#define ALIAS_PORT_BASE 0x08000
496#define ALIAS_PORT_MASK 0x07fff
497#define ALIAS_PORT_MASK_EVEN 0x07ffe
498#define GET_NEW_PORT_MAX_ATTEMPTS 20
499
500#define GET_ALIAS_PORT -1

--- 4 unchanged lines hidden (view full) ---

505/* GetNewPort() allocates port numbers. Note that if a port number
506 is already in use, that does not mean that it cannot be used by
507 another link concurrently. This is because GetNewPort() looks for
508 unused triplets: (dest addr, dest port, alias port). */
509
510static int
511GetNewPort(struct libalias *la, struct alias_link *link, int alias_port_param)
512{
514 int i;
515 int max_trials;
516 u_short port_sys;
517 u_short port_net;
513 int i;
514 int max_trials;
515 u_short port_sys;
516 u_short port_net;
518
519/*
520 Description of alias_port_param for GetNewPort(). When
521 this parameter is zero or positive, it precisely specifies
522 the port number. GetNewPort() will return this number
523 without check that it is in use.
524
525 When this parameter is GET_ALIAS_PORT, it indicates to get a randomly
526 selected port number.
527*/
528
517
518/*
519 Description of alias_port_param for GetNewPort(). When
520 this parameter is zero or positive, it precisely specifies
521 the port number. GetNewPort() will return this number
522 without check that it is in use.
523
524 When this parameter is GET_ALIAS_PORT, it indicates to get a randomly
525 selected port number.
526*/
527
529 if (alias_port_param == GET_ALIAS_PORT)
530 {
531 /*
532 * The aliasing port is automatically selected
533 * by one of two methods below:
534 */
535 max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
528 if (alias_port_param == GET_ALIAS_PORT) {
529 /*
530 * The aliasing port is automatically selected by one of
531 * two methods below:
532 */
533 max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
536
534
537 if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS)
538 {
539 /*
540 * When the PKT_ALIAS_SAME_PORTS option is
541 * chosen, the first try will be the
542 * actual source port. If this is already
543 * in use, the remainder of the trials
544 * will be random.
545 */
546 port_net = link->src_port;
547 port_sys = ntohs(port_net);
548 }
549 else
550 {
551 /* First trial and all subsequent are random. */
552 port_sys = random() & ALIAS_PORT_MASK;
553 port_sys += ALIAS_PORT_BASE;
554 port_net = htons(port_sys);
555 }
556 }
557 else if (alias_port_param >= 0 && alias_port_param < 0x10000)
558 {
559 link->alias_port = (u_short) alias_port_param;
560 return(0);
561 }
562 else
563 {
535 if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
536 /*
537 * When the PKT_ALIAS_SAME_PORTS option is chosen,
538 * the first try will be the actual source port. If
539 * this is already in use, the remainder of the
540 * trials will be random.
541 */
542 port_net = link->src_port;
543 port_sys = ntohs(port_net);
544 } else {
545 /* First trial and all subsequent are random. */
546 port_sys = random() & ALIAS_PORT_MASK;
547 port_sys += ALIAS_PORT_BASE;
548 port_net = htons(port_sys);
549 }
550 } else if (alias_port_param >= 0 && alias_port_param < 0x10000) {
551 link->alias_port = (u_short) alias_port_param;
552 return (0);
553 } else {
564#ifdef DEBUG
554#ifdef DEBUG
565 fprintf(stderr, "PacketAlias/GetNewPort(): ");
566 fprintf(stderr, "input parameter error\n");
555 fprintf(stderr, "PacketAlias/GetNewPort(): ");
556 fprintf(stderr, "input parameter error\n");
567#endif
557#endif
568 return(-1);
569 }
558 return (-1);
559 }
570
571
572/* Port number search */
560
561
562/* Port number search */
573 for (i=0; i<max_trials; i++)
574 {
575 int go_ahead;
576 struct alias_link *search_result;
563 for (i = 0; i < max_trials; i++) {
564 int go_ahead;
565 struct alias_link *search_result;
577
566
578 search_result = FindLinkIn(la, link->dst_addr, link->alias_addr,
579 link->dst_port, port_net,
580 link->link_type, 0);
567 search_result = FindLinkIn(la, link->dst_addr, link->alias_addr,
568 link->dst_port, port_net,
569 link->link_type, 0);
581
570
582 if (search_result == NULL)
583 go_ahead = 1;
584 else if (!(link->flags & LINK_PARTIALLY_SPECIFIED)
585 && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
586 go_ahead = 1;
587 else
588 go_ahead = 0;
571 if (search_result == NULL)
572 go_ahead = 1;
573 else if (!(link->flags & LINK_PARTIALLY_SPECIFIED)
574 && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
575 go_ahead = 1;
576 else
577 go_ahead = 0;
589
578
590 if (go_ahead)
591 {
592 if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS)
593 && (link->flags & LINK_PARTIALLY_SPECIFIED)
594 && ((link->link_type == LINK_TCP) ||
595 (link->link_type == LINK_UDP)))
596 {
597 if (GetSocket(la, port_net, &link->sockfd, link->link_type))
598 {
599 link->alias_port = port_net;
600 return(0);
601 }
602 }
603 else
604 {
605 link->alias_port = port_net;
606 return(0);
607 }
608 }
579 if (go_ahead) {
580 if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS)
581 && (link->flags & LINK_PARTIALLY_SPECIFIED)
582 && ((link->link_type == LINK_TCP) ||
583 (link->link_type == LINK_UDP))) {
584 if (GetSocket(la, port_net, &link->sockfd, link->link_type)) {
585 link->alias_port = port_net;
586 return (0);
587 }
588 } else {
589 link->alias_port = port_net;
590 return (0);
591 }
592 }
593 port_sys = random() & ALIAS_PORT_MASK;
594 port_sys += ALIAS_PORT_BASE;
595 port_net = htons(port_sys);
596 }
609
597
610 port_sys = random() & ALIAS_PORT_MASK;
611 port_sys += ALIAS_PORT_BASE;
612 port_net = htons(port_sys);
613 }
614
615#ifdef DEBUG
598#ifdef DEBUG
616 fprintf(stderr, "PacketAlias/GetnewPort(): ");
617 fprintf(stderr, "could not find free port\n");
599 fprintf(stderr, "PacketAlias/GetnewPort(): ");
600 fprintf(stderr, "could not find free port\n");
618#endif
619
601#endif
602
620 return(-1);
603 return (-1);
621}
622
623
604}
605
606
624static u_short
607static u_short
625GetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type)
626{
608GetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type)
609{
627 int err;
628 int sock;
629 struct sockaddr_in sock_addr;
610 int err;
611 int sock;
612 struct sockaddr_in sock_addr;
630
613
631 if (link_type == LINK_TCP)
632 sock = socket(AF_INET, SOCK_STREAM, 0);
633 else if (link_type == LINK_UDP)
634 sock = socket(AF_INET, SOCK_DGRAM, 0);
635 else
636 {
614 if (link_type == LINK_TCP)
615 sock = socket(AF_INET, SOCK_STREAM, 0);
616 else if (link_type == LINK_UDP)
617 sock = socket(AF_INET, SOCK_DGRAM, 0);
618 else {
637#ifdef DEBUG
619#ifdef DEBUG
638 fprintf(stderr, "PacketAlias/GetSocket(): ");
639 fprintf(stderr, "incorrect link type\n");
620 fprintf(stderr, "PacketAlias/GetSocket(): ");
621 fprintf(stderr, "incorrect link type\n");
640#endif
622#endif
641 return(0);
642 }
623 return (0);
624 }
643
625
644 if (sock < 0)
645 {
626 if (sock < 0) {
646#ifdef DEBUG
627#ifdef DEBUG
647 fprintf(stderr, "PacketAlias/GetSocket(): ");
648 fprintf(stderr, "socket() error %d\n", *sockfd);
628 fprintf(stderr, "PacketAlias/GetSocket(): ");
629 fprintf(stderr, "socket() error %d\n", *sockfd);
649#endif
630#endif
650 return(0);
651 }
631 return (0);
632 }
633 sock_addr.sin_family = AF_INET;
634 sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
635 sock_addr.sin_port = port_net;
652
636
653 sock_addr.sin_family = AF_INET;
654 sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
655 sock_addr.sin_port = port_net;
656
657 err = bind(sock,
658 (struct sockaddr *) &sock_addr,
659 sizeof(sock_addr));
660 if (err == 0)
661 {
662 la->sockCount++;
663 *sockfd = sock;
664 return(1);
665 }
666 else
667 {
668 close(sock);
669 return(0);
670 }
637 err = bind(sock,
638 (struct sockaddr *)&sock_addr,
639 sizeof(sock_addr));
640 if (err == 0) {
641 la->sockCount++;
642 *sockfd = sock;
643 return (1);
644 } else {
645 close(sock);
646 return (0);
647 }
671}
672
673
674/* FindNewPortGroup() returns a base port number for an available
675 range of contiguous port numbers. Note that if a port number
676 is already in use, that does not mean that it cannot be used by
677 another link concurrently. This is because FindNewPortGroup()
678 looks for unused triplets: (dest addr, dest port, alias port). */
679
680int
681FindNewPortGroup(struct libalias *la,
648}
649
650
651/* FindNewPortGroup() returns a base port number for an available
652 range of contiguous port numbers. Note that if a port number
653 is already in use, that does not mean that it cannot be used by
654 another link concurrently. This is because FindNewPortGroup()
655 looks for unused triplets: (dest addr, dest port, alias port). */
656
657int
658FindNewPortGroup(struct libalias *la,
682 struct in_addr dst_addr,
683 struct in_addr alias_addr,
684 u_short src_port,
685 u_short dst_port,
686 u_short port_count,
687 u_char proto,
688 u_char align)
659 struct in_addr dst_addr,
660 struct in_addr alias_addr,
661 u_short src_port,
662 u_short dst_port,
663 u_short port_count,
664 u_char proto,
665 u_char align)
689{
666{
690 int i, j;
691 int max_trials;
692 u_short port_sys;
693 int link_type;
667 int i, j;
668 int max_trials;
669 u_short port_sys;
670 int link_type;
694
671
695 /*
696 * Get link_type from protocol
697 */
672 /*
673 * Get link_type from protocol
674 */
698
675
699 switch (proto)
700 {
701 case IPPROTO_UDP:
702 link_type = LINK_UDP;
703 break;
704 case IPPROTO_TCP:
705 link_type = LINK_TCP;
706 break;
707 default:
708 return (0);
709 break;
710 }
676 switch (proto) {
677 case IPPROTO_UDP:
678 link_type = LINK_UDP;
679 break;
680 case IPPROTO_TCP:
681 link_type = LINK_TCP;
682 break;
683 default:
684 return (0);
685 break;
686 }
711
687
712 /*
713 * The aliasing port is automatically selected
714 * by one of two methods below:
715 */
716 max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
688 /*
689 * The aliasing port is automatically selected by one of two
690 * methods below:
691 */
692 max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
717
693
718 if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
719 /*
720 * When the ALIAS_SAME_PORTS option is
721 * chosen, the first try will be the
722 * actual source port. If this is already
723 * in use, the remainder of the trials
724 * will be random.
725 */
726 port_sys = ntohs(src_port);
694 if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
695 /*
696 * When the ALIAS_SAME_PORTS option is chosen, the first
697 * try will be the actual source port. If this is already
698 * in use, the remainder of the trials will be random.
699 */
700 port_sys = ntohs(src_port);
727
701
728 } else {
702 } else {
729
703
730 /* First trial and all subsequent are random. */
731 if (align == FIND_EVEN_ALIAS_BASE)
732 port_sys = random() & ALIAS_PORT_MASK_EVEN;
733 else
734 port_sys = random() & ALIAS_PORT_MASK;
704 /* First trial and all subsequent are random. */
705 if (align == FIND_EVEN_ALIAS_BASE)
706 port_sys = random() & ALIAS_PORT_MASK_EVEN;
707 else
708 port_sys = random() & ALIAS_PORT_MASK;
735
709
736 port_sys += ALIAS_PORT_BASE;
737 }
710 port_sys += ALIAS_PORT_BASE;
711 }
738
739/* Port number search */
712
713/* Port number search */
740 for (i = 0; i < max_trials; i++) {
714 for (i = 0; i < max_trials; i++) {
741
715
742 struct alias_link *search_result;
716 struct alias_link *search_result;
743
717
744 for (j = 0; j < port_count; j++)
745 if (0 != (search_result = FindLinkIn(la, dst_addr, alias_addr,
746 dst_port, htons(port_sys + j),
747 link_type, 0)))
748 break;
718 for (j = 0; j < port_count; j++)
719 if (0 != (search_result = FindLinkIn(la, dst_addr, alias_addr,
720 dst_port, htons(port_sys + j),
721 link_type, 0)))
722 break;
749
723
750 /* Found a good range, return base */
751 if (j == port_count)
752 return (htons(port_sys));
724 /* Found a good range, return base */
725 if (j == port_count)
726 return (htons(port_sys));
753
727
754 /* Find a new base to try */
755 if (align == FIND_EVEN_ALIAS_BASE)
756 port_sys = random() & ALIAS_PORT_MASK_EVEN;
757 else
758 port_sys = random() & ALIAS_PORT_MASK;
728 /* Find a new base to try */
729 if (align == FIND_EVEN_ALIAS_BASE)
730 port_sys = random() & ALIAS_PORT_MASK_EVEN;
731 else
732 port_sys = random() & ALIAS_PORT_MASK;
759
733
760 port_sys += ALIAS_PORT_BASE;
761 }
734 port_sys += ALIAS_PORT_BASE;
735 }
762
763#ifdef DEBUG
736
737#ifdef DEBUG
764 fprintf(stderr, "PacketAlias/FindNewPortGroup(): ");
765 fprintf(stderr, "could not find free port(s)\n");
738 fprintf(stderr, "PacketAlias/FindNewPortGroup(): ");
739 fprintf(stderr, "could not find free port(s)\n");
766#endif
767
740#endif
741
768 return(0);
742 return (0);
769}
770
771static void
772CleanupAliasData(struct libalias *la)
773{
743}
744
745static void
746CleanupAliasData(struct libalias *la)
747{
774 struct alias_link *link;
775 int i, icount;
748 struct alias_link *link;
749 int i, icount;
776
750
777 icount = 0;
778 for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
779 {
780 link = LIST_FIRST(&la->linkTableOut[i]);
781 while (link != NULL)
782 {
783 struct alias_link *link_next;
784 link_next = LIST_NEXT(link, list_out);
785 icount++;
786 DeleteLink(link);
787 link = link_next;
788 }
789 }
751 icount = 0;
752 for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) {
753 link = LIST_FIRST(&la->linkTableOut[i]);
754 while (link != NULL) {
755 struct alias_link *link_next;
790
756
791 la->cleanupIndex =0;
757 link_next = LIST_NEXT(link, list_out);
758 icount++;
759 DeleteLink(link);
760 link = link_next;
761 }
762 }
763
764 la->cleanupIndex = 0;
792}
793
794
795static void
796IncrementalCleanup(struct libalias *la)
797{
765}
766
767
768static void
769IncrementalCleanup(struct libalias *la)
770{
798 int icount;
799 struct alias_link *link;
771 int icount;
772 struct alias_link *link;
800
773
801 icount = 0;
802 link = LIST_FIRST(&la->linkTableOut[la->cleanupIndex++]);
803 while (link != NULL)
804 {
805 int idelta;
806 struct alias_link *link_next;
774 icount = 0;
775 link = LIST_FIRST(&la->linkTableOut[la->cleanupIndex++]);
776 while (link != NULL) {
777 int idelta;
778 struct alias_link *link_next;
807
779
808 link_next = LIST_NEXT(link, list_out);
809 idelta = la->timeStamp - link->timestamp;
810 switch (link->link_type)
811 {
812 case LINK_TCP:
813 if (idelta > link->expire_time)
814 {
815 struct tcp_dat *tcp_aux;
780 link_next = LIST_NEXT(link, list_out);
781 idelta = la->timeStamp - link->timestamp;
782 switch (link->link_type) {
783 case LINK_TCP:
784 if (idelta > link->expire_time) {
785 struct tcp_dat *tcp_aux;
816
786
817 tcp_aux = link->data.tcp;
818 if (tcp_aux->state.in != ALIAS_TCP_STATE_CONNECTED
819 || tcp_aux->state.out != ALIAS_TCP_STATE_CONNECTED)
820 {
821 DeleteLink(link);
822 icount++;
823 }
824 }
825 break;
826 default:
827 if (idelta > link->expire_time)
828 {
829 DeleteLink(link);
830 icount++;
831 }
832 break;
833 }
834 link = link_next;
835 }
787 tcp_aux = link->data.tcp;
788 if (tcp_aux->state.in != ALIAS_TCP_STATE_CONNECTED
789 || tcp_aux->state.out != ALIAS_TCP_STATE_CONNECTED) {
790 DeleteLink(link);
791 icount++;
792 }
793 }
794 break;
795 default:
796 if (idelta > link->expire_time) {
797 DeleteLink(link);
798 icount++;
799 }
800 break;
801 }
802 link = link_next;
803 }
836
804
837 if (la->cleanupIndex == LINK_TABLE_OUT_SIZE)
838 la->cleanupIndex = 0;
805 if (la->cleanupIndex == LINK_TABLE_OUT_SIZE)
806 la->cleanupIndex = 0;
839}
840
841static void
842DeleteLink(struct alias_link *link)
843{
807}
808
809static void
810DeleteLink(struct alias_link *link)
811{
844 struct libalias *la = link->la;
812 struct libalias *la = link->la;
845
846/* Don't do anything if the link is marked permanent */
813
814/* Don't do anything if the link is marked permanent */
847 if (la->deleteAllLinks == 0 && link->flags & LINK_PERMANENT)
848 return;
815 if (la->deleteAllLinks == 0 && link->flags & LINK_PERMANENT)
816 return;
849
850#ifndef NO_FW_PUNCH
851/* Delete associated firewall hole, if any */
817
818#ifndef NO_FW_PUNCH
819/* Delete associated firewall hole, if any */
852 ClearFWHole(link);
820 ClearFWHole(link);
853#endif
854
855/* Free memory allocated for LSNAT server pool */
821#endif
822
823/* Free memory allocated for LSNAT server pool */
856 if (link->server != NULL) {
857 struct server *head, *curr, *next;
824 if (link->server != NULL) {
825 struct server *head, *curr, *next;
858
826
859 head = curr = link->server;
860 do {
861 next = curr->next;
862 free(curr);
863 } while ((curr = next) != head);
864 }
865
827 head = curr = link->server;
828 do {
829 next = curr->next;
830 free(curr);
831 } while ((curr = next) != head);
832 }
866/* Adjust output table pointers */
833/* Adjust output table pointers */
867 LIST_REMOVE(link, list_out);
834 LIST_REMOVE(link, list_out);
868
869/* Adjust input table pointers */
835
836/* Adjust input table pointers */
870 LIST_REMOVE(link, list_in);
837 LIST_REMOVE(link, list_in);
871
872/* Close socket, if one has been allocated */
838
839/* Close socket, if one has been allocated */
873 if (link->sockfd != -1)
874 {
875 la->sockCount--;
876 close(link->sockfd);
877 }
878
840 if (link->sockfd != -1) {
841 la->sockCount--;
842 close(link->sockfd);
843 }
879/* Link-type dependent cleanup */
844/* Link-type dependent cleanup */
880 switch(link->link_type)
881 {
882 case LINK_ICMP:
883 la->icmpLinkCount--;
884 break;
885 case LINK_UDP:
886 la->udpLinkCount--;
887 break;
888 case LINK_TCP:
889 la->tcpLinkCount--;
890 free(link->data.tcp);
891 break;
892 case LINK_PPTP:
893 la->pptpLinkCount--;
894 break;
895 case LINK_FRAGMENT_ID:
896 la->fragmentIdLinkCount--;
897 break;
898 case LINK_FRAGMENT_PTR:
899 la->fragmentPtrLinkCount--;
900 if (link->data.frag_ptr != NULL)
901 free(link->data.frag_ptr);
902 break;
845 switch (link->link_type) {
846 case LINK_ICMP:
847 la->icmpLinkCount--;
848 break;
849 case LINK_UDP:
850 la->udpLinkCount--;
851 break;
852 case LINK_TCP:
853 la->tcpLinkCount--;
854 free(link->data.tcp);
855 break;
856 case LINK_PPTP:
857 la->pptpLinkCount--;
858 break;
859 case LINK_FRAGMENT_ID:
860 la->fragmentIdLinkCount--;
861 break;
862 case LINK_FRAGMENT_PTR:
863 la->fragmentPtrLinkCount--;
864 if (link->data.frag_ptr != NULL)
865 free(link->data.frag_ptr);
866 break;
903 case LINK_ADDR:
867 case LINK_ADDR:
904 break;
905 default:
906 la->protoLinkCount--;
907 break;
908 }
868 break;
869 default:
870 la->protoLinkCount--;
871 break;
872 }
909
910/* Free memory */
873
874/* Free memory */
911 free(link);
875 free(link);
912
913/* Write statistics, if logging enabled */
876
877/* Write statistics, if logging enabled */
914 if (la->packetAliasMode & PKT_ALIAS_LOG)
915 {
916 ShowAliasStats(la);
917 }
878 if (la->packetAliasMode & PKT_ALIAS_LOG) {
879 ShowAliasStats(la);
880 }
918}
919
920
921static struct alias_link *
881}
882
883
884static struct alias_link *
922AddLink(struct libalias *la, struct in_addr src_addr,
923 struct in_addr dst_addr,
924 struct in_addr alias_addr,
925 u_short src_port,
926 u_short dst_port,
927 int alias_port_param, /* if less than zero, alias */
928 int link_type) /* port will be automatically */
929{ /* chosen. If greater than */
930 u_int start_point; /* zero, equal to alias port */
931 struct alias_link *link;
885AddLink(struct libalias *la, struct in_addr src_addr,
886 struct in_addr dst_addr,
887 struct in_addr alias_addr,
888 u_short src_port,
889 u_short dst_port,
890 int alias_port_param, /* if less than zero, alias */
891 int link_type)
892{ /* port will be automatically *//* chosen.
893 * If greater than */
894 u_int start_point; /* zero, equal to alias port */
895 struct alias_link *link;
932
896
933 link = malloc(sizeof(struct alias_link));
934 if (link != NULL)
935 {
936 /* Basic initialization */
937 link->la = la;
938 link->src_addr = src_addr;
939 link->dst_addr = dst_addr;
940 link->alias_addr = alias_addr;
941 link->proxy_addr.s_addr = INADDR_ANY;
942 link->src_port = src_port;
943 link->dst_port = dst_port;
944 link->proxy_port = 0;
945 link->server = NULL;
946 link->link_type = link_type;
947 link->sockfd = -1;
948 link->flags = 0;
949 link->pflags = 0;
950 link->timestamp = la->timeStamp;
897 link = malloc(sizeof(struct alias_link));
898 if (link != NULL) {
899 /* Basic initialization */
900 link->la = la;
901 link->src_addr = src_addr;
902 link->dst_addr = dst_addr;
903 link->alias_addr = alias_addr;
904 link->proxy_addr.s_addr = INADDR_ANY;
905 link->src_port = src_port;
906 link->dst_port = dst_port;
907 link->proxy_port = 0;
908 link->server = NULL;
909 link->link_type = link_type;
910 link->sockfd = -1;
911 link->flags = 0;
912 link->pflags = 0;
913 link->timestamp = la->timeStamp;
951
914
952 /* Expiration time */
953 switch (link_type)
954 {
955 case LINK_ICMP:
956 link->expire_time = ICMP_EXPIRE_TIME;
957 break;
958 case LINK_UDP:
959 link->expire_time = UDP_EXPIRE_TIME;
960 break;
961 case LINK_TCP:
962 link->expire_time = TCP_EXPIRE_INITIAL;
963 break;
964 case LINK_PPTP:
965 link->flags |= LINK_PERMANENT; /* no timeout. */
966 break;
967 case LINK_FRAGMENT_ID:
968 link->expire_time = FRAGMENT_ID_EXPIRE_TIME;
969 break;
970 case LINK_FRAGMENT_PTR:
971 link->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
972 break;
973 case LINK_ADDR:
974 break;
975 default:
976 link->expire_time = PROTO_EXPIRE_TIME;
977 break;
978 }
915 /* Expiration time */
916 switch (link_type) {
917 case LINK_ICMP:
918 link->expire_time = ICMP_EXPIRE_TIME;
919 break;
920 case LINK_UDP:
921 link->expire_time = UDP_EXPIRE_TIME;
922 break;
923 case LINK_TCP:
924 link->expire_time = TCP_EXPIRE_INITIAL;
925 break;
926 case LINK_PPTP:
927 link->flags |= LINK_PERMANENT; /* no timeout. */
928 break;
929 case LINK_FRAGMENT_ID:
930 link->expire_time = FRAGMENT_ID_EXPIRE_TIME;
931 break;
932 case LINK_FRAGMENT_PTR:
933 link->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
934 break;
935 case LINK_ADDR:
936 break;
937 default:
938 link->expire_time = PROTO_EXPIRE_TIME;
939 break;
940 }
979
941
980 /* Determine alias flags */
981 if (dst_addr.s_addr == INADDR_ANY)
982 link->flags |= LINK_UNKNOWN_DEST_ADDR;
983 if (dst_port == 0)
984 link->flags |= LINK_UNKNOWN_DEST_PORT;
942 /* Determine alias flags */
943 if (dst_addr.s_addr == INADDR_ANY)
944 link->flags |= LINK_UNKNOWN_DEST_ADDR;
945 if (dst_port == 0)
946 link->flags |= LINK_UNKNOWN_DEST_PORT;
985
947
986 /* Determine alias port */
987 if (GetNewPort(la, link, alias_port_param) != 0)
988 {
989 free(link);
990 return(NULL);
991 }
948 /* Determine alias port */
949 if (GetNewPort(la, link, alias_port_param) != 0) {
950 free(link);
951 return (NULL);
952 }
953 /* Link-type dependent initialization */
954 switch (link_type) {
955 struct tcp_dat *aux_tcp;
992
956
993 /* Link-type dependent initialization */
994 switch(link_type)
995 {
996 struct tcp_dat *aux_tcp;
957 case LINK_ICMP:
958 la->icmpLinkCount++;
959 break;
960 case LINK_UDP:
961 la->udpLinkCount++;
962 break;
963 case LINK_TCP:
964 aux_tcp = malloc(sizeof(struct tcp_dat));
965 if (aux_tcp != NULL) {
966 int i;
997
967
998 case LINK_ICMP:
999 la->icmpLinkCount++;
1000 break;
1001 case LINK_UDP:
1002 la->udpLinkCount++;
1003 break;
1004 case LINK_TCP:
1005 aux_tcp = malloc(sizeof(struct tcp_dat));
1006 if (aux_tcp != NULL)
1007 {
1008 int i;
1009
1010 la->tcpLinkCount++;
1011 aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
1012 aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
1013 aux_tcp->state.index = 0;
1014 aux_tcp->state.ack_modified = 0;
1015 for (i=0; i<N_LINK_TCP_DATA; i++)
1016 aux_tcp->ack[i].active = 0;
1017 aux_tcp->fwhole = -1;
1018 link->data.tcp = aux_tcp;
1019 }
1020 else
1021 {
968 la->tcpLinkCount++;
969 aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
970 aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
971 aux_tcp->state.index = 0;
972 aux_tcp->state.ack_modified = 0;
973 for (i = 0; i < N_LINK_TCP_DATA; i++)
974 aux_tcp->ack[i].active = 0;
975 aux_tcp->fwhole = -1;
976 link->data.tcp = aux_tcp;
977 } else {
1022#ifdef DEBUG
978#ifdef DEBUG
1023 fprintf(stderr, "PacketAlias/AddLink: ");
1024 fprintf(stderr, " cannot allocate auxiliary TCP data\n");
979 fprintf(stderr, "PacketAlias/AddLink: ");
980 fprintf(stderr, " cannot allocate auxiliary TCP data\n");
1025#endif
981#endif
1026 free(link);
1027 return (NULL);
1028 }
1029 break;
1030 case LINK_PPTP:
1031 la->pptpLinkCount++;
1032 break;
1033 case LINK_FRAGMENT_ID:
1034 la->fragmentIdLinkCount++;
1035 break;
1036 case LINK_FRAGMENT_PTR:
1037 la->fragmentPtrLinkCount++;
1038 break;
1039 case LINK_ADDR:
1040 break;
1041 default:
1042 la->protoLinkCount++;
1043 break;
1044 }
982 free(link);
983 return (NULL);
984 }
985 break;
986 case LINK_PPTP:
987 la->pptpLinkCount++;
988 break;
989 case LINK_FRAGMENT_ID:
990 la->fragmentIdLinkCount++;
991 break;
992 case LINK_FRAGMENT_PTR:
993 la->fragmentPtrLinkCount++;
994 break;
995 case LINK_ADDR:
996 break;
997 default:
998 la->protoLinkCount++;
999 break;
1000 }
1045
1001
1046 /* Set up pointers for output lookup table */
1047 start_point = StartPointOut(src_addr, dst_addr,
1048 src_port, dst_port, link_type);
1049 LIST_INSERT_HEAD(&la->linkTableOut[start_point], link, list_out);
1002 /* Set up pointers for output lookup table */
1003 start_point = StartPointOut(src_addr, dst_addr,
1004 src_port, dst_port, link_type);
1005 LIST_INSERT_HEAD(&la->linkTableOut[start_point], link, list_out);
1050
1006
1051 /* Set up pointers for input lookup table */
1052 start_point = StartPointIn(alias_addr, link->alias_port, link_type);
1053 LIST_INSERT_HEAD(&la->linkTableIn[start_point], link, list_in);
1054 }
1055 else
1056 {
1007 /* Set up pointers for input lookup table */
1008 start_point = StartPointIn(alias_addr, link->alias_port, link_type);
1009 LIST_INSERT_HEAD(&la->linkTableIn[start_point], link, list_in);
1010 } else {
1057#ifdef DEBUG
1011#ifdef DEBUG
1058 fprintf(stderr, "PacketAlias/AddLink(): ");
1059 fprintf(stderr, "malloc() call failed.\n");
1012 fprintf(stderr, "PacketAlias/AddLink(): ");
1013 fprintf(stderr, "malloc() call failed.\n");
1060#endif
1014#endif
1061 }
1015 }
1062
1016
1063 if (la->packetAliasMode & PKT_ALIAS_LOG)
1064 {
1065 ShowAliasStats(la);
1066 }
1067
1068 return(link);
1017 if (la->packetAliasMode & PKT_ALIAS_LOG) {
1018 ShowAliasStats(la);
1019 }
1020 return (link);
1069}
1070
1071static struct alias_link *
1072ReLink(struct alias_link *old_link,
1021}
1022
1023static struct alias_link *
1024ReLink(struct alias_link *old_link,
1073 struct in_addr src_addr,
1074 struct in_addr dst_addr,
1075 struct in_addr alias_addr,
1076 u_short src_port,
1077 u_short dst_port,
1078 int alias_port_param, /* if less than zero, alias */
1079 int link_type) /* port will be automatically */
1080{ /* chosen. If greater than */
1081 struct alias_link *new_link; /* zero, equal to alias port */
1082 struct libalias *la = old_link->la;
1025 struct in_addr src_addr,
1026 struct in_addr dst_addr,
1027 struct in_addr alias_addr,
1028 u_short src_port,
1029 u_short dst_port,
1030 int alias_port_param, /* if less than zero, alias */
1031 int link_type)
1032{ /* port will be automatically *//* chosen.
1033 * If greater than */
1034 struct alias_link *new_link; /* zero, equal to alias port */
1035 struct libalias *la = old_link->la;
1083
1036
1084 new_link = AddLink(la, src_addr, dst_addr, alias_addr,
1085 src_port, dst_port, alias_port_param,
1086 link_type);
1037 new_link = AddLink(la, src_addr, dst_addr, alias_addr,
1038 src_port, dst_port, alias_port_param,
1039 link_type);
1087#ifndef NO_FW_PUNCH
1040#ifndef NO_FW_PUNCH
1088 if (new_link != NULL &&
1089 old_link->link_type == LINK_TCP &&
1090 old_link->data.tcp->fwhole > 0) {
1091 PunchFWHole(new_link);
1092 }
1041 if (new_link != NULL &&
1042 old_link->link_type == LINK_TCP &&
1043 old_link->data.tcp->fwhole > 0) {
1044 PunchFWHole(new_link);
1045 }
1093#endif
1046#endif
1094 DeleteLink(old_link);
1095 return new_link;
1047 DeleteLink(old_link);
1048 return new_link;
1096}
1097
1098static struct alias_link *
1099_FindLinkOut(struct libalias *la, struct in_addr src_addr,
1049}
1050
1051static struct alias_link *
1052_FindLinkOut(struct libalias *la, struct in_addr src_addr,
1100 struct in_addr dst_addr,
1101 u_short src_port,
1102 u_short dst_port,
1103 int link_type,
1104 int replace_partial_links)
1053 struct in_addr dst_addr,
1054 u_short src_port,
1055 u_short dst_port,
1056 int link_type,
1057 int replace_partial_links)
1105{
1058{
1106 u_int i;
1107 struct alias_link *link;
1059 u_int i;
1060 struct alias_link *link;
1108
1061
1109 i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
1110 LIST_FOREACH(link, &la->linkTableOut[i], list_out)
1111 {
1112 if (link->src_addr.s_addr == src_addr.s_addr
1113 && link->server == NULL
1114 && link->dst_addr.s_addr == dst_addr.s_addr
1115 && link->dst_port == dst_port
1116 && link->src_port == src_port
1117 && link->link_type == link_type)
1118 {
1119 link->timestamp = la->timeStamp;
1120 break;
1121 }
1122 }
1062 i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
1063 LIST_FOREACH(link, &la->linkTableOut[i], list_out) {
1064 if (link->src_addr.s_addr == src_addr.s_addr
1065 && link->server == NULL
1066 && link->dst_addr.s_addr == dst_addr.s_addr
1067 && link->dst_port == dst_port
1068 && link->src_port == src_port
1069 && link->link_type == link_type) {
1070 link->timestamp = la->timeStamp;
1071 break;
1072 }
1073 }
1123
1124/* Search for partially specified links. */
1074
1075/* Search for partially specified links. */
1125 if (link == NULL && replace_partial_links)
1126 {
1127 if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY)
1128 {
1129 link = _FindLinkOut(la, src_addr, dst_addr, src_port, 0,
1130 link_type, 0);
1131 if (link == NULL)
1132 link = _FindLinkOut(la, src_addr, la->nullAddress, src_port,
1133 dst_port, link_type, 0);
1134 }
1135 if (link == NULL &&
1136 (dst_port != 0 || dst_addr.s_addr != INADDR_ANY))
1137 {
1138 link = _FindLinkOut(la, src_addr, la->nullAddress, src_port, 0,
1139 link_type, 0);
1140 }
1141 if (link != NULL)
1142 {
1143 link = ReLink(link,
1144 src_addr, dst_addr, link->alias_addr,
1145 src_port, dst_port, link->alias_port,
1146 link_type);
1147 }
1148 }
1149
1150 return(link);
1076 if (link == NULL && replace_partial_links) {
1077 if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) {
1078 link = _FindLinkOut(la, src_addr, dst_addr, src_port, 0,
1079 link_type, 0);
1080 if (link == NULL)
1081 link = _FindLinkOut(la, src_addr, la->nullAddress, src_port,
1082 dst_port, link_type, 0);
1083 }
1084 if (link == NULL &&
1085 (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) {
1086 link = _FindLinkOut(la, src_addr, la->nullAddress, src_port, 0,
1087 link_type, 0);
1088 }
1089 if (link != NULL) {
1090 link = ReLink(link,
1091 src_addr, dst_addr, link->alias_addr,
1092 src_port, dst_port, link->alias_port,
1093 link_type);
1094 }
1095 }
1096 return (link);
1151}
1152
1153static struct alias_link *
1154FindLinkOut(struct libalias *la, struct in_addr src_addr,
1097}
1098
1099static struct alias_link *
1100FindLinkOut(struct libalias *la, struct in_addr src_addr,
1155 struct in_addr dst_addr,
1156 u_short src_port,
1157 u_short dst_port,
1158 int link_type,
1159 int replace_partial_links)
1101 struct in_addr dst_addr,
1102 u_short src_port,
1103 u_short dst_port,
1104 int link_type,
1105 int replace_partial_links)
1160{
1106{
1161 struct alias_link *link;
1107 struct alias_link *link;
1162
1108
1163 link = _FindLinkOut(la, src_addr, dst_addr, src_port, dst_port,
1164 link_type, replace_partial_links);
1109 link = _FindLinkOut(la, src_addr, dst_addr, src_port, dst_port,
1110 link_type, replace_partial_links);
1165
1111
1166 if (link == NULL)
1167 {
1168 /* The following allows permanent links to be
1169 specified as using the default source address
1170 (i.e. device interface address) without knowing
1171 in advance what that address is. */
1172 if (la->aliasAddress.s_addr != INADDR_ANY &&
1173 src_addr.s_addr == la->aliasAddress.s_addr)
1174 {
1175 link = _FindLinkOut(la, la->nullAddress, dst_addr, src_port, dst_port,
1176 link_type, replace_partial_links);
1177 }
1178 }
1179
1180 return(link);
1112 if (link == NULL) {
1113 /*
1114 * The following allows permanent links to be specified as
1115 * using the default source address (i.e. device interface
1116 * address) without knowing in advance what that address
1117 * is.
1118 */
1119 if (la->aliasAddress.s_addr != INADDR_ANY &&
1120 src_addr.s_addr == la->aliasAddress.s_addr) {
1121 link = _FindLinkOut(la, la->nullAddress, dst_addr, src_port, dst_port,
1122 link_type, replace_partial_links);
1123 }
1124 }
1125 return (link);
1181}
1182
1183
1184static struct alias_link *
1185_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1126}
1127
1128
1129static struct alias_link *
1130_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1186 struct in_addr alias_addr,
1187 u_short dst_port,
1188 u_short alias_port,
1189 int link_type,
1190 int replace_partial_links)
1131 struct in_addr alias_addr,
1132 u_short dst_port,
1133 u_short alias_port,
1134 int link_type,
1135 int replace_partial_links)
1191{
1136{
1192 int flags_in;
1193 u_int start_point;
1194 struct alias_link *link;
1195 struct alias_link *link_fully_specified;
1196 struct alias_link *link_unknown_all;
1197 struct alias_link *link_unknown_dst_addr;
1198 struct alias_link *link_unknown_dst_port;
1137 int flags_in;
1138 u_int start_point;
1139 struct alias_link *link;
1140 struct alias_link *link_fully_specified;
1141 struct alias_link *link_unknown_all;
1142 struct alias_link *link_unknown_dst_addr;
1143 struct alias_link *link_unknown_dst_port;
1199
1200/* Initialize pointers */
1144
1145/* Initialize pointers */
1201 link_fully_specified = NULL;
1202 link_unknown_all = NULL;
1203 link_unknown_dst_addr = NULL;
1204 link_unknown_dst_port = NULL;
1146 link_fully_specified = NULL;
1147 link_unknown_all = NULL;
1148 link_unknown_dst_addr = NULL;
1149 link_unknown_dst_port = NULL;
1205
1206/* If either the dest addr or port is unknown, the search
1207 loop will have to know about this. */
1208
1150
1151/* If either the dest addr or port is unknown, the search
1152 loop will have to know about this. */
1153
1209 flags_in = 0;
1210 if (dst_addr.s_addr == INADDR_ANY)
1211 flags_in |= LINK_UNKNOWN_DEST_ADDR;
1212 if (dst_port == 0)
1213 flags_in |= LINK_UNKNOWN_DEST_PORT;
1154 flags_in = 0;
1155 if (dst_addr.s_addr == INADDR_ANY)
1156 flags_in |= LINK_UNKNOWN_DEST_ADDR;
1157 if (dst_port == 0)
1158 flags_in |= LINK_UNKNOWN_DEST_PORT;
1214
1215/* Search loop */
1159
1160/* Search loop */
1216 start_point = StartPointIn(alias_addr, alias_port, link_type);
1217 LIST_FOREACH(link, &la->linkTableIn[start_point], list_in)
1218 {
1219 int flags;
1161 start_point = StartPointIn(alias_addr, alias_port, link_type);
1162 LIST_FOREACH(link, &la->linkTableIn[start_point], list_in) {
1163 int flags;
1220
1164
1221 flags = flags_in | link->flags;
1222 if (!(flags & LINK_PARTIALLY_SPECIFIED))
1223 {
1224 if (link->alias_addr.s_addr == alias_addr.s_addr
1225 && link->alias_port == alias_port
1226 && link->dst_addr.s_addr == dst_addr.s_addr
1227 && link->dst_port == dst_port
1228 && link->link_type == link_type)
1229 {
1230 link_fully_specified = link;
1231 break;
1232 }
1233 }
1234 else if ((flags & LINK_UNKNOWN_DEST_ADDR)
1235 && (flags & LINK_UNKNOWN_DEST_PORT))
1236 {
1237 if (link->alias_addr.s_addr == alias_addr.s_addr
1238 && link->alias_port == alias_port
1239 && link->link_type == link_type)
1240 {
1241 if (link_unknown_all == NULL)
1242 link_unknown_all = link;
1243 }
1244 }
1245 else if (flags & LINK_UNKNOWN_DEST_ADDR)
1246 {
1247 if (link->alias_addr.s_addr == alias_addr.s_addr
1248 && link->alias_port == alias_port
1249 && link->link_type == link_type
1250 && link->dst_port == dst_port)
1251 {
1252 if (link_unknown_dst_addr == NULL)
1253 link_unknown_dst_addr = link;
1254 }
1255 }
1256 else if (flags & LINK_UNKNOWN_DEST_PORT)
1257 {
1258 if (link->alias_addr.s_addr == alias_addr.s_addr
1259 && link->alias_port == alias_port
1260 && link->link_type == link_type
1261 && link->dst_addr.s_addr == dst_addr.s_addr)
1262 {
1263 if (link_unknown_dst_port == NULL)
1264 link_unknown_dst_port = link;
1265 }
1266 }
1267 }
1165 flags = flags_in | link->flags;
1166 if (!(flags & LINK_PARTIALLY_SPECIFIED)) {
1167 if (link->alias_addr.s_addr == alias_addr.s_addr
1168 && link->alias_port == alias_port
1169 && link->dst_addr.s_addr == dst_addr.s_addr
1170 && link->dst_port == dst_port
1171 && link->link_type == link_type) {
1172 link_fully_specified = link;
1173 break;
1174 }
1175 } else if ((flags & LINK_UNKNOWN_DEST_ADDR)
1176 && (flags & LINK_UNKNOWN_DEST_PORT)) {
1177 if (link->alias_addr.s_addr == alias_addr.s_addr
1178 && link->alias_port == alias_port
1179 && link->link_type == link_type) {
1180 if (link_unknown_all == NULL)
1181 link_unknown_all = link;
1182 }
1183 } else if (flags & LINK_UNKNOWN_DEST_ADDR) {
1184 if (link->alias_addr.s_addr == alias_addr.s_addr
1185 && link->alias_port == alias_port
1186 && link->link_type == link_type
1187 && link->dst_port == dst_port) {
1188 if (link_unknown_dst_addr == NULL)
1189 link_unknown_dst_addr = link;
1190 }
1191 } else if (flags & LINK_UNKNOWN_DEST_PORT) {
1192 if (link->alias_addr.s_addr == alias_addr.s_addr
1193 && link->alias_port == alias_port
1194 && link->link_type == link_type
1195 && link->dst_addr.s_addr == dst_addr.s_addr) {
1196 if (link_unknown_dst_port == NULL)
1197 link_unknown_dst_port = link;
1198 }
1199 }
1200 }
1268
1269
1270
1201
1202
1203
1271 if (link_fully_specified != NULL)
1272 {
1273 link_fully_specified->timestamp = la->timeStamp;
1274 link = link_fully_specified;
1275 }
1276 else if (link_unknown_dst_port != NULL)
1277 link = link_unknown_dst_port;
1278 else if (link_unknown_dst_addr != NULL)
1279 link = link_unknown_dst_addr;
1280 else if (link_unknown_all != NULL)
1281 link = link_unknown_all;
1282 else
1283 return (NULL);
1204 if (link_fully_specified != NULL) {
1205 link_fully_specified->timestamp = la->timeStamp;
1206 link = link_fully_specified;
1207 } else if (link_unknown_dst_port != NULL)
1208 link = link_unknown_dst_port;
1209 else if (link_unknown_dst_addr != NULL)
1210 link = link_unknown_dst_addr;
1211 else if (link_unknown_all != NULL)
1212 link = link_unknown_all;
1213 else
1214 return (NULL);
1284
1215
1285 if (replace_partial_links &&
1286 (link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL))
1287 {
1288 struct in_addr src_addr;
1289 u_short src_port;
1216 if (replace_partial_links &&
1217 (link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL)) {
1218 struct in_addr src_addr;
1219 u_short src_port;
1290
1220
1291 if (link->server != NULL) { /* LSNAT link */
1292 src_addr = link->server->addr;
1293 src_port = link->server->port;
1294 link->server = link->server->next;
1295 } else {
1296 src_addr = link->src_addr;
1297 src_port = link->src_port;
1298 }
1221 if (link->server != NULL) { /* LSNAT link */
1222 src_addr = link->server->addr;
1223 src_port = link->server->port;
1224 link->server = link->server->next;
1225 } else {
1226 src_addr = link->src_addr;
1227 src_port = link->src_port;
1228 }
1299
1229
1300 link = ReLink(link,
1301 src_addr, dst_addr, alias_addr,
1302 src_port, dst_port, alias_port,
1303 link_type);
1304 }
1305
1306 return (link);
1230 link = ReLink(link,
1231 src_addr, dst_addr, alias_addr,
1232 src_port, dst_port, alias_port,
1233 link_type);
1234 }
1235 return (link);
1307}
1308
1309static struct alias_link *
1310FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1236}
1237
1238static struct alias_link *
1239FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1311 struct in_addr alias_addr,
1312 u_short dst_port,
1313 u_short alias_port,
1314 int link_type,
1315 int replace_partial_links)
1240 struct in_addr alias_addr,
1241 u_short dst_port,
1242 u_short alias_port,
1243 int link_type,
1244 int replace_partial_links)
1316{
1245{
1317 struct alias_link *link;
1246 struct alias_link *link;
1318
1247
1319 link = _FindLinkIn(la, dst_addr, alias_addr, dst_port, alias_port,
1320 link_type, replace_partial_links);
1248 link = _FindLinkIn(la, dst_addr, alias_addr, dst_port, alias_port,
1249 link_type, replace_partial_links);
1321
1250
1322 if (link == NULL)
1323 {
1324 /* The following allows permanent links to be
1325 specified as using the default aliasing address
1326 (i.e. device interface address) without knowing
1327 in advance what that address is. */
1328 if (la->aliasAddress.s_addr != INADDR_ANY &&
1329 alias_addr.s_addr == la->aliasAddress.s_addr)
1330 {
1331 link = _FindLinkIn(la, dst_addr, la->nullAddress, dst_port, alias_port,
1332 link_type, replace_partial_links);
1333 }
1334 }
1335
1336 return(link);
1251 if (link == NULL) {
1252 /*
1253 * The following allows permanent links to be specified as
1254 * using the default aliasing address (i.e. device
1255 * interface address) without knowing in advance what that
1256 * address is.
1257 */
1258 if (la->aliasAddress.s_addr != INADDR_ANY &&
1259 alias_addr.s_addr == la->aliasAddress.s_addr) {
1260 link = _FindLinkIn(la, dst_addr, la->nullAddress, dst_port, alias_port,
1261 link_type, replace_partial_links);
1262 }
1263 }
1264 return (link);
1337}
1338
1339
1340
1341
1342/* External routines for finding/adding links
1343
1344-- "external" means outside alias_db.c, but within alias*.c --

--- 8 unchanged lines hidden (view full) ---

1353 FindOriginalAddress(), FindAliasAddress()
1354
1355(prototypes in alias_local.h)
1356*/
1357
1358
1359struct alias_link *
1360FindIcmpIn(struct libalias *la, struct in_addr dst_addr,
1265}
1266
1267
1268
1269
1270/* External routines for finding/adding links
1271
1272-- "external" means outside alias_db.c, but within alias*.c --

--- 8 unchanged lines hidden (view full) ---

1281 FindOriginalAddress(), FindAliasAddress()
1282
1283(prototypes in alias_local.h)
1284*/
1285
1286
1287struct alias_link *
1288FindIcmpIn(struct libalias *la, struct in_addr dst_addr,
1361 struct in_addr alias_addr,
1362 u_short id_alias,
1363 int create)
1289 struct in_addr alias_addr,
1290 u_short id_alias,
1291 int create)
1364{
1292{
1365 struct alias_link *link;
1293 struct alias_link *link;
1366
1294
1367 link = FindLinkIn(la, dst_addr, alias_addr,
1368 NO_DEST_PORT, id_alias,
1369 LINK_ICMP, 0);
1370 if (link == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING))
1371 {
1372 struct in_addr target_addr;
1295 link = FindLinkIn(la, dst_addr, alias_addr,
1296 NO_DEST_PORT, id_alias,
1297 LINK_ICMP, 0);
1298 if (link == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
1299 struct in_addr target_addr;
1373
1300
1374 target_addr = FindOriginalAddress(la, alias_addr);
1375 link = AddLink(la, target_addr, dst_addr, alias_addr,
1376 id_alias, NO_DEST_PORT, id_alias,
1377 LINK_ICMP);
1378 }
1379
1380 return (link);
1301 target_addr = FindOriginalAddress(la, alias_addr);
1302 link = AddLink(la, target_addr, dst_addr, alias_addr,
1303 id_alias, NO_DEST_PORT, id_alias,
1304 LINK_ICMP);
1305 }
1306 return (link);
1381}
1382
1383
1384struct alias_link *
1385FindIcmpOut(struct libalias *la, struct in_addr src_addr,
1307}
1308
1309
1310struct alias_link *
1311FindIcmpOut(struct libalias *la, struct in_addr src_addr,
1386 struct in_addr dst_addr,
1387 u_short id,
1388 int create)
1312 struct in_addr dst_addr,
1313 u_short id,
1314 int create)
1389{
1315{
1390 struct alias_link * link;
1316 struct alias_link *link;
1391
1317
1392 link = FindLinkOut(la, src_addr, dst_addr,
1393 id, NO_DEST_PORT,
1394 LINK_ICMP, 0);
1395 if (link == NULL && create)
1396 {
1397 struct in_addr alias_addr;
1318 link = FindLinkOut(la, src_addr, dst_addr,
1319 id, NO_DEST_PORT,
1320 LINK_ICMP, 0);
1321 if (link == NULL && create) {
1322 struct in_addr alias_addr;
1398
1323
1399 alias_addr = FindAliasAddress(la, src_addr);
1400 link = AddLink(la, src_addr, dst_addr, alias_addr,
1401 id, NO_DEST_PORT, GET_ALIAS_ID,
1402 LINK_ICMP);
1403 }
1404
1405 return(link);
1324 alias_addr = FindAliasAddress(la, src_addr);
1325 link = AddLink(la, src_addr, dst_addr, alias_addr,
1326 id, NO_DEST_PORT, GET_ALIAS_ID,
1327 LINK_ICMP);
1328 }
1329 return (link);
1406}
1407
1408
1409struct alias_link *
1410FindFragmentIn1(struct libalias *la, struct in_addr dst_addr,
1330}
1331
1332
1333struct alias_link *
1334FindFragmentIn1(struct libalias *la, struct in_addr dst_addr,
1411 struct in_addr alias_addr,
1412 u_short ip_id)
1335 struct in_addr alias_addr,
1336 u_short ip_id)
1413{
1337{
1414 struct alias_link *link;
1338 struct alias_link *link;
1415
1339
1416 link = FindLinkIn(la, dst_addr, alias_addr,
1417 NO_DEST_PORT, ip_id,
1418 LINK_FRAGMENT_ID, 0);
1340 link = FindLinkIn(la, dst_addr, alias_addr,
1341 NO_DEST_PORT, ip_id,
1342 LINK_FRAGMENT_ID, 0);
1419
1343
1420 if (link == NULL)
1421 {
1422 link = AddLink(la, la->nullAddress, dst_addr, alias_addr,
1423 NO_SRC_PORT, NO_DEST_PORT, ip_id,
1424 LINK_FRAGMENT_ID);
1425 }
1426
1427 return(link);
1344 if (link == NULL) {
1345 link = AddLink(la, la->nullAddress, dst_addr, alias_addr,
1346 NO_SRC_PORT, NO_DEST_PORT, ip_id,
1347 LINK_FRAGMENT_ID);
1348 }
1349 return (link);
1428}
1429
1430
1431struct alias_link *
1350}
1351
1352
1353struct alias_link *
1432FindFragmentIn2(struct libalias *la, struct in_addr dst_addr, /* Doesn't add a link if one */
1433 struct in_addr alias_addr, /* is not found. */
1434 u_short ip_id)
1354FindFragmentIn2(struct libalias *la, struct in_addr dst_addr, /* Doesn't add a link if
1355 * one */
1356 struct in_addr alias_addr, /* is not found. */
1357 u_short ip_id)
1435{
1358{
1436 return FindLinkIn(la, dst_addr, alias_addr,
1437 NO_DEST_PORT, ip_id,
1438 LINK_FRAGMENT_ID, 0);
1359 return FindLinkIn(la, dst_addr, alias_addr,
1360 NO_DEST_PORT, ip_id,
1361 LINK_FRAGMENT_ID, 0);
1439}
1440
1441
1442struct alias_link *
1443AddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr,
1362}
1363
1364
1365struct alias_link *
1366AddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr,
1444 u_short ip_id)
1367 u_short ip_id)
1445{
1368{
1446 return AddLink(la, la->nullAddress, dst_addr, la->nullAddress,
1447 NO_SRC_PORT, NO_DEST_PORT, ip_id,
1448 LINK_FRAGMENT_PTR);
1369 return AddLink(la, la->nullAddress, dst_addr, la->nullAddress,
1370 NO_SRC_PORT, NO_DEST_PORT, ip_id,
1371 LINK_FRAGMENT_PTR);
1449}
1450
1451
1452struct alias_link *
1453FindFragmentPtr(struct libalias *la, struct in_addr dst_addr,
1372}
1373
1374
1375struct alias_link *
1376FindFragmentPtr(struct libalias *la, struct in_addr dst_addr,
1454 u_short ip_id)
1377 u_short ip_id)
1455{
1378{
1456 return FindLinkIn(la, dst_addr, la->nullAddress,
1457 NO_DEST_PORT, ip_id,
1458 LINK_FRAGMENT_PTR, 0);
1379 return FindLinkIn(la, dst_addr, la->nullAddress,
1380 NO_DEST_PORT, ip_id,
1381 LINK_FRAGMENT_PTR, 0);
1459}
1460
1461
1462struct alias_link *
1463FindProtoIn(struct libalias *la, struct in_addr dst_addr,
1382}
1383
1384
1385struct alias_link *
1386FindProtoIn(struct libalias *la, struct in_addr dst_addr,
1464 struct in_addr alias_addr,
1465 u_char proto)
1387 struct in_addr alias_addr,
1388 u_char proto)
1466{
1389{
1467 struct alias_link *link;
1390 struct alias_link *link;
1468
1391
1469 link = FindLinkIn(la, dst_addr, alias_addr,
1470 NO_DEST_PORT, 0,
1471 proto, 1);
1392 link = FindLinkIn(la, dst_addr, alias_addr,
1393 NO_DEST_PORT, 0,
1394 proto, 1);
1472
1395
1473 if (link == NULL && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING))
1474 {
1475 struct in_addr target_addr;
1396 if (link == NULL && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
1397 struct in_addr target_addr;
1476
1398
1477 target_addr = FindOriginalAddress(la, alias_addr);
1478 link = AddLink(la, target_addr, dst_addr, alias_addr,
1479 NO_SRC_PORT, NO_DEST_PORT, 0,
1480 proto);
1481 }
1482
1483 return (link);
1399 target_addr = FindOriginalAddress(la, alias_addr);
1400 link = AddLink(la, target_addr, dst_addr, alias_addr,
1401 NO_SRC_PORT, NO_DEST_PORT, 0,
1402 proto);
1403 }
1404 return (link);
1484}
1485
1486
1487struct alias_link *
1488FindProtoOut(struct libalias *la, struct in_addr src_addr,
1405}
1406
1407
1408struct alias_link *
1409FindProtoOut(struct libalias *la, struct in_addr src_addr,
1489 struct in_addr dst_addr,
1490 u_char proto)
1410 struct in_addr dst_addr,
1411 u_char proto)
1491{
1412{
1492 struct alias_link *link;
1413 struct alias_link *link;
1493
1414
1494 link = FindLinkOut(la, src_addr, dst_addr,
1495 NO_SRC_PORT, NO_DEST_PORT,
1496 proto, 1);
1415 link = FindLinkOut(la, src_addr, dst_addr,
1416 NO_SRC_PORT, NO_DEST_PORT,
1417 proto, 1);
1497
1418
1498 if (link == NULL)
1499 {
1500 struct in_addr alias_addr;
1419 if (link == NULL) {
1420 struct in_addr alias_addr;
1501
1421
1502 alias_addr = FindAliasAddress(la, src_addr);
1503 link = AddLink(la, src_addr, dst_addr, alias_addr,
1504 NO_SRC_PORT, NO_DEST_PORT, 0,
1505 proto);
1506 }
1507
1508 return (link);
1422 alias_addr = FindAliasAddress(la, src_addr);
1423 link = AddLink(la, src_addr, dst_addr, alias_addr,
1424 NO_SRC_PORT, NO_DEST_PORT, 0,
1425 proto);
1426 }
1427 return (link);
1509}
1510
1511
1512struct alias_link *
1513FindUdpTcpIn(struct libalias *la, struct in_addr dst_addr,
1428}
1429
1430
1431struct alias_link *
1432FindUdpTcpIn(struct libalias *la, struct in_addr dst_addr,
1514 struct in_addr alias_addr,
1515 u_short dst_port,
1516 u_short alias_port,
1517 u_char proto,
1518 int create)
1433 struct in_addr alias_addr,
1434 u_short dst_port,
1435 u_short alias_port,
1436 u_char proto,
1437 int create)
1519{
1438{
1520 int link_type;
1521 struct alias_link *link;
1439 int link_type;
1440 struct alias_link *link;
1522
1441
1523 switch (proto)
1524 {
1525 case IPPROTO_UDP:
1526 link_type = LINK_UDP;
1527 break;
1528 case IPPROTO_TCP:
1529 link_type = LINK_TCP;
1530 break;
1531 default:
1532 return NULL;
1533 break;
1534 }
1442 switch (proto) {
1443 case IPPROTO_UDP:
1444 link_type = LINK_UDP;
1445 break;
1446 case IPPROTO_TCP:
1447 link_type = LINK_TCP;
1448 break;
1449 default:
1450 return NULL;
1451 break;
1452 }
1535
1453
1536 link = FindLinkIn(la, dst_addr, alias_addr,
1537 dst_port, alias_port,
1538 link_type, create);
1454 link = FindLinkIn(la, dst_addr, alias_addr,
1455 dst_port, alias_port,
1456 link_type, create);
1539
1457
1540 if (link == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING))
1541 {
1542 struct in_addr target_addr;
1458 if (link == NULL && create && !(la->packetAliasMode & PKT_ALIAS_DENY_INCOMING)) {
1459 struct in_addr target_addr;
1543
1460
1544 target_addr = FindOriginalAddress(la, alias_addr);
1545 link = AddLink(la, target_addr, dst_addr, alias_addr,
1546 alias_port, dst_port, alias_port,
1547 link_type);
1548 }
1549
1550 return(link);
1461 target_addr = FindOriginalAddress(la, alias_addr);
1462 link = AddLink(la, target_addr, dst_addr, alias_addr,
1463 alias_port, dst_port, alias_port,
1464 link_type);
1465 }
1466 return (link);
1551}
1552
1553
1554struct alias_link *
1467}
1468
1469
1470struct alias_link *
1555FindUdpTcpOut(struct libalias *la, struct in_addr src_addr,
1556 struct in_addr dst_addr,
1557 u_short src_port,
1558 u_short dst_port,
1559 u_char proto,
1560 int create)
1471FindUdpTcpOut(struct libalias *la, struct in_addr src_addr,
1472 struct in_addr dst_addr,
1473 u_short src_port,
1474 u_short dst_port,
1475 u_char proto,
1476 int create)
1561{
1477{
1562 int link_type;
1563 struct alias_link *link;
1478 int link_type;
1479 struct alias_link *link;
1564
1480
1565 switch (proto)
1566 {
1567 case IPPROTO_UDP:
1568 link_type = LINK_UDP;
1569 break;
1570 case IPPROTO_TCP:
1571 link_type = LINK_TCP;
1572 break;
1573 default:
1574 return NULL;
1575 break;
1576 }
1481 switch (proto) {
1482 case IPPROTO_UDP:
1483 link_type = LINK_UDP;
1484 break;
1485 case IPPROTO_TCP:
1486 link_type = LINK_TCP;
1487 break;
1488 default:
1489 return NULL;
1490 break;
1491 }
1577
1492
1578 link = FindLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type, create);
1493 link = FindLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type, create);
1579
1494
1580 if (link == NULL && create)
1581 {
1582 struct in_addr alias_addr;
1495 if (link == NULL && create) {
1496 struct in_addr alias_addr;
1583
1497
1584 alias_addr = FindAliasAddress(la, src_addr);
1585 link = AddLink(la, src_addr, dst_addr, alias_addr,
1586 src_port, dst_port, GET_ALIAS_PORT,
1587 link_type);
1588 }
1589
1590 return(link);
1498 alias_addr = FindAliasAddress(la, src_addr);
1499 link = AddLink(la, src_addr, dst_addr, alias_addr,
1500 src_port, dst_port, GET_ALIAS_PORT,
1501 link_type);
1502 }
1503 return (link);
1591}
1592
1593
1594struct alias_link *
1504}
1505
1506
1507struct alias_link *
1595AddPptp(struct libalias *la, struct in_addr src_addr,
1596 struct in_addr dst_addr,
1597 struct in_addr alias_addr,
1598 u_int16_t src_call_id)
1508AddPptp(struct libalias *la, struct in_addr src_addr,
1509 struct in_addr dst_addr,
1510 struct in_addr alias_addr,
1511 u_int16_t src_call_id)
1599{
1512{
1600 struct alias_link *link;
1513 struct alias_link *link;
1601
1514
1602 link = AddLink(la, src_addr, dst_addr, alias_addr,
1603 src_call_id, 0, GET_ALIAS_PORT,
1604 LINK_PPTP);
1515 link = AddLink(la, src_addr, dst_addr, alias_addr,
1516 src_call_id, 0, GET_ALIAS_PORT,
1517 LINK_PPTP);
1605
1518
1606 return (link);
1519 return (link);
1607}
1608
1609
1610struct alias_link *
1611FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr,
1520}
1521
1522
1523struct alias_link *
1524FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr,
1612 struct in_addr dst_addr,
1613 u_int16_t src_call_id)
1525 struct in_addr dst_addr,
1526 u_int16_t src_call_id)
1614{
1527{
1615 u_int i;
1616 struct alias_link *link;
1528 u_int i;
1529 struct alias_link *link;
1617
1530
1618 i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1619 LIST_FOREACH(link, &la->linkTableOut[i], list_out)
1620 if (link->link_type == LINK_PPTP &&
1531 i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1532 LIST_FOREACH(link, &la->linkTableOut[i], list_out)
1533 if (link->link_type == LINK_PPTP &&
1621 link->src_addr.s_addr == src_addr.s_addr &&
1622 link->dst_addr.s_addr == dst_addr.s_addr &&
1623 link->src_port == src_call_id)
1624 break;
1625
1534 link->src_addr.s_addr == src_addr.s_addr &&
1535 link->dst_addr.s_addr == dst_addr.s_addr &&
1536 link->src_port == src_call_id)
1537 break;
1538
1626 return (link);
1539 return (link);
1627}
1628
1629
1630struct alias_link *
1631FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr,
1540}
1541
1542
1543struct alias_link *
1544FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr,
1632 struct in_addr dst_addr,
1633 u_int16_t dst_call_id)
1545 struct in_addr dst_addr,
1546 u_int16_t dst_call_id)
1634{
1547{
1635 u_int i;
1636 struct alias_link *link;
1548 u_int i;
1549 struct alias_link *link;
1637
1550
1638 i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1639 LIST_FOREACH(link, &la->linkTableOut[i], list_out)
1640 if (link->link_type == LINK_PPTP &&
1551 i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1552 LIST_FOREACH(link, &la->linkTableOut[i], list_out)
1553 if (link->link_type == LINK_PPTP &&
1641 link->src_addr.s_addr == src_addr.s_addr &&
1642 link->dst_addr.s_addr == dst_addr.s_addr &&
1643 link->dst_port == dst_call_id)
1644 break;
1645
1554 link->src_addr.s_addr == src_addr.s_addr &&
1555 link->dst_addr.s_addr == dst_addr.s_addr &&
1556 link->dst_port == dst_call_id)
1557 break;
1558
1646 return (link);
1559 return (link);
1647}
1648
1649
1650struct alias_link *
1651FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr,
1560}
1561
1562
1563struct alias_link *
1564FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr,
1652 struct in_addr alias_addr,
1653 u_int16_t dst_call_id)
1565 struct in_addr alias_addr,
1566 u_int16_t dst_call_id)
1654{
1567{
1655 u_int i;
1656 struct alias_link *link;
1568 u_int i;
1569 struct alias_link *link;
1657
1570
1658 i = StartPointIn(alias_addr, 0, LINK_PPTP);
1659 LIST_FOREACH(link, &la->linkTableIn[i], list_in)
1660 if (link->link_type == LINK_PPTP &&
1571 i = StartPointIn(alias_addr, 0, LINK_PPTP);
1572 LIST_FOREACH(link, &la->linkTableIn[i], list_in)
1573 if (link->link_type == LINK_PPTP &&
1661 link->dst_addr.s_addr == dst_addr.s_addr &&
1662 link->alias_addr.s_addr == alias_addr.s_addr &&
1663 link->dst_port == dst_call_id)
1664 break;
1665
1574 link->dst_addr.s_addr == dst_addr.s_addr &&
1575 link->alias_addr.s_addr == alias_addr.s_addr &&
1576 link->dst_port == dst_call_id)
1577 break;
1578
1666 return (link);
1579 return (link);
1667}
1668
1669
1670struct alias_link *
1671FindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr,
1580}
1581
1582
1583struct alias_link *
1584FindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr,
1672 struct in_addr alias_addr,
1673 u_int16_t alias_call_id)
1585 struct in_addr alias_addr,
1586 u_int16_t alias_call_id)
1674{
1587{
1675 struct alias_link *link;
1588 struct alias_link *link;
1676
1589
1677 link = FindLinkIn(la, dst_addr, alias_addr,
1678 0/* any */, alias_call_id,
1679 LINK_PPTP, 0);
1590 link = FindLinkIn(la, dst_addr, alias_addr,
1591 0 /* any */ , alias_call_id,
1592 LINK_PPTP, 0);
1680
1681
1593
1594
1682 return (link);
1595 return (link);
1683}
1684
1685
1686struct alias_link *
1596}
1597
1598
1599struct alias_link *
1687FindRtspOut(struct libalias *la, struct in_addr src_addr,
1688 struct in_addr dst_addr,
1689 u_short src_port,
1690 u_short alias_port,
1691 u_char proto)
1600FindRtspOut(struct libalias *la, struct in_addr src_addr,
1601 struct in_addr dst_addr,
1602 u_short src_port,
1603 u_short alias_port,
1604 u_char proto)
1692{
1605{
1693 int link_type;
1694 struct alias_link *link;
1606 int link_type;
1607 struct alias_link *link;
1695
1608
1696 switch (proto)
1697 {
1698 case IPPROTO_UDP:
1699 link_type = LINK_UDP;
1700 break;
1701 case IPPROTO_TCP:
1702 link_type = LINK_TCP;
1703 break;
1704 default:
1705 return NULL;
1706 break;
1707 }
1609 switch (proto) {
1610 case IPPROTO_UDP:
1611 link_type = LINK_UDP;
1612 break;
1613 case IPPROTO_TCP:
1614 link_type = LINK_TCP;
1615 break;
1616 default:
1617 return NULL;
1618 break;
1619 }
1708
1620
1709 link = FindLinkOut(la, src_addr, dst_addr, src_port, 0, link_type, 1);
1621 link = FindLinkOut(la, src_addr, dst_addr, src_port, 0, link_type, 1);
1710
1622
1711 if (link == NULL)
1712 {
1713 struct in_addr alias_addr;
1623 if (link == NULL) {
1624 struct in_addr alias_addr;
1714
1625
1715 alias_addr = FindAliasAddress(la, src_addr);
1716 link = AddLink(la, src_addr, dst_addr, alias_addr,
1717 src_port, 0, alias_port,
1718 link_type);
1719 }
1720
1721 return(link);
1626 alias_addr = FindAliasAddress(la, src_addr);
1627 link = AddLink(la, src_addr, dst_addr, alias_addr,
1628 src_port, 0, alias_port,
1629 link_type);
1630 }
1631 return (link);
1722}
1723
1724
1725struct in_addr
1726FindOriginalAddress(struct libalias *la, struct in_addr alias_addr)
1727{
1632}
1633
1634
1635struct in_addr
1636FindOriginalAddress(struct libalias *la, struct in_addr alias_addr)
1637{
1728 struct alias_link *link;
1638 struct alias_link *link;
1729
1639
1730 link = FindLinkIn(la, la->nullAddress, alias_addr,
1731 0, 0, LINK_ADDR, 0);
1732 if (link == NULL)
1733 {
1734 la->newDefaultLink = 1;
1735 if (la->targetAddress.s_addr == INADDR_ANY)
1736 return alias_addr;
1737 else if (la->targetAddress.s_addr == INADDR_NONE)
1738 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1739 la->aliasAddress : alias_addr;
1740 else
1741 return la->targetAddress;
1742 }
1743 else
1744 {
1745 if (link->server != NULL) { /* LSNAT link */
1746 struct in_addr src_addr;
1640 link = FindLinkIn(la, la->nullAddress, alias_addr,
1641 0, 0, LINK_ADDR, 0);
1642 if (link == NULL) {
1643 la->newDefaultLink = 1;
1644 if (la->targetAddress.s_addr == INADDR_ANY)
1645 return alias_addr;
1646 else if (la->targetAddress.s_addr == INADDR_NONE)
1647 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1648 la->aliasAddress : alias_addr;
1649 else
1650 return la->targetAddress;
1651 } else {
1652 if (link->server != NULL) { /* LSNAT link */
1653 struct in_addr src_addr;
1747
1654
1748 src_addr = link->server->addr;
1749 link->server = link->server->next;
1750 return (src_addr);
1751 } else if (link->src_addr.s_addr == INADDR_ANY)
1752 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1753 la->aliasAddress : alias_addr;
1754 else
1755 return link->src_addr;
1756 }
1655 src_addr = link->server->addr;
1656 link->server = link->server->next;
1657 return (src_addr);
1658 } else if (link->src_addr.s_addr == INADDR_ANY)
1659 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1660 la->aliasAddress : alias_addr;
1661 else
1662 return link->src_addr;
1663 }
1757}
1758
1759
1760struct in_addr
1761FindAliasAddress(struct libalias *la, struct in_addr original_addr)
1762{
1664}
1665
1666
1667struct in_addr
1668FindAliasAddress(struct libalias *la, struct in_addr original_addr)
1669{
1763 struct alias_link *link;
1670 struct alias_link *link;
1764
1671
1765 link = FindLinkOut(la, original_addr, la->nullAddress,
1766 0, 0, LINK_ADDR, 0);
1767 if (link == NULL)
1768 {
1769 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1770 la->aliasAddress : original_addr;
1771 }
1772 else
1773 {
1774 if (link->alias_addr.s_addr == INADDR_ANY)
1775 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1776 la->aliasAddress : original_addr;
1777 else
1778 return link->alias_addr;
1779 }
1672 link = FindLinkOut(la, original_addr, la->nullAddress,
1673 0, 0, LINK_ADDR, 0);
1674 if (link == NULL) {
1675 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1676 la->aliasAddress : original_addr;
1677 } else {
1678 if (link->alias_addr.s_addr == INADDR_ANY)
1679 return (la->aliasAddress.s_addr != INADDR_ANY) ?
1680 la->aliasAddress : original_addr;
1681 else
1682 return link->alias_addr;
1683 }
1780}
1781
1782
1783/* External routines for getting or changing link data
1784 (external to alias_db.c, but internal to alias*.c)
1785
1786 SetFragmentData(), GetFragmentData()
1787 SetFragmentPtr(), GetFragmentPtr()

--- 5 unchanged lines hidden (view full) ---

1793 SetProtocolFlags(), GetProtocolFlags()
1794 SetDestCallId()
1795*/
1796
1797
1798void
1799SetFragmentAddr(struct alias_link *link, struct in_addr src_addr)
1800{
1684}
1685
1686
1687/* External routines for getting or changing link data
1688 (external to alias_db.c, but internal to alias*.c)
1689
1690 SetFragmentData(), GetFragmentData()
1691 SetFragmentPtr(), GetFragmentPtr()

--- 5 unchanged lines hidden (view full) ---

1697 SetProtocolFlags(), GetProtocolFlags()
1698 SetDestCallId()
1699*/
1700
1701
1702void
1703SetFragmentAddr(struct alias_link *link, struct in_addr src_addr)
1704{
1801 link->data.frag_addr = src_addr;
1705 link->data.frag_addr = src_addr;
1802}
1803
1804
1805void
1806GetFragmentAddr(struct alias_link *link, struct in_addr *src_addr)
1807{
1706}
1707
1708
1709void
1710GetFragmentAddr(struct alias_link *link, struct in_addr *src_addr)
1711{
1808 *src_addr = link->data.frag_addr;
1712 *src_addr = link->data.frag_addr;
1809}
1810
1811
1812void
1813SetFragmentPtr(struct alias_link *link, char *fptr)
1814{
1713}
1714
1715
1716void
1717SetFragmentPtr(struct alias_link *link, char *fptr)
1718{
1815 link->data.frag_ptr = fptr;
1719 link->data.frag_ptr = fptr;
1816}
1817
1818
1819void
1820GetFragmentPtr(struct alias_link *link, char **fptr)
1821{
1720}
1721
1722
1723void
1724GetFragmentPtr(struct alias_link *link, char **fptr)
1725{
1822 *fptr = link->data.frag_ptr;
1726 *fptr = link->data.frag_ptr;
1823}
1824
1825
1826void
1827SetStateIn(struct alias_link *link, int state)
1828{
1727}
1728
1729
1730void
1731SetStateIn(struct alias_link *link, int state)
1732{
1829 /* TCP input state */
1830 switch (state) {
1831 case ALIAS_TCP_STATE_DISCONNECTED:
1832 if (link->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED)
1833 link->expire_time = TCP_EXPIRE_DEAD;
1834 else
1835 link->expire_time = TCP_EXPIRE_SINGLEDEAD;
1836 break;
1837 case ALIAS_TCP_STATE_CONNECTED:
1838 if (link->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED)
1839 link->expire_time = TCP_EXPIRE_CONNECTED;
1840 break;
1841 default:
1842 abort();
1843 }
1844 link->data.tcp->state.in = state;
1733 /* TCP input state */
1734 switch (state) {
1735 case ALIAS_TCP_STATE_DISCONNECTED:
1736 if (link->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED)
1737 link->expire_time = TCP_EXPIRE_DEAD;
1738 else
1739 link->expire_time = TCP_EXPIRE_SINGLEDEAD;
1740 break;
1741 case ALIAS_TCP_STATE_CONNECTED:
1742 if (link->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED)
1743 link->expire_time = TCP_EXPIRE_CONNECTED;
1744 break;
1745 default:
1746 abort();
1747 }
1748 link->data.tcp->state.in = state;
1845}
1846
1847
1848void
1849SetStateOut(struct alias_link *link, int state)
1850{
1749}
1750
1751
1752void
1753SetStateOut(struct alias_link *link, int state)
1754{
1851 /* TCP output state */
1852 switch (state) {
1853 case ALIAS_TCP_STATE_DISCONNECTED:
1854 if (link->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED)
1855 link->expire_time = TCP_EXPIRE_DEAD;
1856 else
1857 link->expire_time = TCP_EXPIRE_SINGLEDEAD;
1858 break;
1859 case ALIAS_TCP_STATE_CONNECTED:
1860 if (link->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED)
1861 link->expire_time = TCP_EXPIRE_CONNECTED;
1862 break;
1863 default:
1864 abort();
1865 }
1866 link->data.tcp->state.out = state;
1755 /* TCP output state */
1756 switch (state) {
1757 case ALIAS_TCP_STATE_DISCONNECTED:
1758 if (link->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED)
1759 link->expire_time = TCP_EXPIRE_DEAD;
1760 else
1761 link->expire_time = TCP_EXPIRE_SINGLEDEAD;
1762 break;
1763 case ALIAS_TCP_STATE_CONNECTED:
1764 if (link->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED)
1765 link->expire_time = TCP_EXPIRE_CONNECTED;
1766 break;
1767 default:
1768 abort();
1769 }
1770 link->data.tcp->state.out = state;
1867}
1868
1869
1870int
1871GetStateIn(struct alias_link *link)
1872{
1771}
1772
1773
1774int
1775GetStateIn(struct alias_link *link)
1776{
1873 /* TCP input state */
1874 return link->data.tcp->state.in;
1777 /* TCP input state */
1778 return link->data.tcp->state.in;
1875}
1876
1877
1878int
1879GetStateOut(struct alias_link *link)
1880{
1779}
1780
1781
1782int
1783GetStateOut(struct alias_link *link)
1784{
1881 /* TCP output state */
1882 return link->data.tcp->state.out;
1785 /* TCP output state */
1786 return link->data.tcp->state.out;
1883}
1884
1885
1886struct in_addr
1887GetOriginalAddress(struct alias_link *link)
1888{
1787}
1788
1789
1790struct in_addr
1791GetOriginalAddress(struct alias_link *link)
1792{
1889 if (link->src_addr.s_addr == INADDR_ANY)
1890 return link->la->aliasAddress;
1891 else
1892 return(link->src_addr);
1793 if (link->src_addr.s_addr == INADDR_ANY)
1794 return link->la->aliasAddress;
1795 else
1796 return (link->src_addr);
1893}
1894
1895
1896struct in_addr
1897GetDestAddress(struct alias_link *link)
1898{
1797}
1798
1799
1800struct in_addr
1801GetDestAddress(struct alias_link *link)
1802{
1899 return(link->dst_addr);
1803 return (link->dst_addr);
1900}
1901
1902
1903struct in_addr
1904GetAliasAddress(struct alias_link *link)
1905{
1804}
1805
1806
1807struct in_addr
1808GetAliasAddress(struct alias_link *link)
1809{
1906 if (link->alias_addr.s_addr == INADDR_ANY)
1907 return link->la->aliasAddress;
1908 else
1909 return link->alias_addr;
1810 if (link->alias_addr.s_addr == INADDR_ANY)
1811 return link->la->aliasAddress;
1812 else
1813 return link->alias_addr;
1910}
1911
1912
1913struct in_addr
1914GetDefaultAliasAddress(struct libalias *la)
1915{
1814}
1815
1816
1817struct in_addr
1818GetDefaultAliasAddress(struct libalias *la)
1819{
1916 return la->aliasAddress;
1820 return la->aliasAddress;
1917}
1918
1919
1920void
1921SetDefaultAliasAddress(struct libalias *la, struct in_addr alias_addr)
1922{
1821}
1822
1823
1824void
1825SetDefaultAliasAddress(struct libalias *la, struct in_addr alias_addr)
1826{
1923 la->aliasAddress = alias_addr;
1827 la->aliasAddress = alias_addr;
1924}
1925
1926
1927u_short
1928GetOriginalPort(struct alias_link *link)
1929{
1828}
1829
1830
1831u_short
1832GetOriginalPort(struct alias_link *link)
1833{
1930 return(link->src_port);
1834 return (link->src_port);
1931}
1932
1933
1934u_short
1935GetAliasPort(struct alias_link *link)
1936{
1835}
1836
1837
1838u_short
1839GetAliasPort(struct alias_link *link)
1840{
1937 return(link->alias_port);
1841 return (link->alias_port);
1938}
1939
1940#ifndef NO_FW_PUNCH
1842}
1843
1844#ifndef NO_FW_PUNCH
1941static u_short
1845static u_short
1942GetDestPort(struct alias_link *link)
1943{
1846GetDestPort(struct alias_link *link)
1847{
1944 return(link->dst_port);
1848 return (link->dst_port);
1945}
1849}
1850
1946#endif
1947
1948void
1949SetAckModified(struct alias_link *link)
1950{
1951/* Indicate that ACK numbers have been modified in a TCP connection */
1851#endif
1852
1853void
1854SetAckModified(struct alias_link *link)
1855{
1856/* Indicate that ACK numbers have been modified in a TCP connection */
1952 link->data.tcp->state.ack_modified = 1;
1857 link->data.tcp->state.ack_modified = 1;
1953}
1954
1955
1956struct in_addr
1957GetProxyAddress(struct alias_link *link)
1958{
1858}
1859
1860
1861struct in_addr
1862GetProxyAddress(struct alias_link *link)
1863{
1959 return link->proxy_addr;
1864 return link->proxy_addr;
1960}
1961
1962
1963void
1964SetProxyAddress(struct alias_link *link, struct in_addr addr)
1965{
1865}
1866
1867
1868void
1869SetProxyAddress(struct alias_link *link, struct in_addr addr)
1870{
1966 link->proxy_addr = addr;
1871 link->proxy_addr = addr;
1967}
1968
1969
1970u_short
1971GetProxyPort(struct alias_link *link)
1972{
1872}
1873
1874
1875u_short
1876GetProxyPort(struct alias_link *link)
1877{
1973 return link->proxy_port;
1878 return link->proxy_port;
1974}
1975
1976
1977void
1978SetProxyPort(struct alias_link *link, u_short port)
1979{
1879}
1880
1881
1882void
1883SetProxyPort(struct alias_link *link, u_short port)
1884{
1980 link->proxy_port = port;
1885 link->proxy_port = port;
1981}
1982
1983
1984int
1985GetAckModified(struct alias_link *link)
1986{
1987/* See if ACK numbers have been modified */
1886}
1887
1888
1889int
1890GetAckModified(struct alias_link *link)
1891{
1892/* See if ACK numbers have been modified */
1988 return link->data.tcp->state.ack_modified;
1893 return link->data.tcp->state.ack_modified;
1989}
1990
1991
1992int
1993GetDeltaAckIn(struct ip *pip, struct alias_link *link)
1994{
1995/*
1996Find out how much the ACK number has been altered for an incoming
1997TCP packet. To do this, a circular list of ACK numbers where the TCP
1998packet size was altered is searched.
1999*/
2000
1894}
1895
1896
1897int
1898GetDeltaAckIn(struct ip *pip, struct alias_link *link)
1899{
1900/*
1901Find out how much the ACK number has been altered for an incoming
1902TCP packet. To do this, a circular list of ACK numbers where the TCP
1903packet size was altered is searched.
1904*/
1905
2001 int i;
2002 struct tcphdr *tc;
2003 int delta, ack_diff_min;
2004 u_long ack;
1906 int i;
1907 struct tcphdr *tc;
1908 int delta, ack_diff_min;
1909 u_long ack;
2005
1910
2006 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
2007 ack = tc->th_ack;
1911 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
1912 ack = tc->th_ack;
2008
1913
2009 delta = 0;
2010 ack_diff_min = -1;
2011 for (i=0; i<N_LINK_TCP_DATA; i++)
2012 {
2013 struct ack_data_record x;
1914 delta = 0;
1915 ack_diff_min = -1;
1916 for (i = 0; i < N_LINK_TCP_DATA; i++) {
1917 struct ack_data_record x;
2014
1918
2015 x = link->data.tcp->ack[i];
2016 if (x.active == 1)
2017 {
2018 int ack_diff;
1919 x = link->data.tcp->ack[i];
1920 if (x.active == 1) {
1921 int ack_diff;
2019
1922
2020 ack_diff = SeqDiff(x.ack_new, ack);
2021 if (ack_diff >= 0)
2022 {
2023 if (ack_diff_min >= 0)
2024 {
2025 if (ack_diff < ack_diff_min)
2026 {
2027 delta = x.delta;
2028 ack_diff_min = ack_diff;
2029 }
2030 }
2031 else
2032 {
2033 delta = x.delta;
2034 ack_diff_min = ack_diff;
2035 }
2036 }
2037 }
2038 }
2039 return (delta);
1923 ack_diff = SeqDiff(x.ack_new, ack);
1924 if (ack_diff >= 0) {
1925 if (ack_diff_min >= 0) {
1926 if (ack_diff < ack_diff_min) {
1927 delta = x.delta;
1928 ack_diff_min = ack_diff;
1929 }
1930 } else {
1931 delta = x.delta;
1932 ack_diff_min = ack_diff;
1933 }
1934 }
1935 }
1936 }
1937 return (delta);
2040}
2041
2042
2043int
2044GetDeltaSeqOut(struct ip *pip, struct alias_link *link)
2045{
2046/*
2047Find out how much the sequence number has been altered for an outgoing
2048TCP packet. To do this, a circular list of ACK numbers where the TCP
2049packet size was altered is searched.
2050*/
2051
1938}
1939
1940
1941int
1942GetDeltaSeqOut(struct ip *pip, struct alias_link *link)
1943{
1944/*
1945Find out how much the sequence number has been altered for an outgoing
1946TCP packet. To do this, a circular list of ACK numbers where the TCP
1947packet size was altered is searched.
1948*/
1949
2052 int i;
2053 struct tcphdr *tc;
2054 int delta, seq_diff_min;
2055 u_long seq;
1950 int i;
1951 struct tcphdr *tc;
1952 int delta, seq_diff_min;
1953 u_long seq;
2056
1954
2057 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
2058 seq = tc->th_seq;
1955 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
1956 seq = tc->th_seq;
2059
1957
2060 delta = 0;
2061 seq_diff_min = -1;
2062 for (i=0; i<N_LINK_TCP_DATA; i++)
2063 {
2064 struct ack_data_record x;
1958 delta = 0;
1959 seq_diff_min = -1;
1960 for (i = 0; i < N_LINK_TCP_DATA; i++) {
1961 struct ack_data_record x;
2065
1962
2066 x = link->data.tcp->ack[i];
2067 if (x.active == 1)
2068 {
2069 int seq_diff;
1963 x = link->data.tcp->ack[i];
1964 if (x.active == 1) {
1965 int seq_diff;
2070
1966
2071 seq_diff = SeqDiff(x.ack_old, seq);
2072 if (seq_diff >= 0)
2073 {
2074 if (seq_diff_min >= 0)
2075 {
2076 if (seq_diff < seq_diff_min)
2077 {
2078 delta = x.delta;
2079 seq_diff_min = seq_diff;
2080 }
2081 }
2082 else
2083 {
2084 delta = x.delta;
2085 seq_diff_min = seq_diff;
2086 }
2087 }
2088 }
2089 }
2090 return (delta);
1967 seq_diff = SeqDiff(x.ack_old, seq);
1968 if (seq_diff >= 0) {
1969 if (seq_diff_min >= 0) {
1970 if (seq_diff < seq_diff_min) {
1971 delta = x.delta;
1972 seq_diff_min = seq_diff;
1973 }
1974 } else {
1975 delta = x.delta;
1976 seq_diff_min = seq_diff;
1977 }
1978 }
1979 }
1980 }
1981 return (delta);
2091}
2092
2093
2094void
2095AddSeq(struct ip *pip, struct alias_link *link, int delta)
2096{
2097/*
2098When a TCP packet has been altered in length, save this
2099information in a circular list. If enough packets have
2100been altered, then this list will begin to overwrite itself.
2101*/
2102
1982}
1983
1984
1985void
1986AddSeq(struct ip *pip, struct alias_link *link, int delta)
1987{
1988/*
1989When a TCP packet has been altered in length, save this
1990information in a circular list. If enough packets have
1991been altered, then this list will begin to overwrite itself.
1992*/
1993
2103 struct tcphdr *tc;
2104 struct ack_data_record x;
2105 int hlen, tlen, dlen;
2106 int i;
1994 struct tcphdr *tc;
1995 struct ack_data_record x;
1996 int hlen, tlen, dlen;
1997 int i;
2107
1998
2108 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
1999 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
2109
2000
2110 hlen = (pip->ip_hl + tc->th_off) << 2;
2111 tlen = ntohs(pip->ip_len);
2112 dlen = tlen - hlen;
2001 hlen = (pip->ip_hl + tc->th_off) << 2;
2002 tlen = ntohs(pip->ip_len);
2003 dlen = tlen - hlen;
2113
2004
2114 x.ack_old = htonl(ntohl(tc->th_seq) + dlen);
2115 x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
2116 x.delta = delta;
2117 x.active = 1;
2005 x.ack_old = htonl(ntohl(tc->th_seq) + dlen);
2006 x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta);
2007 x.delta = delta;
2008 x.active = 1;
2118
2009
2119 i = link->data.tcp->state.index;
2120 link->data.tcp->ack[i] = x;
2010 i = link->data.tcp->state.index;
2011 link->data.tcp->ack[i] = x;
2121
2012
2122 i++;
2123 if (i == N_LINK_TCP_DATA)
2124 link->data.tcp->state.index = 0;
2125 else
2126 link->data.tcp->state.index = i;
2013 i++;
2014 if (i == N_LINK_TCP_DATA)
2015 link->data.tcp->state.index = 0;
2016 else
2017 link->data.tcp->state.index = i;
2127}
2128
2129void
2130SetExpire(struct alias_link *link, int expire)
2131{
2018}
2019
2020void
2021SetExpire(struct alias_link *link, int expire)
2022{
2132 if (expire == 0)
2133 {
2134 link->flags &= ~LINK_PERMANENT;
2135 DeleteLink(link);
2136 }
2137 else if (expire == -1)
2138 {
2139 link->flags |= LINK_PERMANENT;
2140 }
2141 else if (expire > 0)
2142 {
2143 link->expire_time = expire;
2144 }
2145 else
2146 {
2023 if (expire == 0) {
2024 link->flags &= ~LINK_PERMANENT;
2025 DeleteLink(link);
2026 } else if (expire == -1) {
2027 link->flags |= LINK_PERMANENT;
2028 } else if (expire > 0) {
2029 link->expire_time = expire;
2030 } else {
2147#ifdef DEBUG
2031#ifdef DEBUG
2148 fprintf(stderr, "PacketAlias/SetExpire(): ");
2149 fprintf(stderr, "error in expire parameter\n");
2032 fprintf(stderr, "PacketAlias/SetExpire(): ");
2033 fprintf(stderr, "error in expire parameter\n");
2150#endif
2034#endif
2151 }
2035 }
2152}
2153
2154void
2155ClearCheckNewLink(struct libalias *la)
2156{
2036}
2037
2038void
2039ClearCheckNewLink(struct libalias *la)
2040{
2157 la->newDefaultLink = 0;
2041 la->newDefaultLink = 0;
2158}
2159
2160void
2161SetProtocolFlags(struct alias_link *link, int pflags)
2162{
2163
2042}
2043
2044void
2045SetProtocolFlags(struct alias_link *link, int pflags)
2046{
2047
2164 link->pflags = pflags;;
2048 link->pflags = pflags;;
2165}
2166
2167int
2168GetProtocolFlags(struct alias_link *link)
2169{
2170
2049}
2050
2051int
2052GetProtocolFlags(struct alias_link *link)
2053{
2054
2171 return (link->pflags);
2055 return (link->pflags);
2172}
2173
2174void
2175SetDestCallId(struct alias_link *link, u_int16_t cid)
2176{
2056}
2057
2058void
2059SetDestCallId(struct alias_link *link, u_int16_t cid)
2060{
2177 struct libalias *la = link->la;
2061 struct libalias *la = link->la;
2178
2062
2179 la->deleteAllLinks = 1;
2180 link = ReLink(link, link->src_addr, link->dst_addr, link->alias_addr,
2181 link->src_port, cid, link->alias_port, link->link_type);
2182 la->deleteAllLinks = 0;
2063 la->deleteAllLinks = 1;
2064 link = ReLink(link, link->src_addr, link->dst_addr, link->alias_addr,
2065 link->src_port, cid, link->alias_port, link->link_type);
2066 la->deleteAllLinks = 0;
2183}
2184
2185
2186/* Miscellaneous Functions
2187
2188 HouseKeeping()
2189 InitPacketAliasLog()
2190 UninitPacketAliasLog()

--- 6 unchanged lines hidden (view full) ---

2197 every 60 seconds.
2198
2199 (prototype in alias_local.h)
2200*/
2201
2202void
2203HouseKeeping(struct libalias *la)
2204{
2067}
2068
2069
2070/* Miscellaneous Functions
2071
2072 HouseKeeping()
2073 InitPacketAliasLog()
2074 UninitPacketAliasLog()

--- 6 unchanged lines hidden (view full) ---

2081 every 60 seconds.
2082
2083 (prototype in alias_local.h)
2084*/
2085
2086void
2087HouseKeeping(struct libalias *la)
2088{
2205 int i, n, n100;
2206 struct timeval tv;
2207 struct timezone tz;
2089 int i, n, n100;
2090 struct timeval tv;
2091 struct timezone tz;
2208
2092
2209 /*
2210 * Save system time (seconds) in global variable timeStamp for
2211 * use by other functions. This is done so as not to unnecessarily
2212 * waste timeline by making system calls.
2213 */
2214 gettimeofday(&tv, &tz);
2215 la->timeStamp = tv.tv_sec;
2093 /*
2094 * Save system time (seconds) in global variable timeStamp for use
2095 * by other functions. This is done so as not to unnecessarily
2096 * waste timeline by making system calls.
2097 */
2098 gettimeofday(&tv, &tz);
2099 la->timeStamp = tv.tv_sec;
2216
2100
2217 /* Compute number of spokes (output table link chains) to cover */
2218 n100 = LINK_TABLE_OUT_SIZE * 100 + la->houseKeepingResidual;
2219 n100 *= la->timeStamp - la->lastCleanupTime;
2220 n100 /= ALIAS_CLEANUP_INTERVAL_SECS;
2101 /* Compute number of spokes (output table link chains) to cover */
2102 n100 = LINK_TABLE_OUT_SIZE * 100 + la->houseKeepingResidual;
2103 n100 *= la->timeStamp - la->lastCleanupTime;
2104 n100 /= ALIAS_CLEANUP_INTERVAL_SECS;
2221
2105
2222 n = n100/100;
2106 n = n100 / 100;
2223
2107
2224 /* Handle different cases */
2225 if (n > ALIAS_CLEANUP_MAX_SPOKES)
2226 {
2227 n = ALIAS_CLEANUP_MAX_SPOKES;
2228 la->lastCleanupTime = la->timeStamp;
2229 la->houseKeepingResidual = 0;
2108 /* Handle different cases */
2109 if (n > ALIAS_CLEANUP_MAX_SPOKES) {
2110 n = ALIAS_CLEANUP_MAX_SPOKES;
2111 la->lastCleanupTime = la->timeStamp;
2112 la->houseKeepingResidual = 0;
2230
2113
2231 for (i=0; i<n; i++)
2232 IncrementalCleanup(la);
2233 }
2234 else if (n > 0)
2235 {
2236 la->lastCleanupTime = la->timeStamp;
2237 la->houseKeepingResidual = n100 - 100*n;
2114 for (i = 0; i < n; i++)
2115 IncrementalCleanup(la);
2116 } else if (n > 0) {
2117 la->lastCleanupTime = la->timeStamp;
2118 la->houseKeepingResidual = n100 - 100 * n;
2238
2119
2239 for (i=0; i<n; i++)
2240 IncrementalCleanup(la);
2241 }
2242 else if (n < 0)
2243 {
2120 for (i = 0; i < n; i++)
2121 IncrementalCleanup(la);
2122 } else if (n < 0) {
2244#ifdef DEBUG
2123#ifdef DEBUG
2245 fprintf(stderr, "PacketAlias/HouseKeeping(): ");
2246 fprintf(stderr, "something unexpected in time values\n");
2124 fprintf(stderr, "PacketAlias/HouseKeeping(): ");
2125 fprintf(stderr, "something unexpected in time values\n");
2247#endif
2126#endif
2248 la->lastCleanupTime = la->timeStamp;
2249 la->houseKeepingResidual = 0;
2250 }
2127 la->lastCleanupTime = la->timeStamp;
2128 la->houseKeepingResidual = 0;
2129 }
2251}
2252
2253
2254/* Init the log file and enable logging */
2255static void
2256InitPacketAliasLog(struct libalias *la)
2257{
2130}
2131
2132
2133/* Init the log file and enable logging */
2134static void
2135InitPacketAliasLog(struct libalias *la)
2136{
2258 if ((~la->packetAliasMode & PKT_ALIAS_LOG)
2259 && (la->monitorFile = fopen("/var/log/alias.log", "w")))
2260 {
2261 la->packetAliasMode |= PKT_ALIAS_LOG;
2262 fprintf(la->monitorFile,
2263 "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
2264 }
2137 if ((~la->packetAliasMode & PKT_ALIAS_LOG)
2138 && (la->monitorFile = fopen("/var/log/alias.log", "w"))) {
2139 la->packetAliasMode |= PKT_ALIAS_LOG;
2140 fprintf(la->monitorFile,
2141 "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
2142 }
2265}
2266
2267
2268/* Close the log-file and disable logging. */
2269static void
2270UninitPacketAliasLog(struct libalias *la)
2271{
2143}
2144
2145
2146/* Close the log-file and disable logging. */
2147static void
2148UninitPacketAliasLog(struct libalias *la)
2149{
2272 if (la->monitorFile) {
2273 fclose(la->monitorFile);
2274 la->monitorFile = NULL;
2275 }
2276 la->packetAliasMode &= ~PKT_ALIAS_LOG;
2150 if (la->monitorFile) {
2151 fclose(la->monitorFile);
2152 la->monitorFile = NULL;
2153 }
2154 la->packetAliasMode &= ~PKT_ALIAS_LOG;
2277}
2278
2279
2280
2281
2282
2283
2284/* Outside world interfaces

--- 12 unchanged lines hidden (view full) ---

2297 PacketAliasSetMode()
2298
2299(prototypes in alias.h)
2300*/
2301
2302/* Redirection from a specific public addr:port to a
2303 private addr:port */
2304struct alias_link *
2155}
2156
2157
2158
2159
2160
2161
2162/* Outside world interfaces

--- 12 unchanged lines hidden (view full) ---

2175 PacketAliasSetMode()
2176
2177(prototypes in alias.h)
2178*/
2179
2180/* Redirection from a specific public addr:port to a
2181 private addr:port */
2182struct alias_link *
2305LibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_port,
2306 struct in_addr dst_addr, u_short dst_port,
2307 struct in_addr alias_addr, u_short alias_port,
2308 u_char proto)
2183LibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_port,
2184 struct in_addr dst_addr, u_short dst_port,
2185 struct in_addr alias_addr, u_short alias_port,
2186 u_char proto)
2309{
2187{
2310 int link_type;
2311 struct alias_link *link;
2188 int link_type;
2189 struct alias_link *link;
2312
2190
2313 switch(proto)
2314 {
2315 case IPPROTO_UDP:
2316 link_type = LINK_UDP;
2317 break;
2318 case IPPROTO_TCP:
2319 link_type = LINK_TCP;
2320 break;
2321 default:
2191 switch (proto) {
2192 case IPPROTO_UDP:
2193 link_type = LINK_UDP;
2194 break;
2195 case IPPROTO_TCP:
2196 link_type = LINK_TCP;
2197 break;
2198 default:
2322#ifdef DEBUG
2199#ifdef DEBUG
2323 fprintf(stderr, "PacketAliasRedirectPort(): ");
2324 fprintf(stderr, "only TCP and UDP protocols allowed\n");
2200 fprintf(stderr, "PacketAliasRedirectPort(): ");
2201 fprintf(stderr, "only TCP and UDP protocols allowed\n");
2325#endif
2202#endif
2326 return NULL;
2327 }
2203 return NULL;
2204 }
2328
2205
2329 link = AddLink(la, src_addr, dst_addr, alias_addr,
2330 src_port, dst_port, alias_port,
2331 link_type);
2206 link = AddLink(la, src_addr, dst_addr, alias_addr,
2207 src_port, dst_port, alias_port,
2208 link_type);
2332
2209
2333 if (link != NULL)
2334 {
2335 link->flags |= LINK_PERMANENT;
2336 }
2210 if (link != NULL) {
2211 link->flags |= LINK_PERMANENT;
2212 }
2337#ifdef DEBUG
2213#ifdef DEBUG
2338 else
2339 {
2340 fprintf(stderr, "PacketAliasRedirectPort(): "
2341 "call to AddLink() failed\n");
2342 }
2214 else {
2215 fprintf(stderr, "PacketAliasRedirectPort(): "
2216 "call to AddLink() failed\n");
2217 }
2343#endif
2344
2218#endif
2219
2345 return link;
2220 return link;
2346}
2347
2348/* Add server to the pool of servers */
2349int
2350LibAliasAddServer(struct libalias *la, struct alias_link *link, struct in_addr addr, u_short port)
2351{
2221}
2222
2223/* Add server to the pool of servers */
2224int
2225LibAliasAddServer(struct libalias *la, struct alias_link *link, struct in_addr addr, u_short port)
2226{
2352 struct server *server;
2227 struct server *server;
2353
2228
2354 server = malloc(sizeof(struct server));
2229 server = malloc(sizeof(struct server));
2355
2230
2356 if (server != NULL) {
2357 struct server *head;
2231 if (server != NULL) {
2232 struct server *head;
2358
2233
2359 server->addr = addr;
2360 server->port = port;
2234 server->addr = addr;
2235 server->port = port;
2361
2236
2362 head = link->server;
2363 if (head == NULL)
2364 server->next = server;
2365 else {
2366 struct server *s;
2237 head = link->server;
2238 if (head == NULL)
2239 server->next = server;
2240 else {
2241 struct server *s;
2367
2242
2368 for (s = head; s->next != head; s = s->next);
2369 s->next = server;
2370 server->next = head;
2371 }
2372 link->server = server;
2373 return (0);
2374 } else
2375 return (-1);
2243 for (s = head; s->next != head; s = s->next);
2244 s->next = server;
2245 server->next = head;
2246 }
2247 link->server = server;
2248 return (0);
2249 } else
2250 return (-1);
2376}
2377
2378/* Redirect packets of a given IP protocol from a specific
2379 public address to a private address */
2380struct alias_link *
2381LibAliasRedirectProto(struct libalias *la, struct in_addr src_addr,
2251}
2252
2253/* Redirect packets of a given IP protocol from a specific
2254 public address to a private address */
2255struct alias_link *
2256LibAliasRedirectProto(struct libalias *la, struct in_addr src_addr,
2382 struct in_addr dst_addr,
2383 struct in_addr alias_addr,
2384 u_char proto)
2257 struct in_addr dst_addr,
2258 struct in_addr alias_addr,
2259 u_char proto)
2385{
2260{
2386 struct alias_link *link;
2261 struct alias_link *link;
2387
2262
2388 link = AddLink(la, src_addr, dst_addr, alias_addr,
2389 NO_SRC_PORT, NO_DEST_PORT, 0,
2390 proto);
2263 link = AddLink(la, src_addr, dst_addr, alias_addr,
2264 NO_SRC_PORT, NO_DEST_PORT, 0,
2265 proto);
2391
2266
2392 if (link != NULL)
2393 {
2394 link->flags |= LINK_PERMANENT;
2395 }
2267 if (link != NULL) {
2268 link->flags |= LINK_PERMANENT;
2269 }
2396#ifdef DEBUG
2270#ifdef DEBUG
2397 else
2398 {
2399 fprintf(stderr, "PacketAliasRedirectProto(): "
2400 "call to AddLink() failed\n");
2401 }
2271 else {
2272 fprintf(stderr, "PacketAliasRedirectProto(): "
2273 "call to AddLink() failed\n");
2274 }
2402#endif
2403
2275#endif
2276
2404 return link;
2277 return link;
2405}
2406
2407/* Static address translation */
2408struct alias_link *
2409LibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr,
2278}
2279
2280/* Static address translation */
2281struct alias_link *
2282LibAliasRedirectAddr(struct libalias *la, struct in_addr src_addr,
2410 struct in_addr alias_addr)
2283 struct in_addr alias_addr)
2411{
2284{
2412 struct alias_link *link;
2285 struct alias_link *link;
2413
2286
2414 link = AddLink(la, src_addr, la->nullAddress, alias_addr,
2415 0, 0, 0,
2416 LINK_ADDR);
2287 link = AddLink(la, src_addr, la->nullAddress, alias_addr,
2288 0, 0, 0,
2289 LINK_ADDR);
2417
2290
2418 if (link != NULL)
2419 {
2420 link->flags |= LINK_PERMANENT;
2421 }
2291 if (link != NULL) {
2292 link->flags |= LINK_PERMANENT;
2293 }
2422#ifdef DEBUG
2294#ifdef DEBUG
2423 else
2424 {
2425 fprintf(stderr, "PacketAliasRedirectAddr(): "
2426 "call to AddLink() failed\n");
2427 }
2295 else {
2296 fprintf(stderr, "PacketAliasRedirectAddr(): "
2297 "call to AddLink() failed\n");
2298 }
2428#endif
2429
2299#endif
2300
2430 return link;
2301 return link;
2431}
2432
2433
2434/* Mark the aliasing link dynamic */
2435int
2436LibAliasRedirectDynamic(struct libalias *la, struct alias_link *link)
2437{
2438
2302}
2303
2304
2305/* Mark the aliasing link dynamic */
2306int
2307LibAliasRedirectDynamic(struct libalias *la, struct alias_link *link)
2308{
2309
2439 if (link->flags & LINK_PARTIALLY_SPECIFIED)
2440 return (-1);
2441 else {
2442 link->flags &= ~LINK_PERMANENT;
2443 return (0);
2444 }
2310 if (link->flags & LINK_PARTIALLY_SPECIFIED)
2311 return (-1);
2312 else {
2313 link->flags &= ~LINK_PERMANENT;
2314 return (0);
2315 }
2445}
2446
2447
2448void
2449LibAliasRedirectDelete(struct libalias *la, struct alias_link *link)
2450{
2451/* This is a dangerous function to put in the API,
2452 because an invalid pointer can crash the program. */
2453
2316}
2317
2318
2319void
2320LibAliasRedirectDelete(struct libalias *la, struct alias_link *link)
2321{
2322/* This is a dangerous function to put in the API,
2323 because an invalid pointer can crash the program. */
2324
2454 la->deleteAllLinks = 1;
2455 DeleteLink(link);
2456 la->deleteAllLinks = 0;
2325 la->deleteAllLinks = 1;
2326 DeleteLink(link);
2327 la->deleteAllLinks = 0;
2457}
2458
2459
2460void
2461LibAliasSetAddress(struct libalias *la, struct in_addr addr)
2462{
2328}
2329
2330
2331void
2332LibAliasSetAddress(struct libalias *la, struct in_addr addr)
2333{
2463 if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
2464 && la->aliasAddress.s_addr != addr.s_addr)
2465 CleanupAliasData(la);
2334 if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
2335 && la->aliasAddress.s_addr != addr.s_addr)
2336 CleanupAliasData(la);
2466
2337
2467 la->aliasAddress = addr;
2338 la->aliasAddress = addr;
2468}
2469
2470
2471void
2472LibAliasSetTarget(struct libalias *la, struct in_addr target_addr)
2473{
2339}
2340
2341
2342void
2343LibAliasSetTarget(struct libalias *la, struct in_addr target_addr)
2344{
2474 la->targetAddress = target_addr;
2345 la->targetAddress = target_addr;
2475}
2476
2477static void
2478finishoff(void)
2479{
2480
2346}
2347
2348static void
2349finishoff(void)
2350{
2351
2481 while(!LIST_EMPTY(&instancehead))
2352 while (!LIST_EMPTY(&instancehead))
2482 LibAliasUninit(LIST_FIRST(&instancehead));
2483}
2484
2485struct libalias *
2486LibAliasInit(struct libalias *la)
2487{
2353 LibAliasUninit(LIST_FIRST(&instancehead));
2354}
2355
2356struct libalias *
2357LibAliasInit(struct libalias *la)
2358{
2488 int i;
2489 struct timeval tv;
2490 struct timezone tz;
2359 int i;
2360 struct timeval tv;
2361 struct timezone tz;
2491
2362
2492 if (la == NULL)
2493 {
2494 la = calloc(sizeof *la, 1);
2495 if (la == NULL)
2496 return (la);
2497 if (LIST_EMPTY(&instancehead))
2498 atexit(finishoff);
2499 LIST_INSERT_HEAD(&instancehead, la, instancelist);
2500
2501 gettimeofday(&tv, &tz);
2502 la->timeStamp = tv.tv_sec;
2503 la->lastCleanupTime = tv.tv_sec;
2504 la->houseKeepingResidual = 0;
2363 if (la == NULL) {
2364 la = calloc(sizeof *la, 1);
2365 if (la == NULL)
2366 return (la);
2367 if (LIST_EMPTY(&instancehead))
2368 atexit(finishoff);
2369 LIST_INSERT_HEAD(&instancehead, la, instancelist);
2505
2370
2506 for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
2507 LIST_INIT(&la->linkTableOut[i]);
2508 for (i=0; i<LINK_TABLE_IN_SIZE; i++)
2509 LIST_INIT(&la->linkTableIn[i]);
2371 gettimeofday(&tv, &tz);
2372 la->timeStamp = tv.tv_sec;
2373 la->lastCleanupTime = tv.tv_sec;
2374 la->houseKeepingResidual = 0;
2510
2375
2511 }
2512 else
2513 {
2514 la->deleteAllLinks = 1;
2515 CleanupAliasData(la);
2516 la->deleteAllLinks = 0;
2517 }
2376 for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
2377 LIST_INIT(&la->linkTableOut[i]);
2378 for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
2379 LIST_INIT(&la->linkTableIn[i]);
2518
2380
2519 la->aliasAddress.s_addr = INADDR_ANY;
2520 la->targetAddress.s_addr = INADDR_ANY;
2381 } else {
2382 la->deleteAllLinks = 1;
2383 CleanupAliasData(la);
2384 la->deleteAllLinks = 0;
2385 }
2521
2386
2522 la->icmpLinkCount = 0;
2523 la->udpLinkCount = 0;
2524 la->tcpLinkCount = 0;
2525 la->pptpLinkCount = 0;
2526 la->protoLinkCount = 0;
2527 la->fragmentIdLinkCount = 0;
2528 la->fragmentPtrLinkCount = 0;
2529 la->sockCount = 0;
2387 la->aliasAddress.s_addr = INADDR_ANY;
2388 la->targetAddress.s_addr = INADDR_ANY;
2530
2389
2531 la->cleanupIndex =0;
2390 la->icmpLinkCount = 0;
2391 la->udpLinkCount = 0;
2392 la->tcpLinkCount = 0;
2393 la->pptpLinkCount = 0;
2394 la->protoLinkCount = 0;
2395 la->fragmentIdLinkCount = 0;
2396 la->fragmentPtrLinkCount = 0;
2397 la->sockCount = 0;
2532
2398
2533 la->packetAliasMode = PKT_ALIAS_SAME_PORTS
2534 | PKT_ALIAS_USE_SOCKETS
2535 | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
2399 la->cleanupIndex = 0;
2400
2401 la->packetAliasMode = PKT_ALIAS_SAME_PORTS
2402 | PKT_ALIAS_USE_SOCKETS
2403 | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
2536#ifndef NO_FW_PUNCH
2404#ifndef NO_FW_PUNCH
2537 la->fireWallFD = -1;
2405 la->fireWallFD = -1;
2538#endif
2406#endif
2539 return (la);
2407 return (la);
2540}
2541
2542void
2408}
2409
2410void
2543LibAliasUninit(struct libalias *la) {
2544 la->deleteAllLinks = 1;
2545 CleanupAliasData(la);
2546 la->deleteAllLinks = 0;
2547 UninitPacketAliasLog(la);
2411LibAliasUninit(struct libalias *la)
2412{
2413 la->deleteAllLinks = 1;
2414 CleanupAliasData(la);
2415 la->deleteAllLinks = 0;
2416 UninitPacketAliasLog(la);
2548#ifndef NO_FW_PUNCH
2417#ifndef NO_FW_PUNCH
2549 UninitPunchFW(la);
2418 UninitPunchFW(la);
2550#endif
2419#endif
2551 LIST_REMOVE(la, instancelist);
2552 free(la);
2420 LIST_REMOVE(la, instancelist);
2421 free(la);
2553}
2554
2555/* Change mode for some operations */
2556unsigned int
2557LibAliasSetMode(
2558 struct libalias *la,
2422}
2423
2424/* Change mode for some operations */
2425unsigned int
2426LibAliasSetMode(
2427 struct libalias *la,
2559 unsigned int flags, /* Which state to bring flags to */
2560 unsigned int mask /* Mask of which flags to affect (use 0 to do a
2561 probe for flag values) */
2428 unsigned int flags, /* Which state to bring flags to */
2429 unsigned int mask /* Mask of which flags to affect (use 0 to
2430 * do a probe for flag values) */
2562)
2563{
2564/* Enable logging? */
2431)
2432{
2433/* Enable logging? */
2565 if (flags & mask & PKT_ALIAS_LOG)
2566 {
2567 InitPacketAliasLog(la); /* Do the enable */
2568 } else
2434 if (flags & mask & PKT_ALIAS_LOG) {
2435 InitPacketAliasLog(la); /* Do the enable */
2436 } else
2569/* _Disable_ logging? */
2437/* _Disable_ logging? */
2570 if (~flags & mask & PKT_ALIAS_LOG) {
2571 UninitPacketAliasLog(la);
2572 }
2573
2438 if (~flags & mask & PKT_ALIAS_LOG) {
2439 UninitPacketAliasLog(la);
2440 }
2574#ifndef NO_FW_PUNCH
2575/* Start punching holes in the firewall? */
2441#ifndef NO_FW_PUNCH
2442/* Start punching holes in the firewall? */
2576 if (flags & mask & PKT_ALIAS_PUNCH_FW) {
2577 InitPunchFW(la);
2578 } else
2443 if (flags & mask & PKT_ALIAS_PUNCH_FW) {
2444 InitPunchFW(la);
2445 } else
2579/* Stop punching holes in the firewall? */
2446/* Stop punching holes in the firewall? */
2580 if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
2581 UninitPunchFW(la);
2582 }
2447 if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
2448 UninitPunchFW(la);
2449 }
2583#endif
2584
2585/* Other flags can be set/cleared without special action */
2450#endif
2451
2452/* Other flags can be set/cleared without special action */
2586 la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask);
2587 return la->packetAliasMode;
2453 la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask);
2454 return la->packetAliasMode;
2588}
2589
2590
2591int
2592LibAliasCheckNewLink(struct libalias *la)
2593{
2455}
2456
2457
2458int
2459LibAliasCheckNewLink(struct libalias *la)
2460{
2594 return la->newDefaultLink;
2461 return la->newDefaultLink;
2595}
2596
2597
2598#ifndef NO_FW_PUNCH
2599
2600/*****************
2601 Code to support firewall punching. This shouldn't really be in this
2602 file, but making variables global is evil too.
2603 ****************/
2604
2605#ifndef IPFW2
2462}
2463
2464
2465#ifndef NO_FW_PUNCH
2466
2467/*****************
2468 Code to support firewall punching. This shouldn't really be in this
2469 file, but making variables global is evil too.
2470 ****************/
2471
2472#ifndef IPFW2
2606#define IPFW2 1 /* use new ipfw code */
2473#define IPFW2 1 /* use new ipfw code */
2607#endif
2608
2609/* Firewall include files */
2610#include <net/if.h>
2611#include <netinet/ip_fw.h>
2612#include <string.h>
2613#include <err.h>
2614
2474#endif
2475
2476/* Firewall include files */
2477#include <net/if.h>
2478#include <netinet/ip_fw.h>
2479#include <string.h>
2480#include <err.h>
2481
2615#if IPFW2 /* support for new firewall code */
2482#if IPFW2 /* support for new firewall code */
2616/*
2617 * helper function, updates the pointer to cmd with the length
2618 * of the current command, and also cleans up the first word of
2619 * the new command in case it has been clobbered before.
2620 */
2621static ipfw_insn *
2483/*
2484 * helper function, updates the pointer to cmd with the length
2485 * of the current command, and also cleans up the first word of
2486 * the new command in case it has been clobbered before.
2487 */
2488static ipfw_insn *
2622next_cmd(ipfw_insn *cmd)
2489next_cmd(ipfw_insn * cmd)
2623{
2490{
2624 cmd += F_LEN(cmd);
2625 bzero(cmd, sizeof(*cmd));
2626 return cmd;
2491 cmd += F_LEN(cmd);
2492 bzero(cmd, sizeof(*cmd));
2493 return cmd;
2627}
2628
2629/*
2630 * A function to fill simple commands of size 1.
2631 * Existing flags are preserved.
2632 */
2633static ipfw_insn *
2494}
2495
2496/*
2497 * A function to fill simple commands of size 1.
2498 * Existing flags are preserved.
2499 */
2500static ipfw_insn *
2634fill_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, int size,
2635 int flags, u_int16_t arg)
2501fill_cmd(ipfw_insn * cmd, enum ipfw_opcodes opcode, int size,
2502 int flags, u_int16_t arg)
2636{
2503{
2637 cmd->opcode = opcode;
2638 cmd->len = ((cmd->len | flags) & (F_NOT | F_OR)) | (size & F_LEN_MASK);
2639 cmd->arg1 = arg;
2640 return next_cmd(cmd);
2504 cmd->opcode = opcode;
2505 cmd->len = ((cmd->len | flags) & (F_NOT | F_OR)) | (size & F_LEN_MASK);
2506 cmd->arg1 = arg;
2507 return next_cmd(cmd);
2641}
2642
2643static ipfw_insn *
2508}
2509
2510static ipfw_insn *
2644fill_ip(ipfw_insn *cmd1, enum ipfw_opcodes opcode, u_int32_t addr)
2511fill_ip(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int32_t addr)
2645{
2512{
2646 ipfw_insn_ip *cmd = (ipfw_insn_ip *)cmd1;
2513 ipfw_insn_ip *cmd = (ipfw_insn_ip *) cmd1;
2647
2514
2648 cmd->addr.s_addr = addr;
2649 return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u32), 0, 0);
2515 cmd->addr.s_addr = addr;
2516 return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u32), 0, 0);
2650}
2651
2652static ipfw_insn *
2517}
2518
2519static ipfw_insn *
2653fill_one_port(ipfw_insn *cmd1, enum ipfw_opcodes opcode, u_int16_t port)
2520fill_one_port(ipfw_insn * cmd1, enum ipfw_opcodes opcode, u_int16_t port)
2654{
2521{
2655 ipfw_insn_u16 *cmd = (ipfw_insn_u16 *)cmd1;
2522 ipfw_insn_u16 *cmd = (ipfw_insn_u16 *) cmd1;
2656
2523
2657 cmd->ports[0] = cmd->ports[1] = port;
2658 return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u16), 0, 0);
2524 cmd->ports[0] = cmd->ports[1] = port;
2525 return fill_cmd(cmd1, opcode, F_INSN_SIZE(ipfw_insn_u16), 0, 0);
2659}
2660
2661static int
2662fill_rule(void *buf, int bufsize, int rulenum,
2526}
2527
2528static int
2529fill_rule(void *buf, int bufsize, int rulenum,
2663 enum ipfw_opcodes action, int proto,
2664 struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
2530 enum ipfw_opcodes action, int proto,
2531 struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
2665{
2532{
2666 struct ip_fw *rule = (struct ip_fw *)buf;
2667 ipfw_insn *cmd = (ipfw_insn *)rule->cmd;
2533 struct ip_fw *rule = (struct ip_fw *)buf;
2534 ipfw_insn *cmd = (ipfw_insn *) rule->cmd;
2668
2535
2669 bzero(buf, bufsize);
2670 rule->rulenum = rulenum;
2536 bzero(buf, bufsize);
2537 rule->rulenum = rulenum;
2671
2538
2672 cmd = fill_cmd(cmd, O_PROTO, F_INSN_SIZE(ipfw_insn), 0, proto);
2673 cmd = fill_ip(cmd, O_IP_SRC, sa.s_addr);
2674 cmd = fill_one_port(cmd, O_IP_SRCPORT, sp);
2675 cmd = fill_ip(cmd, O_IP_DST, da.s_addr);
2676 cmd = fill_one_port(cmd, O_IP_DSTPORT, dp);
2539 cmd = fill_cmd(cmd, O_PROTO, F_INSN_SIZE(ipfw_insn), 0, proto);
2540 cmd = fill_ip(cmd, O_IP_SRC, sa.s_addr);
2541 cmd = fill_one_port(cmd, O_IP_SRCPORT, sp);
2542 cmd = fill_ip(cmd, O_IP_DST, da.s_addr);
2543 cmd = fill_one_port(cmd, O_IP_DSTPORT, dp);
2677
2544
2678 rule->act_ofs = (u_int32_t *)cmd - (u_int32_t *)rule->cmd;
2679 cmd = fill_cmd(cmd, action, F_INSN_SIZE(ipfw_insn), 0, 0);
2545 rule->act_ofs = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
2546 cmd = fill_cmd(cmd, action, F_INSN_SIZE(ipfw_insn), 0, 0);
2680
2547
2681 rule->cmd_len = (u_int32_t *)cmd - (u_int32_t *)rule->cmd;
2548 rule->cmd_len = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
2682
2549
2683 return ((char *)cmd - (char *)buf);
2550 return ((char *)cmd - (char *)buf);
2684}
2551}
2685#endif /* IPFW2 */
2686
2552
2687static void ClearAllFWHoles(struct libalias *la);
2553#endif /* IPFW2 */
2688
2554
2555static void ClearAllFWHoles(struct libalias *la);
2689
2556
2557
2690#define fw_setfield(la, field, num) \
2691do { \
2692 (field)[(num) - la->fireWallBaseNum] = 1; \
2558#define fw_setfield(la, field, num) \
2559do { \
2560 (field)[(num) - la->fireWallBaseNum] = 1; \
2693} /*lint -save -e717 */ while(0) /*lint -restore */
2561} /*lint -save -e717 */ while(0)/* lint -restore */
2694
2695#define fw_clrfield(la, field, num) \
2696do { \
2697 (field)[(num) - la->fireWallBaseNum] = 0; \
2562
2563#define fw_clrfield(la, field, num) \
2564do { \
2565 (field)[(num) - la->fireWallBaseNum] = 0; \
2698} /*lint -save -e717 */ while(0) /*lint -restore */
2566} /*lint -save -e717 */ while(0)/* lint -restore */
2699
2700#define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
2701
2702static void
2703InitPunchFW(struct libalias *la)
2704{
2705
2567
2568#define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
2569
2570static void
2571InitPunchFW(struct libalias *la)
2572{
2573
2706 la->fireWallField = malloc(la->fireWallNumNums);
2707 if (la->fireWallField) {
2708 memset(la->fireWallField, 0, la->fireWallNumNums);
2709 if (la->fireWallFD < 0) {
2710 la->fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
2711 }
2712 ClearAllFWHoles(la);
2713 la->fireWallActiveNum = la->fireWallBaseNum;
2714 }
2574 la->fireWallField = malloc(la->fireWallNumNums);
2575 if (la->fireWallField) {
2576 memset(la->fireWallField, 0, la->fireWallNumNums);
2577 if (la->fireWallFD < 0) {
2578 la->fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
2579 }
2580 ClearAllFWHoles(la);
2581 la->fireWallActiveNum = la->fireWallBaseNum;
2582 }
2715}
2716
2717static void
2718UninitPunchFW(struct libalias *la)
2719{
2583}
2584
2585static void
2586UninitPunchFW(struct libalias *la)
2587{
2720 ClearAllFWHoles(la);
2721 if (la->fireWallFD >= 0)
2722 close(la->fireWallFD);
2723 la->fireWallFD = -1;
2724 if (la->fireWallField)
2725 free(la->fireWallField);
2726 la->fireWallField = NULL;
2727 la->packetAliasMode &= ~PKT_ALIAS_PUNCH_FW;
2588 ClearAllFWHoles(la);
2589 if (la->fireWallFD >= 0)
2590 close(la->fireWallFD);
2591 la->fireWallFD = -1;
2592 if (la->fireWallField)
2593 free(la->fireWallField);
2594 la->fireWallField = NULL;
2595 la->packetAliasMode &= ~PKT_ALIAS_PUNCH_FW;
2728}
2729
2730/* Make a certain link go through the firewall */
2731void
2732PunchFWHole(struct alias_link *link)
2733{
2596}
2597
2598/* Make a certain link go through the firewall */
2599void
2600PunchFWHole(struct alias_link *link)
2601{
2734 struct libalias *la;
2735 int r; /* Result code */
2736 struct ip_fw rule; /* On-the-fly built rule */
2737 int fwhole; /* Where to punch hole */
2602 struct libalias *la;
2603 int r; /* Result code */
2604 struct ip_fw rule; /* On-the-fly built rule */
2605 int fwhole; /* Where to punch hole */
2738
2606
2739 la = link->la;
2607 la = link->la;
2740
2741/* Don't do anything unless we are asked to */
2608
2609/* Don't do anything unless we are asked to */
2742 if ( !(la->packetAliasMode & PKT_ALIAS_PUNCH_FW) ||
2743 la->fireWallFD < 0 ||
2744 link->link_type != LINK_TCP)
2745 return;
2610 if (!(la->packetAliasMode & PKT_ALIAS_PUNCH_FW) ||
2611 la->fireWallFD < 0 ||
2612 link->link_type != LINK_TCP)
2613 return;
2746
2614
2747 memset(&rule, 0, sizeof rule);
2615 memset(&rule, 0, sizeof rule);
2748
2749/** Build rule **/
2750
2616
2617/** Build rule **/
2618
2751 /* Find empty slot */
2752 for (fwhole = la->fireWallActiveNum;
2753 fwhole < la->fireWallBaseNum + la->fireWallNumNums &&
2754 fw_tstfield(la, la->fireWallField, fwhole);
2755 fwhole++)
2756 ;
2757 if (fwhole == la->fireWallBaseNum + la->fireWallNumNums) {
2758 for (fwhole = la->fireWallBaseNum;
2759 fwhole < la->fireWallActiveNum &&
2760 fw_tstfield(la, la->fireWallField, fwhole);
2761 fwhole++)
2762 ;
2763 if (fwhole == la->fireWallActiveNum) {
2764 /* No rule point empty - we can't punch more holes. */
2765 la->fireWallActiveNum = la->fireWallBaseNum;
2619 /* Find empty slot */
2620 for (fwhole = la->fireWallActiveNum;
2621 fwhole < la->fireWallBaseNum + la->fireWallNumNums &&
2622 fw_tstfield(la, la->fireWallField, fwhole);
2623 fwhole++);
2624 if (fwhole == la->fireWallBaseNum + la->fireWallNumNums) {
2625 for (fwhole = la->fireWallBaseNum;
2626 fwhole < la->fireWallActiveNum &&
2627 fw_tstfield(la, la->fireWallField, fwhole);
2628 fwhole++);
2629 if (fwhole == la->fireWallActiveNum) {
2630 /* No rule point empty - we can't punch more holes. */
2631 la->fireWallActiveNum = la->fireWallBaseNum;
2766#ifdef DEBUG
2632#ifdef DEBUG
2767 fprintf(stderr, "libalias: Unable to create firewall hole!\n");
2633 fprintf(stderr, "libalias: Unable to create firewall hole!\n");
2768#endif
2634#endif
2769 return;
2770 }
2771 }
2772 /* Start next search at next position */
2773 la->fireWallActiveNum = fwhole+1;
2635 return;
2636 }
2637 }
2638 /* Start next search at next position */
2639 la->fireWallActiveNum = fwhole + 1;
2774
2640
2775 /*
2776 * generate two rules of the form
2777 *
2778 * add fwhole accept tcp from OAddr OPort to DAddr DPort
2779 * add fwhole accept tcp from DAddr DPort to OAddr OPort
2780 */
2641 /*
2642 * generate two rules of the form
2643 *
2644 * add fwhole accept tcp from OAddr OPort to DAddr DPort add fwhole
2645 * accept tcp from DAddr DPort to OAddr OPort
2646 */
2781#if IPFW2
2647#if IPFW2
2782 if (GetOriginalPort(link) != 0 && GetDestPort(link) != 0) {
2783 u_int32_t rulebuf[255];
2784 int i;
2648 if (GetOriginalPort(link) != 0 && GetDestPort(link) != 0) {
2649 u_int32_t rulebuf[255];
2650 int i;
2785
2651
2786 i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
2787 O_ACCEPT, IPPROTO_TCP,
2788 GetOriginalAddress(link), ntohs(GetOriginalPort(link)),
2789 GetDestAddress(link), ntohs(GetDestPort(link)) );
2790 r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
2791 if (r)
2792 err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
2652 i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
2653 O_ACCEPT, IPPROTO_TCP,
2654 GetOriginalAddress(link), ntohs(GetOriginalPort(link)),
2655 GetDestAddress(link), ntohs(GetDestPort(link)));
2656 r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
2657 if (r)
2658 err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
2793
2659
2794 i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
2795 O_ACCEPT, IPPROTO_TCP,
2796 GetDestAddress(link), ntohs(GetDestPort(link)),
2797 GetOriginalAddress(link), ntohs(GetOriginalPort(link)) );
2798 r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
2799 if (r)
2800 err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
2801 }
2802#else /* !IPFW2, old code to generate ipfw rule */
2660 i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
2661 O_ACCEPT, IPPROTO_TCP,
2662 GetDestAddress(link), ntohs(GetDestPort(link)),
2663 GetOriginalAddress(link), ntohs(GetOriginalPort(link)));
2664 r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
2665 if (r)
2666 err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
2667 }
2668#else /* !IPFW2, old code to generate ipfw rule */
2803
2669
2804 /* Build generic part of the two rules */
2805 rule.fw_number = fwhole;
2806 IP_FW_SETNSRCP(&rule, 1); /* Number of source ports. */
2807 IP_FW_SETNDSTP(&rule, 1); /* Number of destination ports. */
2808 rule.fw_flg = IP_FW_F_ACCEPT | IP_FW_F_IN | IP_FW_F_OUT;
2809 rule.fw_prot = IPPROTO_TCP;
2810 rule.fw_smsk.s_addr = INADDR_BROADCAST;
2811 rule.fw_dmsk.s_addr = INADDR_BROADCAST;
2670 /* Build generic part of the two rules */
2671 rule.fw_number = fwhole;
2672 IP_FW_SETNSRCP(&rule, 1); /* Number of source ports. */
2673 IP_FW_SETNDSTP(&rule, 1); /* Number of destination ports. */
2674 rule.fw_flg = IP_FW_F_ACCEPT | IP_FW_F_IN | IP_FW_F_OUT;
2675 rule.fw_prot = IPPROTO_TCP;
2676 rule.fw_smsk.s_addr = INADDR_BROADCAST;
2677 rule.fw_dmsk.s_addr = INADDR_BROADCAST;
2812
2678
2813 /* Build and apply specific part of the rules */
2814 rule.fw_src = GetOriginalAddress(link);
2815 rule.fw_dst = GetDestAddress(link);
2816 rule.fw_uar.fw_pts[0] = ntohs(GetOriginalPort(link));
2817 rule.fw_uar.fw_pts[1] = ntohs(GetDestPort(link));
2679 /* Build and apply specific part of the rules */
2680 rule.fw_src = GetOriginalAddress(link);
2681 rule.fw_dst = GetDestAddress(link);
2682 rule.fw_uar.fw_pts[0] = ntohs(GetOriginalPort(link));
2683 rule.fw_uar.fw_pts[1] = ntohs(GetDestPort(link));
2818
2684
2819 /* Skip non-bound links - XXX should not be strictly necessary,
2820 but seems to leave hole if not done. Leak of non-bound links?
2821 (Code should be left even if the problem is fixed - it is a
2822 clear optimization) */
2823 if (rule.fw_uar.fw_pts[0] != 0 && rule.fw_uar.fw_pts[1] != 0) {
2824 r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
2685 /*
2686 * Skip non-bound links - XXX should not be strictly necessary, but
2687 * seems to leave hole if not done. Leak of non-bound links? (Code
2688 * should be left even if the problem is fixed - it is a clear
2689 * optimization)
2690 */
2691 if (rule.fw_uar.fw_pts[0] != 0 && rule.fw_uar.fw_pts[1] != 0) {
2692 r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
2825#ifdef DEBUG
2693#ifdef DEBUG
2826 if (r)
2827 err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
2694 if (r)
2695 err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
2828#endif
2696#endif
2829 rule.fw_src = GetDestAddress(link);
2830 rule.fw_dst = GetOriginalAddress(link);
2831 rule.fw_uar.fw_pts[0] = ntohs(GetDestPort(link));
2832 rule.fw_uar.fw_pts[1] = ntohs(GetOriginalPort(link));
2833 r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
2697 rule.fw_src = GetDestAddress(link);
2698 rule.fw_dst = GetOriginalAddress(link);
2699 rule.fw_uar.fw_pts[0] = ntohs(GetDestPort(link));
2700 rule.fw_uar.fw_pts[1] = ntohs(GetOriginalPort(link));
2701 r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
2834#ifdef DEBUG
2702#ifdef DEBUG
2835 if (r)
2836 err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
2703 if (r)
2704 err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)");
2837#endif
2705#endif
2838 }
2839#endif /* !IPFW2 */
2706 }
2707#endif /* !IPFW2 */
2840/* Indicate hole applied */
2708/* Indicate hole applied */
2841 link->data.tcp->fwhole = fwhole;
2842 fw_setfield(la, la->fireWallField, fwhole);
2709 link->data.tcp->fwhole = fwhole;
2710 fw_setfield(la, la->fireWallField, fwhole);
2843}
2844
2845/* Remove a hole in a firewall associated with a particular alias
2846 link. Calling this too often is harmless. */
2847static void
2848ClearFWHole(struct alias_link *link)
2849{
2850
2711}
2712
2713/* Remove a hole in a firewall associated with a particular alias
2714 link. Calling this too often is harmless. */
2715static void
2716ClearFWHole(struct alias_link *link)
2717{
2718
2851 struct libalias *la;
2719 struct libalias *la;
2852
2720
2853 la = link->la;
2854 if (link->link_type == LINK_TCP) {
2855 int fwhole = link->data.tcp->fwhole; /* Where is the firewall hole? */
2856 struct ip_fw rule;
2721 la = link->la;
2722 if (link->link_type == LINK_TCP) {
2723 int fwhole = link->data.tcp->fwhole; /* Where is the firewall
2724 * hole? */
2725 struct ip_fw rule;
2857
2726
2858 if (fwhole < 0)
2859 return;
2727 if (fwhole < 0)
2728 return;
2860
2729
2861 memset(&rule, 0, sizeof rule); /* useless for ipfw2 */
2730 memset(&rule, 0, sizeof rule); /* useless for ipfw2 */
2862#if IPFW2
2731#if IPFW2
2863 while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL,
2864 &fwhole, sizeof fwhole))
2865 ;
2866#else /* !IPFW2 */
2867 rule.fw_number = fwhole;
2868 while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL,
2869 &rule, sizeof rule))
2870 ;
2871#endif /* !IPFW2 */
2872 fw_clrfield(la, la->fireWallField, fwhole);
2873 link->data.tcp->fwhole = -1;
2874 }
2732 while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL,
2733 &fwhole, sizeof fwhole));
2734#else /* !IPFW2 */
2735 rule.fw_number = fwhole;
2736 while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL,
2737 &rule, sizeof rule));
2738#endif /* !IPFW2 */
2739 fw_clrfield(la, la->fireWallField, fwhole);
2740 link->data.tcp->fwhole = -1;
2741 }
2875}
2876
2877/* Clear out the entire range dedicated to firewall holes. */
2878static void
2742}
2743
2744/* Clear out the entire range dedicated to firewall holes. */
2745static void
2879ClearAllFWHoles(struct libalias *la) {
2880 struct ip_fw rule; /* On-the-fly built rule */
2881 int i;
2746ClearAllFWHoles(struct libalias *la)
2747{
2748 struct ip_fw rule; /* On-the-fly built rule */
2749 int i;
2882
2750
2883 if (la->fireWallFD < 0)
2884 return;
2751 if (la->fireWallFD < 0)
2752 return;
2885
2753
2886 memset(&rule, 0, sizeof rule);
2887 for (i = la->fireWallBaseNum; i < la->fireWallBaseNum + la->fireWallNumNums; i++) {
2754 memset(&rule, 0, sizeof rule);
2755 for (i = la->fireWallBaseNum; i < la->fireWallBaseNum + la->fireWallNumNums; i++) {
2888#if IPFW2
2756#if IPFW2
2889 int r = i;
2890 while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL, &r, sizeof r))
2891 ;
2892#else /* !IPFW2 */
2893 rule.fw_number = i;
2894 while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule))
2895 ;
2896#endif /* !IPFW2 */
2897 }
2898 /* XXX: third arg correct here ? /phk */
2899 memset(la->fireWallField, 0, la->fireWallNumNums);
2757 int r = i;
2758
2759 while (!setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_DEL, &r, sizeof r));
2760#else /* !IPFW2 */
2761 rule.fw_number = i;
2762 while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule));
2763#endif /* !IPFW2 */
2764 }
2765 /* XXX: third arg correct here ? /phk */
2766 memset(la->fireWallField, 0, la->fireWallNumNums);
2900}
2767}
2768
2901#endif
2902
2903void
2769#endif
2770
2771void
2904LibAliasSetFWBase(struct libalias *la, unsigned int base, unsigned int num) {
2772LibAliasSetFWBase(struct libalias *la, unsigned int base, unsigned int num)
2773{
2905#ifndef NO_FW_PUNCH
2774#ifndef NO_FW_PUNCH
2906 la->fireWallBaseNum = base;
2907 la->fireWallNumNums = num;
2775 la->fireWallBaseNum = base;
2776 la->fireWallNumNums = num;
2908#endif
2909}
2910
2911void
2777#endif
2778}
2779
2780void
2912LibAliasSetSkinnyPort(struct libalias *la, unsigned int port) {
2913 la->skinnyPort = port;
2781LibAliasSetSkinnyPort(struct libalias *la, unsigned int port)
2782{
2783 la->skinnyPort = port;
2914}
2784}