xref: /openbsd-src/usr.sbin/relayd/log.c (revision e5157e49389faebcb42b7237d55fbf096d9c2523)
1 /*	$OpenBSD: log.c,v 1.24 2014/10/25 03:23:49 lteo Exp $	*/
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <sys/tree.h>
23 
24 #include <net/if.h>
25 #include <netinet/in.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
28 
29 #include <errno.h>
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <syslog.h>
35 #include <event.h>
36 #include <netdb.h>
37 #include <ctype.h>
38 
39 #include <openssl/ssl.h>
40 
41 #include "relayd.h"
42 
43 int	 debug;
44 int	 verbose;
45 
46 void	 vlog(int, const char *, va_list)
47 	    __attribute__((__format__ (printf, 2, 0)));
48 void	 logit(int, const char *, ...)
49 	    __attribute__((__format__ (printf, 2, 3)));
50 
51 void
52 log_init(int n_debug)
53 {
54 	extern char	*__progname;
55 
56 	debug = n_debug;
57 	verbose = n_debug;
58 
59 	if (!debug)
60 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
61 
62 	tzset();
63 }
64 
65 void
66 log_verbose(int v)
67 {
68 	verbose = v;
69 }
70 
71 void
72 logit(int pri, const char *fmt, ...)
73 {
74 	va_list	ap;
75 
76 	va_start(ap, fmt);
77 	vlog(pri, fmt, ap);
78 	va_end(ap);
79 }
80 
81 void
82 vlog(int pri, const char *fmt, va_list ap)
83 {
84 	char	*nfmt;
85 
86 	if (debug) {
87 		/* best effort in out of mem situations */
88 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
89 			vfprintf(stderr, fmt, ap);
90 			fprintf(stderr, "\n");
91 		} else {
92 			vfprintf(stderr, nfmt, ap);
93 			free(nfmt);
94 		}
95 		fflush(stderr);
96 	} else
97 		vsyslog(pri, fmt, ap);
98 }
99 
100 
101 void
102 log_warn(const char *emsg, ...)
103 {
104 	char	*nfmt;
105 	va_list	 ap;
106 
107 	/* best effort to even work in out of memory situations */
108 	if (emsg == NULL)
109 		logit(LOG_CRIT, "%s", strerror(errno));
110 	else {
111 		va_start(ap, emsg);
112 
113 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
114 			/* we tried it... */
115 			vlog(LOG_CRIT, emsg, ap);
116 			logit(LOG_CRIT, "%s", strerror(errno));
117 		} else {
118 			vlog(LOG_CRIT, nfmt, ap);
119 			free(nfmt);
120 		}
121 		va_end(ap);
122 	}
123 }
124 
125 void
126 log_warnx(const char *emsg, ...)
127 {
128 	va_list	 ap;
129 
130 	va_start(ap, emsg);
131 	vlog(LOG_CRIT, emsg, ap);
132 	va_end(ap);
133 }
134 
135 void
136 log_info(const char *emsg, ...)
137 {
138 	va_list	 ap;
139 
140 	va_start(ap, emsg);
141 	vlog(LOG_INFO, emsg, ap);
142 	va_end(ap);
143 }
144 
145 void
146 log_debug(const char *emsg, ...)
147 {
148 	va_list	 ap;
149 
150 	if (verbose > 1) {
151 		va_start(ap, emsg);
152 		vlog(LOG_DEBUG, emsg, ap);
153 		va_end(ap);
154 	}
155 }
156 
157 void
158 fatal(const char *emsg)
159 {
160 	if (emsg == NULL)
161 		logit(LOG_CRIT, "fatal: %s", strerror(errno));
162 	else
163 		if (errno)
164 			logit(LOG_CRIT, "fatal: %s: %s",
165 			    emsg, strerror(errno));
166 		else
167 			logit(LOG_CRIT, "fatal: %s", emsg);
168 
169 	exit(1);
170 }
171 
172 void
173 fatalx(const char *emsg)
174 {
175 	errno = 0;
176 	fatal(emsg);
177 }
178 
179 const char *
180 host_error(enum host_error he)
181 {
182 	switch (he) {
183 	case HCE_NONE:
184 		return ("none");
185 		break;
186 	case HCE_ABORT:
187 		return ("aborted");
188 		break;
189 	case HCE_INTERVAL_TIMEOUT:
190 		return ("interval timeout");
191 		break;
192 	case HCE_ICMP_OK:
193 		return ("icmp ok");
194 		break;
195 	case HCE_ICMP_READ_TIMEOUT:
196 		return ("icmp read timeout");
197 		break;
198 	case HCE_ICMP_WRITE_TIMEOUT:
199 		return ("icmp write timeout");
200 		break;
201 	case HCE_TCP_SOCKET_ERROR:
202 		return ("tcp socket error");
203 		break;
204 	case HCE_TCP_SOCKET_LIMIT:
205 		return ("tcp socket limit");
206 		break;
207 	case HCE_TCP_SOCKET_OPTION:
208 		return ("tcp socket option");
209 		break;
210 	case HCE_TCP_CONNECT_FAIL:
211 		return ("tcp connect failed");
212 		break;
213 	case HCE_TCP_CONNECT_TIMEOUT:
214 		return ("tcp connect timeout");
215 		break;
216 	case HCE_TCP_CONNECT_OK:
217 		return ("tcp connect ok");
218 		break;
219 	case HCE_TCP_WRITE_TIMEOUT:
220 		return ("tcp write timeout");
221 		break;
222 	case HCE_TCP_WRITE_FAIL:
223 		return ("tcp write failed");
224 		break;
225 	case HCE_TCP_READ_TIMEOUT:
226 		return ("tcp read timeout");
227 		break;
228 	case HCE_TCP_READ_FAIL:
229 		return ("tcp read failed");
230 		break;
231 	case HCE_SCRIPT_OK:
232 		return ("script ok");
233 		break;
234 	case HCE_SCRIPT_FAIL:
235 		return ("script failed");
236 		break;
237 	case HCE_SSL_CONNECT_OK:
238 		return ("ssl connect ok");
239 		break;
240 	case HCE_SSL_CONNECT_FAIL:
241 		return ("ssl connect failed");
242 		break;
243 	case HCE_SSL_CONNECT_TIMEOUT:
244 		return ("ssl connect timeout");
245 		break;
246 	case HCE_SSL_CONNECT_ERROR:
247 		return ("ssl connect error");
248 		break;
249 	case HCE_SSL_READ_TIMEOUT:
250 		return ("ssl read timeout");
251 		break;
252 	case HCE_SSL_WRITE_TIMEOUT:
253 		return ("ssl write timeout");
254 		break;
255 	case HCE_SSL_READ_ERROR:
256 		return ("ssl read error");
257 		break;
258 	case HCE_SSL_WRITE_ERROR:
259 		return ("ssl write error");
260 		break;
261 	case HCE_SEND_EXPECT_FAIL:
262 		return ("send/expect failed");
263 		break;
264 	case HCE_SEND_EXPECT_OK:
265 		return ("send/expect ok");
266 		break;
267 	case HCE_HTTP_CODE_ERROR:
268 		return ("http code malformed");
269 		break;
270 	case HCE_HTTP_CODE_FAIL:
271 		return ("http code mismatch");
272 		break;
273 	case HCE_HTTP_CODE_OK:
274 		return ("http code ok");
275 		break;
276 	case HCE_HTTP_DIGEST_ERROR:
277 		return ("http digest malformed");
278 		break;
279 	case HCE_HTTP_DIGEST_FAIL:
280 		return ("http digest mismatch");
281 		break;
282 	case HCE_HTTP_DIGEST_OK:
283 		return ("http digest ok");
284 		break;
285 	}
286 	/* NOTREACHED */
287 	return ("invalid");
288 }
289 
290 const char *
291 host_status(enum host_status status)
292 {
293 	switch (status) {
294 	case HOST_DOWN:
295 		return ("down");
296 	case HOST_UNKNOWN:
297 		return ("unknown");
298 	case HOST_UP:
299 		return ("up");
300 	};
301 	/* NOTREACHED */
302 	return ("invalid");
303 }
304 
305 const char *
306 table_check(enum table_check check)
307 {
308 	switch (check) {
309 	case CHECK_NOCHECK:
310 		return ("none");
311 	case CHECK_ICMP:
312 		return ("icmp");
313 	case CHECK_TCP:
314 		return ("tcp");
315 	case CHECK_HTTP_CODE:
316 		return ("http code");
317 	case CHECK_HTTP_DIGEST:
318 		return ("http digest");
319 	case CHECK_SEND_EXPECT:
320 		return ("send expect");
321 	case CHECK_SCRIPT:
322 		return ("script");
323 	};
324 	/* NOTREACHED */
325 	return ("invalid");
326 }
327 
328 const char *
329 print_availability(u_long cnt, u_long up)
330 {
331 	static char buf[BUFSIZ];
332 
333 	if (cnt == 0)
334 		return ("");
335 	bzero(buf, sizeof(buf));
336 	snprintf(buf, sizeof(buf), "%.2f%%", (double)up / cnt * 100);
337 	return (buf);
338 }
339 
340 const char *
341 print_host(struct sockaddr_storage *ss, char *buf, size_t len)
342 {
343 	if (getnameinfo((struct sockaddr *)ss, ss->ss_len,
344 	    buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
345 		buf[0] = '\0';
346 		return (NULL);
347 	}
348 	return (buf);
349 }
350 
351 const char *
352 print_time(struct timeval *a, struct timeval *b, char *buf, size_t len)
353 {
354 	struct timeval		tv;
355 	u_long			h, sec, min;
356 
357 	timerclear(&tv);
358 	timersub(a, b, &tv);
359 	sec = tv.tv_sec % 60;
360 	min = tv.tv_sec / 60 % 60;
361 	h = tv.tv_sec / 60 / 60;
362 
363 	snprintf(buf, len, "%.2lu:%.2lu:%.2lu", h, min, sec);
364 	return (buf);
365 }
366 
367 const char *
368 printb_flags(const u_int32_t v, const char *bits)
369 {
370 	static char	 buf[2][BUFSIZ];
371 	static int	 idx = 0;
372 	int		 i, any = 0;
373 	char		 c, *p, *r;
374 
375 	p = r = buf[++idx % 2];
376 	bzero(p, BUFSIZ);
377 
378 	if (bits) {
379 		bits++;
380 		while ((i = *bits++)) {
381 			if (v & (1 << (i - 1))) {
382 				if (any) {
383 					*p++ = ',';
384 					*p++ = ' ';
385 				}
386 				any = 1;
387 				for (; (c = *bits) > 32; bits++) {
388 					if (c == '_')
389 						*p++ = ' ';
390 					else
391 						*p++ = tolower((u_char)c);
392 				}
393 			} else
394 				for (; *bits > 32; bits++)
395 					;
396 		}
397 	}
398 
399 	return (r);
400 }
401 
402 void
403 getmonotime(struct timeval *tv)
404 {
405 	struct timespec	 ts;
406 
407 	if (clock_gettime(CLOCK_MONOTONIC, &ts))
408 		fatal("clock_gettime");
409 
410 	TIMESPEC_TO_TIMEVAL(tv, &ts);
411 }
412