chiark / gitweb /
Merge branch 'fwd'
[fwd] / fwd.h
1 /* -*-c-*-
2  *
3  * Main header file for port forwarder
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the `fwd' port forwarder.
11  *
12  * `fwd' is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * `fwd' is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with `fwd'; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 #ifndef FW_H
28 #define FW_H
29
30 #ifdef __cplusplus
31   extern "C" {
32 #endif
33
34 /*----- Header files ------------------------------------------------------*/
35
36 /* --- Configuration --- */
37
38 #include "config.h"
39 #define _GNU_SOURCE
40
41 /* --- ANSI C --- */
42
43 #include <assert.h>
44 #include <ctype.h>
45 #include <errno.h>
46 #include <float.h>
47 #include <limits.h>
48 #include <math.h>
49 #include <signal.h>
50 #include <stdarg.h>
51 #include <stddef.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <time.h>
56
57 /* --- Unix --- */
58
59 #include <fcntl.h>
60 #include <unistd.h>
61
62 #include <sys/types.h>
63 #include <sys/stat.h>
64 #include <sys/time.h>
65 #include <sys/uio.h>
66 #include <sys/wait.h>
67
68 #include <sys/socket.h>
69 #include <sys/un.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 #include <netdb.h>
73
74 #include <pwd.h>
75 #include <grp.h>
76
77 #include <syslog.h>
78
79 /* --- mLib --- */
80
81 #include <mLib/alloc.h>
82 #include <mLib/bres.h>
83 #include <mLib/conn.h>
84 #include <mLib/darray.h>
85 #include <mLib/dstr.h>
86 #include <mLib/env.h>
87 #include <mLib/fdflags.h>
88 #include <mLib/fdpass.h>
89 #include <mLib/ident.h>
90 #include <mLib/mdwopt.h>
91 #include <mLib/quis.h>
92 #include <mLib/report.h>
93 #include <mLib/sel.h>
94 #include <mLib/selbuf.h>
95 #include <mLib/sig.h>
96 #include <mLib/str.h>
97 #include <mLib/sub.h>
98 #include <mLib/sym.h>
99 #include <mLib/tv.h>
100
101 /*----- Other subtleties --------------------------------------------------*/
102
103 #if defined(HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
104   extern char **environ;
105 #endif
106
107 /*----- Main program ------------------------------------------------------*/
108
109 /* --- The global select state --- */
110
111 extern sel_state *sel;
112
113 /* --- Help text --- */
114
115 extern const char grammar_text[];
116 extern const char option_text[];
117
118 /* --- @fw_log@ --- *
119  *
120  * Arguments:   @time_t t@ = when the connection occurred or (@-1@)
121  *              @const char *fmt@ = format string to fill in
122  *              @...@ = other arguments
123  *
124  * Returns:     ---
125  *
126  * Use:         Logs a connection.
127  */
128
129 extern void fw_log(time_t /*t*/, const char */*fmt*/, ...);
130
131 /* --- @fw_inc@, @fw_dec@ --- *
132  *
133  * Arguments:   ---
134  *
135  * Returns:     ---
136  *
137  * Use:         Increments or decrements the active thing count.  `fwd' won't
138  *              quit while there are active things.
139  */
140
141 extern void fw_inc(void);
142 extern void fw_dec(void);
143
144 /*----- Channel management ------------------------------------------------*/
145
146 /* --- Magic numbers --- */
147
148 #define CHAN_BUFSZ 4096
149
150 /* --- Channel structure --- */
151
152 typedef struct chan {
153   unsigned base, len;                   /* Base and length of data */
154   unsigned f;                           /* Various interesting flags */
155   void (*func)(void */*p*/);            /* Function to call on closure */
156   void *p;                              /* Argument to pass function */
157   sel_file r, w;                        /* Reader and writer selectors */
158   char buf[CHAN_BUFSZ];                 /* The actual data buffer */
159 } chan;
160
161 #define CHANF_CLOSE 1u                  /* Close channel when buffer empty */
162 #define CHANF_READY 2u                  /* The channel destination exists */
163
164 /* --- @chan_close@ --- *
165  *
166  * Arguments:   @chan *c@ = pointer to channel
167  *
168  * Returns:     ---
169  *
170  * Use:         Closes down a channel prematurely.
171  */
172
173 extern void chan_close(chan */*c*/);
174
175 /* --- @chan_dest@ --- *
176  *
177  * Arguments:   @chan *c@ = pointer to channel
178  *              @int fd@ = destination file descriptor for channel
179  *
180  * Returns:     ---
181  *
182  * Use:         Sets the channel's destination so it knows where to put
183  *              data.
184  */
185
186 extern void chan_dest(chan */*c*/, int /*fd*/);
187
188 /* --- @chan_open@ --- *
189  *
190  * Arguments:   @chan *c@ = pointer to channel to open
191  *              @int from, to@ = source and destination file descriptors
192  *              @void (*func)(void *p)@ = function to call on closure
193  *              @void *p@ = argument to pass to function
194  *
195  * Returns:     ---
196  *
197  * Use:         Opens a channel.  Data is copied from the source to the
198  *              destination.  The @to@ argument may be @-1@ if the file
199  *              descriptor isn't known yet.
200  */
201
202 extern void chan_open(chan */*c*/, int /*from*/, int /*to*/,
203                       void (*/*func*/)(void */*p*/), void */*p*/);
204
205 /*----- Character scanners ------------------------------------------------*/
206
207 /* --- A low-level scanner source --- */
208
209 typedef struct scansrc {
210   struct scansrc *next;                 /* Next one in the list */
211   struct scansrc_ops *ops;              /* Pointer to operations table */
212   char *src;                            /* Name of this source */
213   int line;                             /* Current line number */
214   dstr pushback;                        /* Pushback characters */
215   char *tok;                            /* Token pushback */
216   unsigned t;                           /* Token type pushback */
217 } scansrc;
218
219 /* --- Scanner source operations --- */
220
221 typedef struct scansrc_ops {
222   int (*scan)(scansrc */*ss*/);         /* Read another character */
223   void (*destroy)(scansrc */*ss*/);     /* Destroy an unwanted source */
224 } scansrc_ops;
225
226 /* --- A character scanner --- */
227
228 typedef struct scanner {
229   scansrc *head, **tail;                /* Scanner list head and tail */
230   int t;                                /* Token type */
231   dstr d;                               /* Current token value */
232   const char *wbegin, *wcont;           /* Parsing exception strings */
233 } scanner;
234
235 /* --- @scan_file@ --- *
236  *
237  * Arguments:   @FILE *fp@ = pointer to file descriptor
238  *              @const char *name@ = pointer to source file name
239  *              @unsigned f@ = flags
240  *
241  * Returns:     A scanner source.
242  *
243  * Use:         Creates a new scanner source for reading from a file.
244  */
245
246 #define SCF_NOCLOSE 1u                  /* Don't close @fp@ when finished */
247
248 extern scansrc *scan_file(FILE */*fp*/, const char */*name*/,
249                           unsigned /*f*/);
250
251 /* --- @scan_argv@ --- *
252  *
253  * Arguments:   @char **av@ = pointer to argument array (null terminated)
254  *
255  * Returns:     A scanner source.
256  *
257  * Use:         Creates a new scanner source for reading from an @argv@
258  *              array.
259  */
260
261 extern scansrc *scan_argv(char **/*av*/);
262
263 /* --- @scan@ --- *
264  *
265  * Arguments:   @scanner *sc@ = pointer to main scanner context
266  *
267  * Returns:     Character read, or end-of-file.
268  *
269  * Use:         Scans a character from a source of characters.
270  */
271
272 extern int scan(scanner */*sc*/);
273
274 /* --- @unscan@ --- *
275  *
276  * Arguments:   @scanner *sc@ = pointer to main scanner context
277  *              @int ch@ = character to unscan
278  *
279  * Returns:     ---
280  *
281  * Use:         Scans a character from a source of characters.
282  */
283
284 extern void unscan(scanner */*sc*/, int /*ch*/);
285
286 /* --- @scan_push@ --- *
287  *
288  * Arguments:   @scanner *sc@ = pointer to main scanner context
289  *              @scansrc *ss@ = souorce to push
290  *
291  * Returns:     ---
292  *
293  * Use:         Pushes a scanner source onto the front of the queue.
294  */
295
296 extern void scan_push(scanner */*sc*/, scansrc */*ss*/);
297
298 /* --- @scan_add@ --- *
299  *
300  * Arguments:   @scanner *sc@ = pointer to main scanner context
301  *              @scansrc *ss@ = souorce to push
302  *
303  * Returns:     ---
304  *
305  * Use:         Adds a scanner source onto the end of the queue.
306  */
307
308 extern void scan_add(scanner */*sc*/, scansrc */*ss*/);
309
310 /* --- @scan_create@ --- *
311  *
312  * Arguments:   @scanner *sc@ = scanner context to initialize
313  *
314  * Returns:     ---
315  *
316  * Use:         Initializes a scanner block ready for use.
317  */
318
319 extern void scan_create(scanner */*sc*/);
320
321 /* --- @scan_destroy@ --- *
322  *
323  * Arguments:   @scanner *sc@ = pointer to scanner context
324  *
325  * Returns:     ---
326  *
327  * Use:         Destroys a scanner and all the sources attached to it.
328  */
329
330 extern void scan_destroy(scanner */*sc*/);
331
332 /*----- Configuration parsing ---------------------------------------------*/
333
334 /* --- Magical constants --- */
335
336 #define CTOK_EOF (-1)
337 #define CTOK_WORD 256
338
339 /* --- @conf_undelim@ --- *
340  *
341  * Arguments:   @scanner *sc@ = pointer to scanner definition
342  *              @const char *d, *dd@ = pointer to characters to escape
343  *
344  * Returns:     ---
345  *
346  * Use:         Modifies the tokenizer.  Characters in the first list will
347  *              always be considered to begin a word.  Characters in the
348  *              second list will always be allowed to continue a word.
349  */
350
351 extern void conf_undelim(scanner */*sc*/,
352                          const char */*d*/, const char */*dd*/);
353
354 /* --- @token@ --- *
355  *
356  * Arguments:   @scanner *sc@ = pointer to scanner definition
357  *
358  * Returns:     Type of token scanned.
359  *
360  * Use:         Reads the next token from the character scanner.
361  */
362
363 extern int token(scanner */*sc*/);
364
365 /* --- @error@ --- *
366  *
367  * Arguments:   @scanner *sc@ = pointer to scanner definition
368  *              @const char *msg@ = message skeleton string
369  *              @...@ = extra arguments for the skeleton
370  *
371  * Returns:     Doesn't
372  *
373  * Use:         Reports an error at the current scanner location.
374  */
375
376 extern void error(scanner */*sc*/, const char */*msg*/, ...);
377
378 /* --- @pushback@ --- *
379  *
380  * Arguments:   @scanner *sc@ = pointer to scanner definition
381  *
382  * Returns:     ---
383  *
384  * Use:         Pushes the current token back.  This is normally a precursor
385  *              to pushing a new scanner source.
386  */
387
388 extern void pushback(scanner */*sc*/);
389
390 /* --- @conf_enum@ --- *
391  *
392  * Arguments:   @scanner *sc@ = pointer to a scanner object
393  *              @const char *list@ = comma-separated things to allow
394  *              @unsigned @f = flags for the search
395  *              @const char *err@ = error message if not found
396  *
397  * Returns:     Index into list, zero-based, or @-1@.
398  *
399  * Use:         Checks whether the current token is a string which matches
400  *              one of the comma-separated items given.  The return value is
401  *              the index (zero-based) of the matched string in the list.
402  *
403  *              The flags control the behaviour if no exact match is found.
404  *              If @ENUM_ABBREV@ is set, and the current token is a left
405  *              substring of exactly one of the possibilities, then that one
406  *              is chosen.  If @ENUM_NONE@ is set, the value @-1@ is
407  *              returned; otherwise an error is reported and the program is
408  *              terminated.
409  */
410
411 #define ENUM_ABBREV 1u
412 #define ENUM_NONE 2u
413
414 extern int conf_enum(scanner */*sc*/, const char */*list*/,
415                      unsigned /*flags*/, const char */*err*/);
416
417 /* --- @conf_prefix@ --- *
418  *
419  * Arguments:   @scanner *sc@ = pointer to a scanner object
420  *              @const char *p@ = pointer to prefix string to check
421  *
422  * Returns:     Nonzero if the prefix matches.
423  *
424  * Use:         If the current token is a word matching the given prefix
425  *              string, then it and an optional `.' character are removed and
426  *              a nonzero result is returned.  Otherwise the current token is
427  *              left as it is, and zero is returned.
428  *
429  *              Typical options parsing code would remove an expected prefix,
430  *              scan an option anyway (since qualifying prefixes are
431  *              optional) and if a match is found, claim the option.  If no
432  *              match is found, and a prefix was stripped, then an error
433  *              should be reported.
434  */
435
436 extern int conf_prefix(scanner */*sc*/, const char */*p*/);
437
438 /* --- @CONF_BEGIN@, @CONF_END@ --- *
439  *
440  * Arguments:   @sc@ = scanner to read from
441  *              @prefix@ = prefix to scan for
442  *              @desc@ = description of what we're parsing
443  *
444  * Use:         Bracket an options parsing routine.  The current token is
445  *              checked to see whether it matches the prefix.  If so, it is
446  *              removed and the following token examined.  If that's a `.'
447  *              then it's removed.  If it's a `{' then the enclosed
448  *              option-parsing code is executed in a loop until a matching
449  *              '}' is found.  If the options parser doesn't accept an
450  *              option, the behaviour is dependent on whether a prefix was
451  *              seen: if so, an error is reported; otherwse a zero return is
452  *              made.
453  */
454
455 #define CS_PLAIN 0
456 #define CS_PREFIX 1
457 #define CS_BRACE 2
458 #define CS_UNKNOWN 3
459
460 #define CONF_BEGIN(sc, prefix, desc) do {                               \
461   scanner *_conf_sc = (sc);                                             \
462   const char *_conf_desc = (desc);                                      \
463   int _conf_state = CS_PLAIN;                                           \
464                                                                         \
465   /* --- Read the initial prefix --- */                                 \
466                                                                         \
467   if (_conf_sc->t == CTOK_WORD &&                                       \
468       strcmp(_conf_sc->d.buf, (prefix)) == 0) {                         \
469     token(_conf_sc);                                                    \
470     _conf_state = CS_PREFIX;                                            \
471     if (_conf_sc->t == '.')                                             \
472       token(_conf_sc);                                                  \
473     else if (_conf_sc->t == '{') {                                      \
474       token(_conf_sc);                                                  \
475       _conf_state = CS_BRACE;                                           \
476     }                                                                   \
477   }                                                                     \
478                                                                         \
479   /* --- Ensure the next token is a word --- */                         \
480                                                                         \
481   if (_conf_sc->t != CTOK_WORD)                                         \
482     error(_conf_sc, "parse error, expected option keyword");            \
483   do {
484
485 #define CONF_END                                                        \
486                                                                         \
487     /* --- Reject an option --- *                                       \
488      *                                                                  \
489      * We could get here as a result of an explicit @CONF_REJECT@ or    \
490      * because the option wasn't accepted.                              \
491      */                                                                 \
492                                                                         \
493     goto _conf_reject;                                                  \
494   _conf_reject:                                                         \
495     if (_conf_state == CS_PLAIN)                                        \
496       _conf_state = CS_UNKNOWN;                                         \
497     else {                                                              \
498       error(_conf_sc, "unknown %s option `%s'",                         \
499             _conf_desc, _conf_sc->d.buf);                               \
500     }                                                                   \
501                                                                         \
502     /* --- Accept an option --- *                                       \
503      *                                                                  \
504      * It's safe to drop through from above.  Either an error will have \
505      * been reported, or the state is not @CS_BRACE@.                   \
506      */                                                                 \
507                                                                         \
508   _conf_accept:                                                         \
509     if (_conf_state == CS_BRACE && _conf_sc->t == ';')                  \
510       token(_conf_sc);                                                  \
511   } while (_conf_state == CS_BRACE && _conf_sc->t == CTOK_WORD);        \
512                                                                         \
513   /* --- Check for a closing brace --- */                               \
514                                                                         \
515   if (_conf_state == CS_BRACE) {                                        \
516     if (_conf_sc->t == '}')                                             \
517       token(_conf_sc);                                                  \
518     else                                                                \
519       error(_conf_sc, "parse error, expected `}'");                     \
520   }                                                                     \
521                                                                         \
522   /* --- Return an appropriate value --- */                             \
523                                                                         \
524   return (_conf_state != CS_UNKNOWN);                                   \
525 } while (0)
526
527 /* --- @CONF_ACCEPT@, @CONF_REJECT@ --- *
528  *
529  * Arguments:   ---
530  *
531  * Use:         Within an options parser (between @CONF_BEGIN@ and
532  *              @CONF_END@), accept or reject an option.
533  */
534
535 #define CONF_ACCEPT goto _conf_accept
536 #define CONF_REJECT goto _conf_reject
537
538 /* --- @CONF_QUAL@ --- *
539  *
540  * Arguments:   ---
541  *
542  * Use:         Evaluates to a nonzero value if the current option is
543  *              qualified.  This can be used to decide whether abbreviations
544  *              for options should be accepted.
545  */
546
547 #define CONF_QUAL (_conf_state != CS_PLAIN)
548
549 /* --- @conf_name@ --- *
550  *
551  * Arguments:   @scanner *sc@ = pointer to scanner
552  *              @char delim@ = delimiter character to look for
553  *              @dstr *d@ = pointer to dynamic string for output
554  *
555  * Returns:     ---
556  *
557  * Use:         Reads in a compound name consisting of words separated by
558  *              delimiters.  Leading and trailing delimiters are permitted,
559  *              although they'll probably cause confusion if used.  The name
560  *              may be enclosed in square brackets if that helps at all.
561  *
562  *              Examples of compound names are filenames (delimited by `/')
563  *              and IP addresses (delimited by `.').
564  */
565
566 extern void conf_name(scanner */*sc*/, char /*delim*/, dstr */*d*/);
567
568 /*----- Reference-counted file descriptors --------------------------------*/
569
570 typedef struct reffd {
571   int fd;
572   unsigned ref;
573   void (*proc)(void */*p*/);
574   void *p;
575 } reffd;
576
577 /* --- @reffd_init@ --- *
578  *
579  * Arguments:   @int fd@ = file descriptor
580  *
581  * Returns:     Reference-counted file descriptor object.
582  *
583  * Use:         Creates a refcounted file descriptor.
584  */
585
586 extern reffd *reffd_init(int /*fd*/);
587
588 /* --- @reffd_handler@ --- *
589  *
590  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
591  *              @void (*proc)(void *p)@ = procedure to call
592  *              @void *p@
593  *
594  * Returns:     ---
595  *
596  * Use:         Sets the reference counted file descriptor to call @proc@
597  *              when it is no longer required.
598  */
599
600 extern void reffd_handler(reffd */*r*/, void (*/*proc*/)(void */*p*/),
601                           void */*p*/);
602
603 /* --- @reffd_inc@ --- *
604  *
605  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
606  *
607  * Returns:     ---
608  *
609  * Use:         Increments the reference count for a file descriptor.
610  */
611
612 #define REFFD_INC(r) do { (r)->ref++; } while (0)
613
614 extern void reffd_inc(reffd */*r*/);
615
616 /* --- @reffd_dec@ --- *
617  *
618  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
619  *
620  * Returns:     ---
621  *
622  * Use:         Decrements the reference count for a file descriptor.
623  */
624
625 #define REFFD_DEC(r) do {                                               \
626   reffd *_r = (r);                                                      \
627   _r->ref--;                                                            \
628   if (_r->ref == 0) {                                                   \
629     close(_r->fd);                                                      \
630     if (_r->proc)                                                       \
631       _r->proc(_r->p);                                                  \
632     DESTROY(_r);                                                        \
633   }                                                                     \
634 } while (0)
635
636 extern void reffd_dec(reffd */*r*/);
637
638 /*----- Sources, targets and endpoints ------------------------------------*/
639
640 /* --- Basic endpoint structure --- */
641
642 typedef struct endpt {
643   struct endpt_ops *ops;                /* Pointer to operations table */
644   struct endpt *other;                  /* Pointer to sibling endpoint */
645   unsigned f;                           /* Various flags */
646   struct tango *t;                      /* Private data structure */
647   reffd *in, *out;                      /* File descriptors */
648 } endpt;
649
650 /* --- Endpoint flags --- */
651
652 #define EPF_PENDING 1u                  /* Endpoint creation in progress */
653 #define EPF_FILE 2u                     /* Endpoint smells like a file */
654
655 /* --- Endpoint operations table --- */
656
657 typedef struct endpt_ops {
658
659   /* --- @attach@ --- *
660    *
661    * Arguments: @endpt *e@ = pointer to endpoint to be attached
662    *            @reffd *in, *out@ = input and output file descriptors
663    *
664    * Returns:   ---
665    *
666    * Use:       Instructs a non-file endpoint to attach itself to a pair of
667    *            files.
668    */
669
670   void (*attach)(endpt */*e*/, reffd */*in*/, reffd */*out*/);
671
672   /* --- @file@ --- *
673    *
674    * Arguments: @endpt *e@ = pointer to endpoint in question
675    *            @endpt *f@ = pointer to a file endpoint
676    *
677    * Returns:   ---
678    *
679    * Use:       Informs a non-file endpoint of a file endpoint which will
680    *            want to be closed when it's finished with.  At that time, the
681    *            endpoint should arrange to have both itself and its partner
682    *            closed.  If no file is registered, the endpoint manager will
683    *            close both endpoints itself.
684    */
685
686   void (*file)(endpt */*e*/, endpt */*f*/);
687
688   /* --- @wclose@ --- *
689    *
690    * Arguments: @endpt *e@ = endpoint to be partially closed
691    *
692    * Returns:   ---
693    *
694    * Use:       Announces that the endpoint will not be written to any more.
695    */
696
697   void (*wclose)(endpt */*e*/);
698
699   /* --- @close@ --- *
700    *
701    * Arguments: @endpt *e@ = endpoint to be closed
702    *
703    * Returns:   ---
704    *
705    * Use:       Completely closes an endpoint.  The endpoint's data may be
706    *            freed, although some endpoints may wish to delay freeing for
707    *            some reason.
708    */
709
710   void (*close)(endpt */*e*/);
711
712 } endpt_ops;
713
714 /* --- A basic target object --- */
715
716 typedef struct target {
717   struct target_ops *ops;
718   char *desc;
719 } target;
720
721 /* --- Forwarding target operations --- */
722
723 typedef struct target_ops {
724   const char *name;                     /* Name of this target */
725
726   /* --- @option@ --- *
727    *
728    * Arguments: @target *t@ = pointer to target object, or zero if global
729    *            @scanner *sc@ = scanner to read from
730    *
731    * Returns:   Nonzero to claim the option.
732    *
733    * Use:       Handles an option string from the configuration file.
734    */
735
736   int (*option)(target */*t*/, scanner */*sc*/);
737
738   /* --- @read@ --- *
739    *
740    * Arguments: @scanner *sc@ = pointer to scanner to read from
741    *
742    * Returns:   Pointer to a target object to claim, null to reject.
743    *
744    * Use:       Parses a target description from the configuration file.
745    *            Only the socket target is allowed to omit the prefix on a
746    *            target specification.
747    */
748
749   target *(*read)(scanner */*sc*/);
750
751   /* --- @confirm@ --- *
752    *
753    * Arguments: @target *t@ = pointer to target
754    *
755    * Returns:   ---
756    *
757    * Use:       Confirms configuration of a target.
758    */
759
760   void (*confirm)(target */*t*/);
761
762   /* --- @create@ --- *
763    *
764    * Arguments: @target *t@ = pointer to target
765    *            @const char *desc@ = description of connection
766    *
767    * Returns:   Pointer to a created endpoint.
768    *
769    * Use:       Generates a target endpoint for communication.
770    */
771
772   endpt *(*create)(target */*t*/, const char */*desc*/);
773
774   /* --- @destroy@ --- *
775    *
776    * Arguments: @target *t@ = pointer to target
777    *
778    * Returns:   ---
779    *
780    * Use:       Destroys a target.
781    */
782
783   void (*destroy)(target */*t*/);
784
785 } target_ops;
786
787 /* --- A basic source object --- */
788
789 typedef struct source {
790   struct source *next, *prev;
791   struct source_ops *ops;
792   char *desc;
793 } source;
794
795 /* --- Forwarding source operations --- */
796
797 typedef struct source_ops {
798   const char *name;                     /* Name of this source */
799
800   /* --- @option@ --- *
801    *
802    * Arguments: @scanner *sc@ = scanner to read from
803    *            @source *s@ = pointer to source object, or zero if global
804    *
805    * Returns:   Nonzero to claim the option.
806    *
807    * Use:       Handles an option string from the configuration file.
808    */
809
810   int (*option)(source */*s*/, scanner */*sc*/);
811
812   /* --- @read@ --- *
813    *
814    * Arguments: @scanner *sc@ = pointer to scanner to read from
815    *
816    * Returns:   Pointer to a source object to claim, null to reject.
817    *
818    * Use:       Parses a source description from the configuration file.
819    *            Only the socket source is allowed to omit the prefix on a
820    *            source specification.
821    */
822
823   source *(*read)(scanner */*sc*/);
824
825   /* --- @attach@ --- *
826    *
827    * Arguments: @source *s@ = pointer to source
828    *            @scanner *sc@ = scanner (for error reporting)
829    *            @target *t@ = pointer to target to attach
830    *
831    * Returns:   ---
832    *
833    * Use:       Attaches a target to a source.
834    */
835
836   void (*attach)(source */*s*/, scanner */*sc*/, target */*t*/);
837
838   /* --- @destroy@ --- *
839    *
840    * Arguments: @source *s@ = pointer to source
841    *
842    * Returns:   ---
843    *
844    * Use:       Destroys a source.  Used when closing the system down, for
845    *            example as a result of a signal.
846    */
847
848   void (*destroy)(source */*s*/);
849
850 } source_ops;
851
852 /* --- @endpt_kill@ --- *
853  *
854  * Arguments:   @endpt *a@ = an endpoint
855  *
856  * Returns:     ---
857  *
858  * Use:         Kills an endpoint.  If the endpoint is joined to another, the
859  *              other endpoint is also killed, as is the connection between
860  *              them (and that's the tricky bit).
861  */
862
863 extern void endpt_kill(endpt */*a*/);
864
865 /* --- @endpt_killall@ --- *
866  *
867  * Arguments:   ---
868  *
869  * Returns:     ---
870  *
871  * Use:         Destroys all current endpoint connections.  Used when
872  *              shutting down.
873  */
874
875 extern void endpt_killall(void);
876
877 /* --- @endpt_join@ --- *
878  *
879  * Arguments:   @endpt *a@ = pointer to first endpoint
880  *              @endpt *b@ = pointer to second endpoint
881  *
882  * Returns:     ---
883  *
884  * Use:         Joins two endpoints together.
885  */
886
887 extern void endpt_join(endpt */*a*/, endpt */*b*/);
888
889 /* --- @source_add@ --- *
890  *
891  * Arguments:   @source *s@ = pointer to a source
892  *
893  * Returns:     ---
894  *
895  * Use:         Adds a source to the master list.  Only do this for passive
896  *              sources (e.g., listening sockets), not active sources (e.g.,
897  *              executable programs).
898  */
899
900 extern void source_add(source */*s*/);
901
902 /* --- @source_remove@ --- *
903  *
904  * Arguments:   @source *s@ = pointer to a source
905  *
906  * Returns:     ---
907  *
908  * Use:         Removes a source from the master list.
909  */
910
911 extern void source_remove(source */*s*/);
912
913 /* --- @source_killall@ --- *
914  *
915  * Arguments:   ---
916  *
917  * Returns:     ---
918  *
919  * Use:         Frees all sources.
920  */
921
922 extern void source_killall(void);
923
924 /*----- The exec source and target ----------------------------------------*/
925
926 extern source_ops xsource_ops;
927 extern target_ops xtarget_ops;
928
929 /* --- @exec_init@ --- *
930  *
931  * Arguments:   ---
932  *
933  * Returns:     ---
934  *
935  * Use:         Initializes the executable problem source and target.
936  */
937
938 extern void exec_init(void);
939
940 /*----- The file source and target ----------------------------------------*/
941
942 extern source_ops fsource_ops;
943 extern target_ops ftarget_ops;
944
945 /*----- The socket source and target --------------------------------------*/
946
947 extern source_ops ssource_ops;
948 extern target_ops starget_ops;
949
950 /* --- @starget_connected@ --- *
951  *
952  * Arguments:   @int fd@ = file descriptor now ready for use
953  *              @void *p@ = pointer to an endpoint structure
954  *
955  * Returns:     ---
956  *
957  * Use:         Handles successful connection of the target endpoint.
958  */
959
960 extern void starget_connected(int /*fd*/, void */*p*/);
961
962 /*----- Handling of file attributes ---------------------------------------*/
963
964 /* --- File attribute options structure --- */
965
966 typedef struct fattr {
967   unsigned mode;
968   uid_t uid;
969   gid_t gid;
970 } fattr;
971
972 /* --- Shared global options --- */
973
974 extern fattr fattr_global;
975
976 /* --- @fattr_init@ --- *
977  *
978  * Arguments:   @fattr *f@ = pointer to file attributes
979  *
980  * Returns:     ---
981  *
982  * Use:         Initializes a set of file attributes to default values.
983  */
984
985 extern void fattr_init(fattr */*f*/);
986
987 /* --- @fattr_option@ --- *
988  *
989  * Arguments:   @scanner *sc@ = pointer to scanner to read
990  *              @fattr *f@ = pointer to file attributes to set
991  *
992  * Returns:     Whether the option was clamed.
993  *
994  * Use:         Reads file attributes from a scanner.
995  */
996
997 extern int fattr_option(scanner */*sc*/, fattr */*f*/);
998
999 /* --- @fattr_apply@ --- *
1000  *
1001  * Arguments:   @const char *file@ = pointer to filename
1002  *              @fattr *f@ = pointer to attribute set
1003  *
1004  * Returns:     @-1@ if it failed.
1005  *
1006  * Use:         Applies file attributes to a file.  For best results, try to
1007  *              create the file with the right permissions and so on.  This
1008  *              call will fix everything up, but there are potential races
1009  *              which might catch you out if you're not careful.
1010  */
1011
1012 extern int fattr_apply(const char */*file*/, fattr */*f*/);
1013
1014 /*----- Making privileged connections -------------------------------------*/
1015
1016 /* --- @privconn_split@ --- *
1017  *
1018  * Arguments:   @sel_state *s@ = select state
1019  *
1020  * Returns:     ---
1021  *
1022  * Use:         Splits off the privileged binding code into a separate
1023  *              process.
1024  */
1025
1026 extern void privconn_split(sel_state */*s*/);
1027
1028 /* --- @privconn_adddest@ --- *
1029  *
1030  * Arguments:   @struct in_addr peer@ = address to connect to
1031  *              @unsigned port@ = port to connect to
1032  *
1033  * Returns:     Index for this destination address, or @-1@ if not
1034  *              available.
1035  *
1036  * Use:         Adds a valid destination for a privileged connection.
1037  */
1038
1039 extern int privconn_adddest(struct in_addr /*peer*/, unsigned /*port*/);
1040
1041 /* --- @privconn_connect@ --- *
1042  *
1043  * Arguments:   @conn *c@ = connection structure to fill in
1044  *              @sel_state *s@ = pointer to select state to attach to
1045  *              @int i@ = address index to connect to
1046  *              @struct in_addr bind@ = address to bind to
1047  *              @void (*func)(int, void *)@ = function to call on connect
1048  *              @void *p@ = argument for the function
1049  *
1050  * Returns:     Zero on success, @-1@ on failure.
1051  *
1052  * Use:         Sets up a privileged connection job.
1053  */
1054
1055 extern int privconn_connect(conn */*c*/, sel_state */*s*/,
1056                             int /*i*/, struct in_addr /*bind*/,
1057                             void (*/*func*/)(int, void *), void */*p*/);
1058
1059 /*----- Identifying remote clients ----------------------------------------*/
1060
1061 typedef struct id_req {
1062   struct sockaddr_in lsin;              /* Local address of connection */
1063   struct sockaddr_in rsin;              /* Remote address of connection */
1064   const char *desc;                     /* Description of connection */
1065   const char *act;                      /* Action taken by server */
1066   reffd *r;                             /* Pointer to file descriptor */
1067 } id_req;
1068
1069 /* --- @identify@ --- *
1070  *
1071  * Arguments:   @const id_req *q@ = pointer to request block
1072  *
1073  * Returns:     ---
1074  *
1075  * Use:         Starts a background ident lookup and reverse-resolve job
1076  *              which will, eventually, report a message to the system log.
1077  */
1078
1079 extern void identify(const id_req */*q*/);
1080
1081 /*----- Host-based access control -----------------------------------------*/
1082
1083 /* --- An access control entry --- */
1084
1085 typedef struct acl_entry {
1086   struct acl_entry *next;               /* Next entry in the list */
1087   const struct acl_ops *ops;            /* Operations for the ACL entry */
1088   unsigned act;                         /* What to do with matching hosts */
1089 } acl_entry;
1090
1091 #define ACL_DENY 0                      /* Deny access to matching conns */
1092 #define ACL_ALLOW 1                     /* Allow access to matching conns */
1093 #define ACL_PERM 1u                     /* Bit mask for permission bit */
1094
1095 /* --- Host-based access control --- */
1096
1097 typedef struct acl_host {
1098   acl_entry a;                          /* Base structure */
1099   struct in_addr addr, mask;            /* Address and netmask */
1100 } acl_host;
1101
1102 /* --- ACL methods --- */
1103
1104 typedef struct acl_ops {
1105   int (*check)(void */*a*/, struct in_addr /*addr*/, unsigned /*port*/);
1106   void (*dump)(void */*a*/, FILE */*fp*/);
1107   void (*free)(void */*a*/);
1108 } acl_ops;
1109
1110 /* --- @acl_check@ --- *
1111  *
1112  * Arguments:   @acl_entry *a@ = pointer to ACL to check against
1113  *              @struct in_addr addr@ = address to check
1114  *              @unsigned port@ = port number to check
1115  *              @int *act@ = verdict (should initially be @ACT_ALLOW@)
1116  *
1117  * Returns:     Zero if undecided, nonzero if a rule matched.
1118  *
1119  * Use:         Checks an address against an ACL.
1120  */
1121
1122 extern int acl_check(acl_entry */*a*/,
1123                      struct in_addr /*addr*/, unsigned /*port*/,
1124                      int */*act*/);
1125
1126 /* --- @acl_dump@ --- *
1127  *
1128  * Arguments:   @acl_entry *a@ = pointer to ACL to dump
1129  *              @FILE *fp@ = pointer to stream to dump on
1130  *
1131  * Returns:     ---
1132  *
1133  * Use:         Dumps an access control list to an output stream.
1134  */
1135
1136 extern void acl_dump(acl_entry */*a*/, FILE */*fp*/);
1137
1138 /* --- @acl_free@ --- *
1139  *
1140  * Arguments:   @acl_entry *a@ = pointer to a list of ACLs
1141  *
1142  * Returns:     ---
1143  *
1144  * Use:         Frees all of the memory used by an ACL.
1145  */
1146
1147 extern void acl_free(acl_entry */*a*/);
1148
1149 /* --- @acl_addhost@ --- *
1150  *
1151  * Arguments:   @acl_entry ***a@ = address of pointer to list tail
1152  *              @unsigned act@ = what to do with matching addresses
1153  *              @struct in_addr addr, mask@ = address and mask to match
1154  *
1155  * Returns:     ---
1156  *
1157  * Use:         Adds a host-authentication entry to the end of an access
1158  *              control list.
1159  */
1160
1161 extern void acl_addhost(acl_entry ***/*a*/, unsigned /*act*/,
1162                         struct in_addr /*addr*/, struct in_addr /*mask*/);
1163
1164 /* --- @acl_addpriv@ --- *
1165  *
1166  * Arguments:   @acl_entry ***a@ = address of pointer to list tail
1167  *              @unsigned act@ = what to do with matching addresses
1168  *
1169  * Returns:     ---
1170  *
1171  * Use:         Adds a privileged-port check to the end of an access control
1172  *              list.
1173  */
1174
1175 extern void acl_addpriv(acl_entry ***/*a*/, unsigned /*act*/);
1176
1177 /*----- Network addresses -------------------------------------------------*/
1178
1179 /* --- A generic socket address --- *
1180  *
1181  * Not all systems understand @sa_len@ fields.  (In particular, Linux
1182  * doesn't.)  Some fairly ugly hacking is then performed on particular
1183  * address types.
1184  */
1185
1186 typedef struct addr {
1187   struct addr_ops *ops;
1188   size_t sz;
1189 } addr;
1190
1191 #define ADDRSZ(sz) (sizeof(addr) + (sz))
1192
1193 /* --- Address configuration --- *
1194  *
1195  * An address family will want to extend this.
1196  */
1197
1198 typedef struct addr_opts {
1199   unsigned f;
1200 } addr_opts;
1201
1202 #define ADDRF_NOLOG 1u
1203
1204 /* --- Address types --- *
1205  *
1206  * For things like Internet addresses, source and destinations look
1207  * different.
1208  */
1209
1210 enum {
1211   ADDR_SRC,
1212   ADDR_DEST,
1213   ADDR_GLOBAL
1214 };
1215
1216 /* --- Description of an address type handler --- */
1217
1218 typedef struct addr_ops {
1219   const char *name;                     /* Protocol's internal name */
1220
1221   /* --- @read@ --- *
1222    *
1223    * Arguments: @scanner *sc@ = pointer to scanner to read from
1224    *            @unsigned type@ = type of address to be read
1225    *
1226    * Returns:   A filled-in socket address.
1227    *
1228    * Use:       Parses a textual representation of a socket address.
1229    */
1230
1231   addr *(*read)(scanner */*sc*/, unsigned /*type*/);
1232
1233   /* --- @destroy@ --- *
1234    *
1235    * Arguments: @addr *a@ = pointer to an address block
1236    *
1237    * Returns:   ---
1238    *
1239    * Use:       Disposes of an address block in some suitable fashion.
1240    */
1241
1242   void (*destroy)(addr */*a*/);
1243
1244   /* --- @print@ --- *
1245    *
1246    * Arguments: @addr *a@ = pointer to socket address to read
1247    *            @unsigned type@ = type of address to be written
1248    *            @dstr *d@ = string on which to write the description
1249    *
1250    * Returns:   ---
1251    *
1252    * Use:       Writes a textual representation of a socket address to
1253    *            a string.
1254    */
1255
1256   void (*print)(addr */*a*/, unsigned /*type*/, dstr */*d*/);
1257
1258   /* --- @initsrcopts@ --- *
1259    *
1260    * Arguments: ---
1261    *
1262    * Returns:   A pointer to a protocol-specific data block for a listener
1263    *
1264    * Use:       Creates a data block for a listener.  This is attached to the
1265    *            listener data structure.  Options can then be requested, and
1266    *            are added to the block when necessary.
1267    */
1268
1269   addr_opts *(*initsrcopts)(void);
1270
1271   /* --- @option@ --- *
1272    *
1273    * Arguments: @scanner *sc@ = pointer to a scanner to read from
1274    *            @unsigned type@ = kind of option this is
1275    *            @addr_opts *ao@ = data block to modify (from @init@), or null
1276    *
1277    * Returns:   Nonzero to claim the option.
1278    *
1279    * Use:       Parses a source option, either global or listener-specific.
1280    */
1281
1282   int (*option)(scanner */*sc*/, addr_opts */*ao*/, unsigned /*type*/);
1283
1284   /* --- @confirm@ --- *
1285    *
1286    * Arguments: @addr *a@ = pointer to an address structure
1287    *            @unsigned type@ = kind of address this is
1288    *            @addr_opts *ao@ = address options
1289    *
1290    * Returns:   ---
1291    *
1292    * Use:       Called during initialization when an address is fully
1293    *            configured.
1294    */
1295
1296   void (*confirm)(addr */*a*/, unsigned /*type*/, addr_opts */*ao*/);
1297
1298   /* --- @freesrcopts@ --- *
1299    *
1300    * Arguments: @addr_opts *ao@ = data block to remove
1301    *
1302    * Returns:   ---
1303    *
1304    * Use:       Throws away all the configuration data for an address type.
1305    */
1306
1307   void (*freesrcopts)(addr_opts */*ao*/);
1308
1309   /* --- @bind@ --- *
1310    *
1311    * Arguments: @addr *a@ = the address to bind to
1312    *            @addr_opts *ao@ = the address options
1313    *
1314    * Returns:   File descriptor of bound socket if OK, or @-1@ on error.
1315    *
1316    * Use:       Binds a listening socket.  The tedious stuff with @listen@
1317    *            isn't necessary.
1318    */
1319
1320   int (*bind)(addr */*a*/, addr_opts */*ao*/);
1321
1322   /* --- @unbind@ --- *
1323    *
1324    * Arguments: @addr *a@ = pointer to an address
1325    *
1326    * Returns:   ---
1327    *
1328    * Use:       Unbinds an address.  This is used when tidying up.  The main
1329    *            purpose is to let the Unix-domain handler remove its socket
1330    *            node from the filesystem.
1331    */
1332
1333   void (*unbind)(addr */*a*/);
1334
1335   /* --- @accept@ --- *
1336    *
1337    * Arguments: @int fd@ = listening file descriptor
1338    *            @addr_opts *ao@ = data block to get configuration from
1339    *            @const char *desc@ = description of the listener
1340    *
1341    * Returns:   Pointer to a reference counted file descriptor.
1342    *
1343    * Use:       Accepts, verifies and logs an incoming connection.
1344    */
1345
1346   reffd *(*accept)(int /*fd*/, addr_opts */*ao*/, const char */*desc*/);
1347
1348   /* --- @inittargopts@ --- *
1349    *
1350    * Arguments: ---
1351    *
1352    * Returns:   A pointer to a protocol-specific data block for a connecter
1353    *
1354    * Use:       Creates a data block for a target.  This is attached to the
1355    *            target data structure.  Options can then be requested, and
1356    *            are added to the block when necessary.
1357    */
1358
1359   addr_opts *(*inittargopts)(void);
1360
1361   /* --- @freetargopts@ --- *
1362    *
1363    * Arguments: @addr_opts *ao@ = data block to remove
1364    *
1365    * Returns:   ---
1366    *
1367    * Use:       Throws away all the configuration data for an address type.
1368    */
1369
1370   void (*freetargopts)(addr_opts */*ao*/);
1371
1372   /* --- @connect@ --- *
1373    *
1374    * Arguments: @addr *a@ = destination address
1375    *            @addr_opts *ao@ = target address options
1376    *            @conn *c@ = connection structure
1377    *            @endpt *e@ = endpoint structure
1378    *
1379    * Returns:   Zero if OK, @-1@ on some error.
1380    *
1381    * Use:       Requests that a connection be made, or at least set in
1382    *            motion.  An address may do one of these things:
1383    *
1384    *              * Return @-1@.
1385    *
1386    *              * Call @starget_connected@ with @-1@ or a connected file
1387    *                descriptor and the pointer @e@.
1388    *
1389    *              * Call @conn_init@ or @conn_fd@, giving @starget_connected@
1390    *                and @e@ as the function to call.
1391    */
1392
1393   int (*connect)(addr */*a*/, addr_opts */*ao*/, conn */*c*/, endpt */*e*/);
1394
1395 } addr_ops;
1396
1397 /* --- Address types --- */
1398
1399 extern addr_ops un_ops;
1400 extern addr_ops inet_ops;
1401
1402 /*----- That's all, folks -------------------------------------------------*/
1403
1404 #ifdef __cplusplus
1405   }
1406 #endif
1407
1408 #endif