2 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: log.h,v 1.31 2002/03/15 22:30:17 dhr Exp $
19 /* our versions of assert: log result */
23 extern void passert_fail(const char *pred_str
24 , const char *file_str, unsigned long line_no) NEVER_RETURNS;
26 # define impossible() passert_fail("impossible", __FILE__, __LINE__)
28 # define passert(pred) { \
30 passert_fail(#pred, __FILE__, __LINE__); \
33 /* assert that an err_t is NULL; evaluate exactly once */
37 passert_fail(ugh, __FILE__, __LINE__); \
42 # define impossible() abort()
43 # define passert(pred) { } /* do nothing */
44 # define happy(x) { (void) x; } /* evaluate non-judgementally */
50 log_to_stderr, /* should log go to stderr? */
51 log_to_syslog; /* should log go to syslog? */
53 /* Context for logging.
55 * Global variables: must be carefully adjusted at transaction boundaries!
56 * All are to be left in RESET condition and will be checked.
57 * There are several pairs of routines to set and reset them.
58 * If the context provides a whack file descriptor, messages
59 * should be copied to it -- see whack_log()
61 extern int whack_log_fd; /* only set during whack_handle() */
62 extern struct state *cur_state; /* current state, for diagnostics */
63 extern struct connection *cur_connection; /* current connection, for diagnostics */
64 extern const ip_address *cur_from; /* source of current current message */
65 extern u_int16_t cur_from_port; /* host order */
69 extern unsigned int cur_debugging; /* current debugging level */
71 extern void extra_debugging(const struct connection *c);
73 # define reset_debugging() { cur_debugging = base_debugging; }
75 # define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
76 && cur_state == NULL \
77 && cur_connection == NULL \
79 && cur_debugging == base_debugging)
83 # define extra_debugging(c) { }
85 # define reset_debugging() { }
87 # define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
88 && cur_state == NULL \
89 && cur_connection == NULL \
94 #define reset_globals() { \
95 whack_log_fd = NULL_FD; \
98 reset_cur_connection(); \
102 #define set_cur_connection(c) { \
103 cur_connection = (c); \
104 extra_debugging(c); \
107 #define reset_cur_connection() { \
108 cur_connection = NULL; \
113 #define set_cur_state(s) { \
115 extra_debugging((s)->st_connection); \
118 #define reset_cur_state() { \
123 extern void init_log(void);
124 extern void close_log(void);
125 extern void log(const char *message, ...) PRINTF_LIKE(1);
126 extern void exit_log(const char *message, ...) PRINTF_LIKE(1) NEVER_RETURNS;
128 /* the following routines do a dance to capture errno before it is changed
129 * A call must doubly parenthesize the argument list (no varargs macros).
130 * The first argument must be "e", the local variable that captures errno.
132 #define log_errno(a) { int e = errno; log_errno_routine a; }
133 extern void log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2);
134 #define exit_log_errno(a) { int e = errno; exit_log_errno_routine a; }
135 extern void exit_log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2) NEVER_RETURNS NEVER_RETURNS;
137 extern void whack_log(int mess_no, const char *message, ...) PRINTF_LIKE(2);
139 /* Log to both main log and whack log
140 * Much like log, actually, except for specifying mess_no.
142 extern void loglog(int mess_no, const char *message, ...) PRINTF_LIKE(2);
144 /* Build up a diagnostic in a static buffer.
145 * Although this would be a generally useful function, it is very
146 * hard to come up with a discipline that prevents different uses
147 * from interfering. It is intended that by limiting it to building
148 * diagnostics, we will avoid this problem.
149 * Juggling is performed to allow an argument to be a previous
150 * result: the new string may safely depend on the old one. This
151 * restriction is not checked in any way: violators will produce
152 * confusing results (without crashing!).
154 extern char diag_space[1024]; /* output buffer, but can be occupied at call */
155 extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1);
159 extern unsigned int base_debugging; /* bits selecting what to report */
160 #define DBG(cond, action) { if (cur_debugging & (cond)) { action ; } }
162 extern void DBG_log(const char *message, ...) PRINTF_LIKE(1);
163 extern void DBG_dump(const char *label, const void *p, size_t len);
164 #define DBG_dump_chunk(label, ch) DBG_dump(label, (ch).ptr, (ch).len)
168 #define DBG(cond, action) { } /* do nothing */
172 #define DBG_cond_dump(cond, label, p, len) DBG(cond, DBG_dump(label, p, len))
173 #define DBG_cond_dump_chunk(cond, label, ch) DBG(cond, DBG_dump_chunk(label, ch))
176 /* ip_str: a simple to use variant of addrtot.
177 * It stores its result in a static buffer.
178 * This means that newer calls overwrite the storage of older calls.
179 * Note: this is not used in any of the logging functions, so their
180 * callers may use it.
182 extern const char *ip_str(const ip_address *src);