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