+++ /dev/null
-/* -*-c-*-
- *
- * Main header file for port forwarder
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the `fw' port forwarder.
- *
- * `fw' is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * `fw' is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef FW_H
-#define FW_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*----- Header files ------------------------------------------------------*/
-
-/* --- Configuration --- */
-
-#include "config.h"
-#define _GNU_SOURCE
-
-/* --- ANSI C --- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <float.h>
-#include <limits.h>
-#include <math.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* --- Unix --- */
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <pwd.h>
-#include <grp.h>
-
-#include <syslog.h>
-
-/* --- mLib --- */
-
-#include <mLib/alloc.h>
-#include <mLib/bres.h>
-#include <mLib/conn.h>
-#include <mLib/darray.h>
-#include <mLib/dstr.h>
-#include <mLib/env.h>
-#include <mLib/fdflags.h>
-#include <mLib/fdpass.h>
-#include <mLib/ident.h>
-#include <mLib/mdwopt.h>
-#include <mLib/quis.h>
-#include <mLib/report.h>
-#include <mLib/sel.h>
-#include <mLib/selbuf.h>
-#include <mLib/sig.h>
-#include <mLib/str.h>
-#include <mLib/sub.h>
-#include <mLib/sym.h>
-#include <mLib/tv.h>
-
-/*----- Other subtleties --------------------------------------------------*/
-
-#if defined(HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
- extern char **environ;
-#endif
-
-/*----- Main program ------------------------------------------------------*/
-
-/* --- The global select state --- */
-
-extern sel_state *sel;
-
-/* --- Help text --- */
-
-extern const char grammar_text[];
-extern const char option_text[];
-
-/* --- @fw_log@ --- *
- *
- * Arguments: @time_t t@ = when the connection occurred or (@-1@)
- * @const char *fmt@ = format string to fill in
- * @...@ = other arguments
- *
- * Returns: ---
- *
- * Use: Logs a connection.
- */
-
-extern void fw_log(time_t /*t*/, const char */*fmt*/, ...);
-
-/* --- @fw_inc@, @fw_dec@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Increments or decrements the active thing count. `fw' won't
- * quit while there are active things.
- */
-
-extern void fw_inc(void);
-extern void fw_dec(void);
-
-/*----- Channel management ------------------------------------------------*/
-
-/* --- Magic numbers --- */
-
-#define CHAN_BUFSZ 4096
-
-/* --- Channel structure --- */
-
-typedef struct chan {
- unsigned base, len; /* Base and length of data */
- unsigned f; /* Various interesting flags */
- void (*func)(void */*p*/); /* Function to call on closure */
- void *p; /* Argument to pass function */
- sel_file r, w; /* Reader and writer selectors */
- char buf[CHAN_BUFSZ]; /* The actual data buffer */
-} chan;
-
-#define CHANF_CLOSE 1u /* Close channel when buffer empty */
-#define CHANF_READY 2u /* The channel destination exists */
-
-/* --- @chan_close@ --- *
- *
- * Arguments: @chan *c@ = pointer to channel
- *
- * Returns: ---
- *
- * Use: Closes down a channel prematurely.
- */
-
-extern void chan_close(chan */*c*/);
-
-/* --- @chan_dest@ --- *
- *
- * Arguments: @chan *c@ = pointer to channel
- * @int fd@ = destination file descriptor for channel
- *
- * Returns: ---
- *
- * Use: Sets the channel's destination so it knows where to put
- * data.
- */
-
-extern void chan_dest(chan */*c*/, int /*fd*/);
-
-/* --- @chan_open@ --- *
- *
- * Arguments: @chan *c@ = pointer to channel to open
- * @int from, to@ = source and destination file descriptors
- * @void (*func)(void *p)@ = function to call on closure
- * @void *p@ = argument to pass to function
- *
- * Returns: ---
- *
- * Use: Opens a channel. Data is copied from the source to the
- * destination. The @to@ argument may be @-1@ if the file
- * descriptor isn't known yet.
- */
-
-extern void chan_open(chan */*c*/, int /*from*/, int /*to*/,
- void (*/*func*/)(void */*p*/), void */*p*/);
-
-/*----- Character scanners ------------------------------------------------*/
-
-/* --- A low-level scanner source --- */
-
-typedef struct scansrc {
- struct scansrc *next; /* Next one in the list */
- struct scansrc_ops *ops; /* Pointer to operations table */
- char *src; /* Name of this source */
- int line; /* Current line number */
- dstr pushback; /* Pushback characters */
- char *tok; /* Token pushback */
- unsigned t; /* Token type pushback */
-} scansrc;
-
-/* --- Scanner source operations --- */
-
-typedef struct scansrc_ops {
- int (*scan)(scansrc */*ss*/); /* Read another character */
- void (*destroy)(scansrc */*ss*/); /* Destroy an unwanted source */
-} scansrc_ops;
-
-/* --- A character scanner --- */
-
-typedef struct scanner {
- scansrc *head, **tail; /* Scanner list head and tail */
- int t; /* Token type */
- dstr d; /* Current token value */
- const char *wbegin, *wcont; /* Parsing exception strings */
-} scanner;
-
-/* --- @scan_file@ --- *
- *
- * Arguments: @FILE *fp@ = pointer to file descriptor
- * @const char *name@ = pointer to source file name
- * @unsigned f@ = flags
- *
- * Returns: A scanner source.
- *
- * Use: Creates a new scanner source for reading from a file.
- */
-
-#define SCF_NOCLOSE 1u /* Don't close @fp@ when finished */
-
-extern scansrc *scan_file(FILE */*fp*/, const char */*name*/,
- unsigned /*f*/);
-
-/* --- @scan_argv@ --- *
- *
- * Arguments: @char **av@ = pointer to argument array (null terminated)
- *
- * Returns: A scanner source.
- *
- * Use: Creates a new scanner source for reading from an @argv@
- * array.
- */
-
-extern scansrc *scan_argv(char **/*av*/);
-
-/* --- @scan@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to main scanner context
- *
- * Returns: Character read, or end-of-file.
- *
- * Use: Scans a character from a source of characters.
- */
-
-extern int scan(scanner */*sc*/);
-
-/* --- @unscan@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to main scanner context
- * @int ch@ = character to unscan
- *
- * Returns: ---
- *
- * Use: Scans a character from a source of characters.
- */
-
-extern void unscan(scanner */*sc*/, int /*ch*/);
-
-/* --- @scan_push@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to main scanner context
- * @scansrc *ss@ = souorce to push
- *
- * Returns: ---
- *
- * Use: Pushes a scanner source onto the front of the queue.
- */
-
-extern void scan_push(scanner */*sc*/, scansrc */*ss*/);
-
-/* --- @scan_add@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to main scanner context
- * @scansrc *ss@ = souorce to push
- *
- * Returns: ---
- *
- * Use: Adds a scanner source onto the end of the queue.
- */
-
-extern void scan_add(scanner */*sc*/, scansrc */*ss*/);
-
-/* --- @scan_create@ --- *
- *
- * Arguments: @scanner *sc@ = scanner context to initialize
- *
- * Returns: ---
- *
- * Use: Initializes a scanner block ready for use.
- */
-
-extern void scan_create(scanner */*sc*/);
-
-/* --- @scan_destroy@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner context
- *
- * Returns: ---
- *
- * Use: Destroys a scanner and all the sources attached to it.
- */
-
-extern void scan_destroy(scanner */*sc*/);
-
-/*----- Configuration parsing ---------------------------------------------*/
-
-/* --- Magical constants --- */
-
-#define CTOK_EOF (-1)
-#define CTOK_WORD 256
-
-/* --- @conf_undelim@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner definition
- * @const char *d, *dd@ = pointer to characters to escape
- *
- * Returns: ---
- *
- * Use: Modifies the tokenizer. Characters in the first list will
- * always be considered to begin a word. Characters in the
- * second list will always be allowed to continue a word.
- */
-
-extern void conf_undelim(scanner */*sc*/,
- const char */*d*/, const char */*dd*/);
-
-/* --- @token@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner definition
- *
- * Returns: Type of token scanned.
- *
- * Use: Reads the next token from the character scanner.
- */
-
-extern int token(scanner */*sc*/);
-
-/* --- @error@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner definition
- * @const char *msg@ = message skeleton string
- * @...@ = extra arguments for the skeleton
- *
- * Returns: Doesn't
- *
- * Use: Reports an error at the current scanner location.
- */
-
-extern void error(scanner */*sc*/, const char */*msg*/, ...);
-
-/* --- @pushback@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner definition
- *
- * Returns: ---
- *
- * Use: Pushes the current token back. This is normally a precursor
- * to pushing a new scanner source.
- */
-
-extern void pushback(scanner */*sc*/);
-
-/* --- @conf_enum@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to a scanner object
- * @const char *list@ = comma-separated things to allow
- * @unsigned @f = flags for the search
- * @const char *err@ = error message if not found
- *
- * Returns: Index into list, zero-based, or @-1@.
- *
- * Use: Checks whether the current token is a string which matches
- * one of the comma-separated items given. The return value is
- * the index (zero-based) of the matched string in the list.
- *
- * The flags control the behaviour if no exact match is found.
- * If @ENUM_ABBREV@ is set, and the current token is a left
- * substring of exactly one of the possibilities, then that one
- * is chosen. If @ENUM_NONE@ is set, the value @-1@ is
- * returned; otherwise an error is reported and the program is
- * terminated.
- */
-
-#define ENUM_ABBREV 1u
-#define ENUM_NONE 2u
-
-extern int conf_enum(scanner */*sc*/, const char */*list*/,
- unsigned /*flags*/, const char */*err*/);
-
-/* --- @conf_prefix@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to a scanner object
- * @const char *p@ = pointer to prefix string to check
- *
- * Returns: Nonzero if the prefix matches.
- *
- * Use: If the current token is a word matching the given prefix
- * string, then it and an optional `.' character are removed and
- * a nonzero result is returned. Otherwise the current token is
- * left as it is, and zero is returned.
- *
- * Typical options parsing code would remove an expected prefix,
- * scan an option anyway (since qualifying prefixes are
- * optional) and if a match is found, claim the option. If no
- * match is found, and a prefix was stripped, then an error
- * should be reported.
- */
-
-extern int conf_prefix(scanner */*sc*/, const char */*p*/);
-
-/* --- @CONF_BEGIN@, @CONF_END@ --- *
- *
- * Arguments: @sc@ = scanner to read from
- * @prefix@ = prefix to scan for
- * @desc@ = description of what we're parsing
- *
- * Use: Bracket an options parsing routine. The current token is
- * checked to see whether it matches the prefix. If so, it is
- * removed and the following token examined. If that's a `.'
- * then it's removed. If it's a `{' then the enclosed
- * option-parsing code is executed in a loop until a matching
- * '}' is found. If the options parser doesn't accept an
- * option, the behaviour is dependent on whether a prefix was
- * seen: if so, an error is reported; otherwse a zero return is
- * made.
- */
-
-#define CS_PLAIN 0
-#define CS_PREFIX 1
-#define CS_BRACE 2
-#define CS_UNKNOWN 3
-
-#define CONF_BEGIN(sc, prefix, desc) do { \
- scanner *_conf_sc = (sc); \
- const char *_conf_desc = (desc); \
- int _conf_state = CS_PLAIN; \
- \
- /* --- Read the initial prefix --- */ \
- \
- if (_conf_sc->t == CTOK_WORD && \
- strcmp(_conf_sc->d.buf, (prefix)) == 0) { \
- token(_conf_sc); \
- _conf_state = CS_PREFIX; \
- if (_conf_sc->t == '.') \
- token(_conf_sc); \
- else if (_conf_sc->t == '{') { \
- token(_conf_sc); \
- _conf_state = CS_BRACE; \
- } \
- } \
- \
- /* --- Ensure the next token is a word --- */ \
- \
- if (_conf_sc->t != CTOK_WORD) \
- error(_conf_sc, "parse error, expected option keyword"); \
- do {
-
-#define CONF_END \
- \
- /* --- Reject an option --- * \
- * \
- * We could get here as a result of an explicit @CONF_REJECT@ or \
- * because the option wasn't accepted. \
- */ \
- \
- goto _conf_reject; \
- _conf_reject: \
- if (_conf_state == CS_PLAIN) \
- _conf_state = CS_UNKNOWN; \
- else { \
- error(_conf_sc, "unknown %s option `%s'", \
- _conf_desc, _conf_sc->d.buf); \
- } \
- \
- /* --- Accept an option --- * \
- * \
- * It's safe to drop through from above. Either an error will have \
- * been reported, or the state is not @CS_BRACE@. \
- */ \
- \
- _conf_accept: \
- if (_conf_state == CS_BRACE && _conf_sc->t == ';') \
- token(_conf_sc); \
- } while (_conf_state == CS_BRACE && _conf_sc->t == CTOK_WORD); \
- \
- /* --- Check for a closing brace --- */ \
- \
- if (_conf_state == CS_BRACE) { \
- if (_conf_sc->t == '}') \
- token(_conf_sc); \
- else \
- error(_conf_sc, "parse error, expected `}'"); \
- } \
- \
- /* --- Return an appropriate value --- */ \
- \
- return (_conf_state != CS_UNKNOWN); \
-} while (0)
-
-/* --- @CONF_ACCEPT@, @CONF_REJECT@ --- *
- *
- * Arguments: ---
- *
- * Use: Within an options parser (between @CONF_BEGIN@ and
- * @CONF_END@), accept or reject an option.
- */
-
-#define CONF_ACCEPT goto _conf_accept
-#define CONF_REJECT goto _conf_reject
-
-/* --- @CONF_QUAL@ --- *
- *
- * Arguments: ---
- *
- * Use: Evaluates to a nonzero value if the current option is
- * qualified. This can be used to decide whether abbreviations
- * for options should be accepted.
- */
-
-#define CONF_QUAL (_conf_state != CS_PLAIN)
-
-/* --- @conf_name@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner
- * @char delim@ = delimiter character to look for
- * @dstr *d@ = pointer to dynamic string for output
- *
- * Returns: ---
- *
- * Use: Reads in a compound name consisting of words separated by
- * delimiters. Leading and trailing delimiters are permitted,
- * although they'll probably cause confusion if used. The name
- * may be enclosed in square brackets if that helps at all.
- *
- * Examples of compound names are filenames (delimited by `/')
- * and IP addresses (delimited by `.').
- */
-
-extern void conf_name(scanner */*sc*/, char /*delim*/, dstr */*d*/);
-
-/*----- Reference-counted file descriptors --------------------------------*/
-
-typedef struct reffd {
- int fd;
- unsigned ref;
- void (*proc)(void */*p*/);
- void *p;
-} reffd;
-
-/* --- @reffd_init@ --- *
- *
- * Arguments: @int fd@ = file descriptor
- *
- * Returns: Reference-counted file descriptor object.
- *
- * Use: Creates a refcounted file descriptor.
- */
-
-extern reffd *reffd_init(int /*fd*/);
-
-/* --- @reffd_handler@ --- *
- *
- * Arguments: @reffd *r@ = pointer to reference counted filehandle
- * @void (*proc)(void *p)@ = procedure to call
- * @void *p@
- *
- * Returns: ---
- *
- * Use: Sets the reference counted file descriptor to call @proc@
- * when it is no longer required.
- */
-
-extern void reffd_handler(reffd */*r*/, void (*/*proc*/)(void */*p*/),
- void */*p*/);
-
-/* --- @reffd_inc@ --- *
- *
- * Arguments: @reffd *r@ = pointer to reference counted filehandle
- *
- * Returns: ---
- *
- * Use: Increments the reference count for a file descriptor.
- */
-
-#define REFFD_INC(r) do { (r)->ref++; } while (0)
-
-extern void reffd_inc(reffd */*r*/);
-
-/* --- @reffd_dec@ --- *
- *
- * Arguments: @reffd *r@ = pointer to reference counted filehandle
- *
- * Returns: ---
- *
- * Use: Decrements the reference count for a file descriptor.
- */
-
-#define REFFD_DEC(r) do { \
- reffd *_r = (r); \
- _r->ref--; \
- if (_r->ref == 0) { \
- close(_r->fd); \
- if (_r->proc) \
- _r->proc(_r->p); \
- DESTROY(_r); \
- } \
-} while (0)
-
-extern void reffd_dec(reffd */*r*/);
-
-/*----- Sources, targets and endpoints ------------------------------------*/
-
-/* --- Basic endpoint structure --- */
-
-typedef struct endpt {
- struct endpt_ops *ops; /* Pointer to operations table */
- struct endpt *other; /* Pointer to sibling endpoint */
- unsigned f; /* Various flags */
- struct tango *t; /* Private data structure */
- reffd *in, *out; /* File descriptors */
-} endpt;
-
-/* --- Endpoint flags --- */
-
-#define EPF_PENDING 1u /* Endpoint creation in progress */
-#define EPF_FILE 2u /* Endpoint smells like a file */
-
-/* --- Endpoint operations table --- */
-
-typedef struct endpt_ops {
-
- /* --- @attach@ --- *
- *
- * Arguments: @endpt *e@ = pointer to endpoint to be attached
- * @reffd *in, *out@ = input and output file descriptors
- *
- * Returns: ---
- *
- * Use: Instructs a non-file endpoint to attach itself to a pair of
- * files.
- */
-
- void (*attach)(endpt */*e*/, reffd */*in*/, reffd */*out*/);
-
- /* --- @file@ --- *
- *
- * Arguments: @endpt *e@ = pointer to endpoint in question
- * @endpt *f@ = pointer to a file endpoint
- *
- * Returns: ---
- *
- * Use: Informs a non-file endpoint of a file endpoint which will
- * want to be closed when it's finished with. At that time, the
- * endpoint should arrange to have both itself and its partner
- * closed. If no file is registered, the endpoint manager will
- * close both endpoints itself.
- */
-
- void (*file)(endpt */*e*/, endpt */*f*/);
-
- /* --- @wclose@ --- *
- *
- * Arguments: @endpt *e@ = endpoint to be partially closed
- *
- * Returns: ---
- *
- * Use: Announces that the endpoint will not be written to any more.
- */
-
- void (*wclose)(endpt */*e*/);
-
- /* --- @close@ --- *
- *
- * Arguments: @endpt *e@ = endpoint to be closed
- *
- * Returns: ---
- *
- * Use: Completely closes an endpoint. The endpoint's data may be
- * freed, although some endpoints may wish to delay freeing for
- * some reason.
- */
-
- void (*close)(endpt */*e*/);
-
-} endpt_ops;
-
-/* --- A basic target object --- */
-
-typedef struct target {
- struct target_ops *ops;
- char *desc;
-} target;
-
-/* --- Forwarding target operations --- */
-
-typedef struct target_ops {
- const char *name; /* Name of this target */
-
- /* --- @option@ --- *
- *
- * Arguments: @target *t@ = pointer to target object, or zero if global
- * @scanner *sc@ = scanner to read from
- *
- * Returns: Nonzero to claim the option.
- *
- * Use: Handles an option string from the configuration file.
- */
-
- int (*option)(target */*t*/, scanner */*sc*/);
-
- /* --- @read@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner to read from
- *
- * Returns: Pointer to a target object to claim, null to reject.
- *
- * Use: Parses a target description from the configuration file.
- * Only the socket target is allowed to omit the prefix on a
- * target specification.
- */
-
- target *(*read)(scanner */*sc*/);
-
- /* --- @confirm@ --- *
- *
- * Arguments: @target *t@ = pointer to target
- *
- * Returns: ---
- *
- * Use: Confirms configuration of a target.
- */
-
- void (*confirm)(target */*t*/);
-
- /* --- @create@ --- *
- *
- * Arguments: @target *t@ = pointer to target
- * @const char *desc@ = description of connection
- *
- * Returns: Pointer to a created endpoint.
- *
- * Use: Generates a target endpoint for communication.
- */
-
- endpt *(*create)(target */*t*/, const char */*desc*/);
-
- /* --- @destroy@ --- *
- *
- * Arguments: @target *t@ = pointer to target
- *
- * Returns: ---
- *
- * Use: Destroys a target.
- */
-
- void (*destroy)(target */*t*/);
-
-} target_ops;
-
-/* --- A basic source object --- */
-
-typedef struct source {
- struct source *next, *prev;
- struct source_ops *ops;
- char *desc;
-} source;
-
-/* --- Forwarding source operations --- */
-
-typedef struct source_ops {
- const char *name; /* Name of this source */
-
- /* --- @option@ --- *
- *
- * Arguments: @scanner *sc@ = scanner to read from
- * @source *s@ = pointer to source object, or zero if global
- *
- * Returns: Nonzero to claim the option.
- *
- * Use: Handles an option string from the configuration file.
- */
-
- int (*option)(source */*s*/, scanner */*sc*/);
-
- /* --- @read@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner to read from
- *
- * Returns: Pointer to a source object to claim, null to reject.
- *
- * Use: Parses a source description from the configuration file.
- * Only the socket source is allowed to omit the prefix on a
- * source specification.
- */
-
- source *(*read)(scanner */*sc*/);
-
- /* --- @attach@ --- *
- *
- * Arguments: @source *s@ = pointer to source
- * @scanner *sc@ = scanner (for error reporting)
- * @target *t@ = pointer to target to attach
- *
- * Returns: ---
- *
- * Use: Attaches a target to a source.
- */
-
- void (*attach)(source */*s*/, scanner */*sc*/, target */*t*/);
-
- /* --- @destroy@ --- *
- *
- * Arguments: @source *s@ = pointer to source
- *
- * Returns: ---
- *
- * Use: Destroys a source. Used when closing the system down, for
- * example as a result of a signal.
- */
-
- void (*destroy)(source */*s*/);
-
-} source_ops;
-
-/* --- @endpt_kill@ --- *
- *
- * Arguments: @endpt *a@ = an endpoint
- *
- * Returns: ---
- *
- * Use: Kills an endpoint. If the endpoint is joined to another, the
- * other endpoint is also killed, as is the connection between
- * them (and that's the tricky bit).
- */
-
-extern void endpt_kill(endpt */*a*/);
-
-/* --- @endpt_killall@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Destroys all current endpoint connections. Used when
- * shutting down.
- */
-
-extern void endpt_killall(void);
-
-/* --- @endpt_join@ --- *
- *
- * Arguments: @endpt *a@ = pointer to first endpoint
- * @endpt *b@ = pointer to second endpoint
- *
- * Returns: ---
- *
- * Use: Joins two endpoints together.
- */
-
-extern void endpt_join(endpt */*a*/, endpt */*b*/);
-
-/* --- @source_add@ --- *
- *
- * Arguments: @source *s@ = pointer to a source
- *
- * Returns: ---
- *
- * Use: Adds a source to the master list. Only do this for passive
- * sources (e.g., listening sockets), not active sources (e.g.,
- * executable programs).
- */
-
-extern void source_add(source */*s*/);
-
-/* --- @source_remove@ --- *
- *
- * Arguments: @source *s@ = pointer to a source
- *
- * Returns: ---
- *
- * Use: Removes a source from the master list.
- */
-
-extern void source_remove(source */*s*/);
-
-/* --- @source_killall@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Frees all sources.
- */
-
-extern void source_killall(void);
-
-/*----- The exec source and target ----------------------------------------*/
-
-extern source_ops xsource_ops;
-extern target_ops xtarget_ops;
-
-/* --- @exec_init@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Initializes the executable problem source and target.
- */
-
-extern void exec_init(void);
-
-/*----- The file source and target ----------------------------------------*/
-
-extern source_ops fsource_ops;
-extern target_ops ftarget_ops;
-
-/*----- The socket source and target --------------------------------------*/
-
-extern source_ops ssource_ops;
-extern target_ops starget_ops;
-
-/* --- @starget_connected@ --- *
- *
- * Arguments: @int fd@ = file descriptor now ready for use
- * @void *p@ = pointer to an endpoint structure
- *
- * Returns: ---
- *
- * Use: Handles successful connection of the target endpoint.
- */
-
-extern void starget_connected(int /*fd*/, void */*p*/);
-
-/*----- Handling of file attributes ---------------------------------------*/
-
-/* --- File attribute options structure --- */
-
-typedef struct fattr {
- unsigned mode;
- uid_t uid;
- gid_t gid;
-} fattr;
-
-/* --- Shared global options --- */
-
-extern fattr fattr_global;
-
-/* --- @fattr_init@ --- *
- *
- * Arguments: @fattr *f@ = pointer to file attributes
- *
- * Returns: ---
- *
- * Use: Initializes a set of file attributes to default values.
- */
-
-extern void fattr_init(fattr */*f*/);
-
-/* --- @fattr_option@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner to read
- * @fattr *f@ = pointer to file attributes to set
- *
- * Returns: Whether the option was clamed.
- *
- * Use: Reads file attributes from a scanner.
- */
-
-extern int fattr_option(scanner */*sc*/, fattr */*f*/);
-
-/* --- @fattr_apply@ --- *
- *
- * Arguments: @const char *file@ = pointer to filename
- * @fattr *f@ = pointer to attribute set
- *
- * Returns: @-1@ if it failed.
- *
- * Use: Applies file attributes to a file. For best results, try to
- * create the file with the right permissions and so on. This
- * call will fix everything up, but there are potential races
- * which might catch you out if you're not careful.
- */
-
-extern int fattr_apply(const char */*file*/, fattr */*f*/);
-
-/*----- Making privileged connections -------------------------------------*/
-
-/* --- @privconn_split@ --- *
- *
- * Arguments: @sel_state *s@ = select state
- *
- * Returns: ---
- *
- * Use: Splits off the privileged binding code into a separate
- * process.
- */
-
-extern void privconn_split(sel_state */*s*/);
-
-/* --- @privconn_adddest@ --- *
- *
- * Arguments: @struct in_addr peer@ = address to connect to
- * @unsigned port@ = port to connect to
- *
- * Returns: Index for this destination address, or @-1@ if not
- * available.
- *
- * Use: Adds a valid destination for a privileged connection.
- */
-
-extern int privconn_adddest(struct in_addr /*peer*/, unsigned /*port*/);
-
-/* --- @privconn_connect@ --- *
- *
- * Arguments: @conn *c@ = connection structure to fill in
- * @sel_state *s@ = pointer to select state to attach to
- * @int i@ = address index to connect to
- * @struct in_addr bind@ = address to bind to
- * @void (*func)(int, void *)@ = function to call on connect
- * @void *p@ = argument for the function
- *
- * Returns: Zero on success, @-1@ on failure.
- *
- * Use: Sets up a privileged connection job.
- */
-
-extern int privconn_connect(conn */*c*/, sel_state */*s*/,
- int /*i*/, struct in_addr /*bind*/,
- void (*/*func*/)(int, void *), void */*p*/);
-
-/*----- Identifying remote clients ----------------------------------------*/
-
-typedef struct id_req {
- struct sockaddr_in lsin; /* Local address of connection */
- struct sockaddr_in rsin; /* Remote address of connection */
- const char *desc; /* Description of connection */
- const char *act; /* Action taken by server */
- reffd *r; /* Pointer to file descriptor */
-} id_req;
-
-/* --- @identify@ --- *
- *
- * Arguments: @const id_req *q@ = pointer to request block
- *
- * Returns: ---
- *
- * Use: Starts a background ident lookup and reverse-resolve job
- * which will, eventually, report a message to the system log.
- */
-
-extern void identify(const id_req */*q*/);
-
-/*----- Host-based access control -----------------------------------------*/
-
-/* --- An access control entry --- */
-
-typedef struct acl_entry {
- struct acl_entry *next; /* Next entry in the list */
- const struct acl_ops *ops; /* Operations for the ACL entry */
- unsigned act; /* What to do with matching hosts */
-} acl_entry;
-
-#define ACL_DENY 0 /* Deny access to matching conns */
-#define ACL_ALLOW 1 /* Allow access to matching conns */
-#define ACL_PERM 1u /* Bit mask for permission bit */
-
-/* --- Host-based access control --- */
-
-typedef struct acl_host {
- acl_entry a; /* Base structure */
- struct in_addr addr, mask; /* Address and netmask */
-} acl_host;
-
-/* --- ACL methods --- */
-
-typedef struct acl_ops {
- int (*check)(void */*a*/, struct in_addr /*addr*/, unsigned /*port*/);
- void (*dump)(void */*a*/, FILE */*fp*/);
- void (*free)(void */*a*/);
-} acl_ops;
-
-/* --- @acl_check@ --- *
- *
- * Arguments: @acl_entry *a@ = pointer to ACL to check against
- * @struct in_addr addr@ = address to check
- * @unsigned port@ = port number to check
- * @int *act@ = verdict (should initially be @ACT_ALLOW@)
- *
- * Returns: Zero if undecided, nonzero if a rule matched.
- *
- * Use: Checks an address against an ACL.
- */
-
-extern int acl_check(acl_entry */*a*/,
- struct in_addr /*addr*/, unsigned /*port*/,
- int */*act*/);
-
-/* --- @acl_dump@ --- *
- *
- * Arguments: @acl_entry *a@ = pointer to ACL to dump
- * @FILE *fp@ = pointer to stream to dump on
- *
- * Returns: ---
- *
- * Use: Dumps an access control list to an output stream.
- */
-
-extern void acl_dump(acl_entry */*a*/, FILE */*fp*/);
-
-/* --- @acl_free@ --- *
- *
- * Arguments: @acl_entry *a@ = pointer to a list of ACLs
- *
- * Returns: ---
- *
- * Use: Frees all of the memory used by an ACL.
- */
-
-extern void acl_free(acl_entry */*a*/);
-
-/* --- @acl_addhost@ --- *
- *
- * Arguments: @acl_entry ***a@ = address of pointer to list tail
- * @unsigned act@ = what to do with matching addresses
- * @struct in_addr addr, mask@ = address and mask to match
- *
- * Returns: ---
- *
- * Use: Adds a host-authentication entry to the end of an access
- * control list.
- */
-
-extern void acl_addhost(acl_entry ***/*a*/, unsigned /*act*/,
- struct in_addr /*addr*/, struct in_addr /*mask*/);
-
-/* --- @acl_addpriv@ --- *
- *
- * Arguments: @acl_entry ***a@ = address of pointer to list tail
- * @unsigned act@ = what to do with matching addresses
- *
- * Returns: ---
- *
- * Use: Adds a privileged-port check to the end of an access control
- * list.
- */
-
-extern void acl_addpriv(acl_entry ***/*a*/, unsigned /*act*/);
-
-/*----- Network addresses -------------------------------------------------*/
-
-/* --- A generic socket address --- *
- *
- * Not all systems understand @sa_len@ fields. (In particular, Linux
- * doesn't.) Some fairly ugly hacking is then performed on particular
- * address types.
- */
-
-typedef struct addr {
- struct addr_ops *ops;
- size_t sz;
-} addr;
-
-#define ADDRSZ(sz) (sizeof(addr) + (sz))
-
-/* --- Address configuration --- *
- *
- * An address family will want to extend this.
- */
-
-typedef struct addr_opts {
- unsigned f;
-} addr_opts;
-
-#define ADDRF_NOLOG 1u
-
-/* --- Address types --- *
- *
- * For things like Internet addresses, source and destinations look
- * different.
- */
-
-enum {
- ADDR_SRC,
- ADDR_DEST,
- ADDR_GLOBAL
-};
-
-/* --- Description of an address type handler --- */
-
-typedef struct addr_ops {
- const char *name; /* Protocol's internal name */
-
- /* --- @read@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to scanner to read from
- * @unsigned type@ = type of address to be read
- *
- * Returns: A filled-in socket address.
- *
- * Use: Parses a textual representation of a socket address.
- */
-
- addr *(*read)(scanner */*sc*/, unsigned /*type*/);
-
- /* --- @destroy@ --- *
- *
- * Arguments: @addr *a@ = pointer to an address block
- *
- * Returns: ---
- *
- * Use: Disposes of an address block in some suitable fashion.
- */
-
- void (*destroy)(addr */*a*/);
-
- /* --- @print@ --- *
- *
- * Arguments: @addr *a@ = pointer to socket address to read
- * @unsigned type@ = type of address to be written
- * @dstr *d@ = string on which to write the description
- *
- * Returns: ---
- *
- * Use: Writes a textual representation of a socket address to
- * a string.
- */
-
- void (*print)(addr */*a*/, unsigned /*type*/, dstr */*d*/);
-
- /* --- @initsrcopts@ --- *
- *
- * Arguments: ---
- *
- * Returns: A pointer to a protocol-specific data block for a listener
- *
- * Use: Creates a data block for a listener. This is attached to the
- * listener data structure. Options can then be requested, and
- * are added to the block when necessary.
- */
-
- addr_opts *(*initsrcopts)(void);
-
- /* --- @option@ --- *
- *
- * Arguments: @scanner *sc@ = pointer to a scanner to read from
- * @unsigned type@ = kind of option this is
- * @addr_opts *ao@ = data block to modify (from @init@), or null
- *
- * Returns: Nonzero to claim the option.
- *
- * Use: Parses a source option, either global or listener-specific.
- */
-
- int (*option)(scanner */*sc*/, addr_opts */*ao*/, unsigned /*type*/);
-
- /* --- @confirm@ --- *
- *
- * Arguments: @addr *a@ = pointer to an address structure
- * @unsigned type@ = kind of address this is
- * @addr_opts *ao@ = address options
- *
- * Returns: ---
- *
- * Use: Called during initialization when an address is fully
- * configured.
- */
-
- void (*confirm)(addr */*a*/, unsigned /*type*/, addr_opts */*ao*/);
-
- /* --- @freesrcopts@ --- *
- *
- * Arguments: @addr_opts *ao@ = data block to remove
- *
- * Returns: ---
- *
- * Use: Throws away all the configuration data for an address type.
- */
-
- void (*freesrcopts)(addr_opts */*ao*/);
-
- /* --- @bind@ --- *
- *
- * Arguments: @addr *a@ = the address to bind to
- * @addr_opts *ao@ = the address options
- *
- * Returns: File descriptor of bound socket if OK, or @-1@ on error.
- *
- * Use: Binds a listening socket. The tedious stuff with @listen@
- * isn't necessary.
- */
-
- int (*bind)(addr */*a*/, addr_opts */*ao*/);
-
- /* --- @unbind@ --- *
- *
- * Arguments: @addr *a@ = pointer to an address
- *
- * Returns: ---
- *
- * Use: Unbinds an address. This is used when tidying up. The main
- * purpose is to let the Unix-domain handler remove its socket
- * node from the filesystem.
- */
-
- void (*unbind)(addr */*a*/);
-
- /* --- @accept@ --- *
- *
- * Arguments: @int fd@ = listening file descriptor
- * @addr_opts *ao@ = data block to get configuration from
- * @const char *desc@ = description of the listener
- *
- * Returns: Pointer to a reference counted file descriptor.
- *
- * Use: Accepts, verifies and logs an incoming connection.
- */
-
- reffd *(*accept)(int /*fd*/, addr_opts */*ao*/, const char */*desc*/);
-
- /* --- @inittargopts@ --- *
- *
- * Arguments: ---
- *
- * Returns: A pointer to a protocol-specific data block for a connecter
- *
- * Use: Creates a data block for a target. This is attached to the
- * target data structure. Options can then be requested, and
- * are added to the block when necessary.
- */
-
- addr_opts *(*inittargopts)(void);
-
- /* --- @freetargopts@ --- *
- *
- * Arguments: @addr_opts *ao@ = data block to remove
- *
- * Returns: ---
- *
- * Use: Throws away all the configuration data for an address type.
- */
-
- void (*freetargopts)(addr_opts */*ao*/);
-
- /* --- @connect@ --- *
- *
- * Arguments: @addr *a@ = destination address
- * @addr_opts *ao@ = target address options
- * @conn *c@ = connection structure
- * @endpt *e@ = endpoint structure
- *
- * Returns: Zero if OK, @-1@ on some error.
- *
- * Use: Requests that a connection be made, or at least set in
- * motion. An address may do one of these things:
- *
- * * Return @-1@.
- *
- * * Call @starget_connected@ with @-1@ or a connected file
- * descriptor and the pointer @e@.
- *
- * * Call @conn_init@ or @conn_fd@, giving @starget_connected@
- * and @e@ as the function to call.
- */
-
- int (*connect)(addr */*a*/, addr_opts */*ao*/, conn */*c*/, endpt */*e*/);
-
-} addr_ops;
-
-/* --- Address types --- */
-
-extern addr_ops un_ops;
-extern addr_ops inet_ops;
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif