xref: /openbsd-src/usr.sbin/ldpd/log.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: log.c,v 1.32 2016/09/02 17:08:02 renato 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 USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <arpa/inet.h>
22 #include <netmpls/mpls.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <syslog.h>
28 #include <unistd.h>
29 #include <netdb.h>
30 #include <limits.h>
31 
32 #include "ldpd.h"
33 #include "ldpe.h"
34 #include "lde.h"
35 #include "log.h"
36 
37 static const char * const procnames[] = {
38 	"parent",
39 	"ldpe",
40 	"lde"
41 };
42 
43 static void	 vlog(int, const char *, va_list);
44 
45 static int	 debug;
46 static int	 verbose;
47 
48 void
49 log_init(int n_debug)
50 {
51 	extern char	*__progname;
52 
53 	debug = n_debug;
54 
55 	if (!debug)
56 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
57 
58 	tzset();
59 }
60 
61 void
62 log_verbose(int v)
63 {
64 	verbose = v;
65 }
66 
67 void
68 logit(int pri, const char *fmt, ...)
69 {
70 	va_list	ap;
71 
72 	va_start(ap, fmt);
73 	vlog(pri, fmt, ap);
74 	va_end(ap);
75 }
76 
77 static void
78 vlog(int pri, const char *fmt, va_list ap)
79 {
80 	char	*nfmt;
81 
82 	if (debug) {
83 		/* best effort in out of mem situations */
84 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
85 			vfprintf(stderr, fmt, ap);
86 			fprintf(stderr, "\n");
87 		} else {
88 			vfprintf(stderr, nfmt, ap);
89 			free(nfmt);
90 		}
91 		fflush(stderr);
92 	} else
93 		vsyslog(pri, fmt, ap);
94 }
95 
96 void
97 log_warn(const char *emsg, ...)
98 {
99 	char	*nfmt;
100 	va_list	 ap;
101 
102 	/* best effort to even work in out of memory situations */
103 	if (emsg == NULL)
104 		logit(LOG_CRIT, "%s", strerror(errno));
105 	else {
106 		va_start(ap, emsg);
107 
108 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
109 			/* we tried it... */
110 			vlog(LOG_CRIT, emsg, ap);
111 			logit(LOG_CRIT, "%s", strerror(errno));
112 		} else {
113 			vlog(LOG_CRIT, nfmt, ap);
114 			free(nfmt);
115 		}
116 		va_end(ap);
117 	}
118 }
119 
120 void
121 log_warnx(const char *emsg, ...)
122 {
123 	va_list	 ap;
124 
125 	va_start(ap, emsg);
126 	vlog(LOG_CRIT, emsg, ap);
127 	va_end(ap);
128 }
129 
130 void
131 log_info(const char *emsg, ...)
132 {
133 	va_list	 ap;
134 
135 	va_start(ap, emsg);
136 	vlog(LOG_INFO, emsg, ap);
137 	va_end(ap);
138 }
139 
140 void
141 log_debug(const char *emsg, ...)
142 {
143 	va_list	 ap;
144 
145 	if (verbose & LDPD_OPT_VERBOSE) {
146 		va_start(ap, emsg);
147 		vlog(LOG_DEBUG, emsg, ap);
148 		va_end(ap);
149 	}
150 }
151 
152 void
153 fatal(const char *emsg)
154 {
155 	if (emsg == NULL)
156 		logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
157 		    strerror(errno));
158 	else
159 		if (errno)
160 			logit(LOG_CRIT, "fatal in %s: %s: %s",
161 			    procnames[ldpd_process], emsg, strerror(errno));
162 		else
163 			logit(LOG_CRIT, "fatal in %s: %s",
164 			    procnames[ldpd_process], emsg);
165 
166 	exit(1);
167 }
168 
169 void
170 fatalx(const char *emsg)
171 {
172 	errno = 0;
173 	fatal(emsg);
174 }
175 
176 #define NUM_LOGS	4
177 const char *
178 log_sockaddr(void *vp)
179 {
180 	static char	 buf[NUM_LOGS][NI_MAXHOST];
181 	static int	 round = 0;
182 	struct sockaddr	*sa = vp;
183 
184 	round = (round + 1) % NUM_LOGS;
185 
186 	if (getnameinfo(sa, sa->sa_len, buf[round], NI_MAXHOST, NULL, 0,
187 	    NI_NUMERICHOST))
188 		return ("(unknown)");
189 	else
190 		return (buf[round]);
191 }
192 
193 const char *
194 log_in6addr(const struct in6_addr *addr)
195 {
196 	struct sockaddr_in6	sa_in6;
197 
198 	memset(&sa_in6, 0, sizeof(sa_in6));
199 	sa_in6.sin6_len = sizeof(sa_in6);
200 	sa_in6.sin6_family = AF_INET6;
201 	sa_in6.sin6_addr = *addr;
202 
203 	recoverscope(&sa_in6);
204 
205 	return (log_sockaddr(&sa_in6));
206 }
207 
208 const char *
209 log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
210 {
211 	struct sockaddr_in6	sa_in6;
212 
213 	memset(&sa_in6, 0, sizeof(sa_in6));
214 	sa_in6.sin6_len = sizeof(sa_in6);
215 	sa_in6.sin6_family = AF_INET6;
216 	sa_in6.sin6_addr = *addr;
217 
218 	addscope(&sa_in6, ifindex);
219 
220 	return (log_sockaddr(&sa_in6));
221 }
222 
223 const char *
224 log_addr(int af, const union ldpd_addr *addr)
225 {
226 	static char	 buf[NUM_LOGS][INET6_ADDRSTRLEN];
227 	static int	 round = 0;
228 
229 	switch (af) {
230 	case AF_INET:
231 		round = (round + 1) % NUM_LOGS;
232 		if (inet_ntop(AF_INET, &addr->v4, buf[round],
233 		    sizeof(buf[round])) == NULL)
234 			return ("???");
235 		return (buf[round]);
236 	case AF_INET6:
237 		return (log_in6addr(&addr->v6));
238 	default:
239 		break;
240 	}
241 
242 	return ("???");
243 }
244 
245 #define	TF_BUFS	4
246 #define	TF_LEN	32
247 
248 char *
249 log_label(uint32_t label)
250 {
251 	char		*buf;
252 	static char	 tfbuf[TF_BUFS][TF_LEN];	/* ring buffer */
253 	static int	 idx = 0;
254 
255 	buf = tfbuf[idx++];
256 	if (idx == TF_BUFS)
257 		idx = 0;
258 
259 	switch (label) {
260 	case NO_LABEL:
261 		snprintf(buf, TF_LEN, "-");
262 		break;
263 	case MPLS_LABEL_IMPLNULL:
264 		snprintf(buf, TF_LEN, "imp-null");
265 		break;
266 	case MPLS_LABEL_IPV4NULL:
267 	case MPLS_LABEL_IPV6NULL:
268 		snprintf(buf, TF_LEN, "exp-null");
269 		break;
270 	default:
271 		snprintf(buf, TF_LEN, "%u", label);
272 		break;
273 	}
274 
275 	return (buf);
276 }
277 
278 char *
279 log_hello_src(const struct hello_source *src)
280 {
281 	static char buf[64];
282 
283 	switch (src->type) {
284 	case HELLO_LINK:
285 		snprintf(buf, sizeof(buf), "iface %s",
286 		    src->link.ia->iface->name);
287 		break;
288 	case HELLO_TARGETED:
289 		snprintf(buf, sizeof(buf), "source %s",
290 		    log_addr(src->target->af, &src->target->addr));
291 		break;
292 	}
293 
294 	return (buf);
295 }
296 
297 const char *
298 log_map(const struct map *map)
299 {
300 	static char	buf[64];
301 
302 	switch (map->type) {
303 	case MAP_TYPE_WILDCARD:
304 		if (snprintf(buf, sizeof(buf), "wildcard") < 0)
305 			return ("???");
306 		break;
307 	case MAP_TYPE_PREFIX:
308 		if (snprintf(buf, sizeof(buf), "%s/%u",
309 		    log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
310 		    map->fec.prefix.prefixlen) == -1)
311 			return ("???");
312 		break;
313 	case MAP_TYPE_PWID:
314 		if (snprintf(buf, sizeof(buf), "pwid %u (%s)",
315 		    map->fec.pwid.pwid,
316 		    pw_type_name(map->fec.pwid.type)) == -1)
317 			return ("???");
318 		break;
319 	default:
320 		return ("???");
321 	}
322 
323 	return (buf);
324 }
325 
326 const char *
327 log_fec(const struct fec *fec)
328 {
329 	static char	buf[64];
330 	union ldpd_addr	addr;
331 
332 	switch (fec->type) {
333 	case FEC_TYPE_IPV4:
334 		addr.v4 = fec->u.ipv4.prefix;
335 		if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
336 		    log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
337 			return ("???");
338 		break;
339 	case FEC_TYPE_IPV6:
340 		addr.v6 = fec->u.ipv6.prefix;
341 		if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
342 		    log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
343 			return ("???");
344 		break;
345 	case FEC_TYPE_PWID:
346 		if (snprintf(buf, sizeof(buf),
347 		    "pwid %u (%s) - %s",
348 		    fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
349 		    inet_ntoa(fec->u.pwid.lsr_id)) == -1)
350 			return ("???");
351 		break;
352 	default:
353 		return ("???");
354 	}
355 
356 	return (buf);
357 }
358 
359 /* names */
360 const char *
361 af_name(int af)
362 {
363 	switch (af) {
364 	case AF_INET:
365 		return ("ipv4");
366 	case AF_INET6:
367 		return ("ipv6");
368 	case AF_MPLS:
369 		return ("mpls");
370 	default:
371 		return ("UNKNOWN");
372 	}
373 }
374 
375 const char *
376 socket_name(int type)
377 {
378 	switch (type) {
379 	case LDP_SOCKET_DISC:
380 		return ("discovery");
381 	case LDP_SOCKET_EDISC:
382 		return ("extended discovery");
383 	case LDP_SOCKET_SESSION:
384 		return ("session");
385 	default:
386 		return ("UNKNOWN");
387 	}
388 }
389 
390 const char *
391 nbr_state_name(int state)
392 {
393 	switch (state) {
394 	case NBR_STA_PRESENT:
395 		return ("PRESENT");
396 	case NBR_STA_INITIAL:
397 		return ("INITIALIZED");
398 	case NBR_STA_OPENREC:
399 		return ("OPENREC");
400 	case NBR_STA_OPENSENT:
401 		return ("OPENSENT");
402 	case NBR_STA_OPER:
403 		return ("OPERATIONAL");
404 	default:
405 		return ("UNKNOWN");
406 	}
407 }
408 
409 const char *
410 if_state_name(int state)
411 {
412 	switch (state) {
413 	case IF_STA_DOWN:
414 		return ("DOWN");
415 	case IF_STA_ACTIVE:
416 		return ("ACTIVE");
417 	default:
418 		return ("UNKNOWN");
419 	}
420 }
421 
422 const char *
423 if_type_name(enum iface_type type)
424 {
425 	switch (type) {
426 	case IF_TYPE_POINTOPOINT:
427 		return ("POINTOPOINT");
428 	case IF_TYPE_BROADCAST:
429 		return ("BROADCAST");
430 	}
431 	/* NOTREACHED */
432 	return ("UNKNOWN");
433 }
434 
435 const char *
436 msg_name(uint16_t msg)
437 {
438 	static char buf[16];
439 
440 	switch (msg) {
441 	case MSG_TYPE_NOTIFICATION:
442 		return ("notification");
443 	case MSG_TYPE_HELLO:
444 		return ("hello");
445 	case MSG_TYPE_INIT:
446 		return ("initialization");
447 	case MSG_TYPE_KEEPALIVE:
448 		return ("keepalive");
449 	case MSG_TYPE_ADDR:
450 		return ("address");
451 	case MSG_TYPE_ADDRWITHDRAW:
452 		return ("address withdraw");
453 	case MSG_TYPE_LABELMAPPING:
454 		return ("label mapping");
455 	case MSG_TYPE_LABELREQUEST:
456 		return ("label request");
457 	case MSG_TYPE_LABELWITHDRAW:
458 		return ("label withdraw");
459 	case MSG_TYPE_LABELRELEASE:
460 		return ("label release");
461 	case MSG_TYPE_LABELABORTREQ:
462 	default:
463 		snprintf(buf, sizeof(buf), "[%08x]", msg);
464 		return (buf);
465 	}
466 }
467 
468 const char *
469 status_code_name(uint32_t status)
470 {
471 	static char buf[16];
472 
473 	switch (status) {
474 	case S_SUCCESS:
475 		return ("Success");
476 	case S_BAD_LDP_ID:
477 		return ("Bad LDP Identifier");
478 	case S_BAD_PROTO_VER:
479 		return ("Bad Protocol Version");
480 	case S_BAD_PDU_LEN:
481 		return ("Bad PDU Length");
482 	case S_UNKNOWN_MSG:
483 		return ("Unknown Message Type");
484 	case S_BAD_MSG_LEN:
485 		return ("Bad Message Length");
486 	case S_UNKNOWN_TLV:
487 		return ("Unknown TLV");
488 	case S_BAD_TLV_LEN:
489 		return ("Bad TLV Length");
490 	case S_BAD_TLV_VAL:
491 		return ("Malformed TLV Value");
492 	case S_HOLDTIME_EXP:
493 		return ("Hold Timer Expired");
494 	case S_SHUTDOWN:
495 		return ("Shutdown");
496 	case S_LOOP_DETECTED:
497 		return ("Loop Detected");
498 	case S_UNKNOWN_FEC:
499 		return ("Unknown FEC");
500 	case S_NO_ROUTE:
501 		return ("No Route");
502 	case S_NO_LABEL_RES:
503 		return ("No Label Resources");
504 	case S_AVAILABLE:
505 		return ("Label Resources Available");
506 	case S_NO_HELLO:
507 		return ("Session Rejected, No Hello");
508 	case S_PARM_ADV_MODE:
509 		return ("Rejected Advertisement Mode Parameter");
510 	case S_MAX_PDU_LEN:
511 		return ("Rejected Max PDU Length Parameter");
512 	case S_PARM_L_RANGE:
513 		return ("Rejected Label Range Parameter");
514 	case S_KEEPALIVE_TMR:
515 		return ("KeepAlive Timer Expired");
516 	case S_LAB_REQ_ABRT:
517 		return ("Label Request Aborted");
518 	case S_MISS_MSG:
519 		return ("Missing Message Parameters");
520 	case S_UNSUP_ADDR:
521 		return ("Unsupported Address Family");
522 	case S_KEEPALIVE_BAD:
523 		return ("Bad KeepAlive Time");
524 	case S_INTERN_ERR:
525 		return ("Internal Error");
526 	case S_ILLEGAL_CBIT:
527 		return ("Illegal C-Bit");
528 	case S_WRONG_CBIT:
529 		return ("Wrong C-Bit");
530 	case S_INCPT_BITRATE:
531 		return ("Incompatible bit-rate");
532 	case S_CEP_MISCONF:
533 		return ("CEP-TDM mis-configuration");
534 	case S_PW_STATUS:
535 		return ("PW Status");
536 	case S_UNASSIGN_TAI:
537 		return ("Unassigned/Unrecognized TAI");
538 	case S_MISCONF_ERR:
539 		return ("Generic Misconfiguration Error");
540 	case S_WITHDRAW_MTHD:
541 		return ("Label Withdraw PW Status Method");
542 	case S_TRANS_MISMTCH:
543 		return ("Transport Connection Mismatch");
544 	case S_DS_NONCMPLNCE:
545 		return ("Dual-Stack Noncompliance");
546 	default:
547 		snprintf(buf, sizeof(buf), "[%08x]", status);
548 		return (buf);
549 	}
550 }
551 
552 const char *
553 pw_type_name(uint16_t pw_type)
554 {
555 	static char buf[64];
556 
557 	switch (pw_type) {
558 	case PW_TYPE_ETHERNET_TAGGED:
559 		return ("Eth Tagged");
560 	case PW_TYPE_ETHERNET:
561 		return ("Ethernet");
562 	default:
563 		snprintf(buf, sizeof(buf), "[%0x]", pw_type);
564 		return (buf);
565 	}
566 }
567 
568 static char *msgtypes[] = {
569 	"",
570 	"RTM_ADD: Add Route",
571 	"RTM_DELETE: Delete Route",
572 	"RTM_CHANGE: Change Metrics or flags",
573 	"RTM_GET: Report Metrics",
574 	"RTM_LOSING: Kernel Suspects Partitioning",
575 	"RTM_REDIRECT: Told to use different route",
576 	"RTM_MISS: Lookup failed on this address",
577 	"RTM_LOCK: fix specified metrics",
578 	"RTM_OLDADD: caused by SIOCADDRT",
579 	"RTM_OLDDEL: caused by SIOCDELRT",
580 	"RTM_RESOLVE: Route created by cloning",
581 	"RTM_NEWADDR: address being added to iface",
582 	"RTM_DELADDR: address being removed from iface",
583 	"RTM_IFINFO: iface status change",
584 	"RTM_IFANNOUNCE: iface arrival/departure",
585 	"RTM_DESYNC: route socket overflow",
586 };
587 
588 void
589 log_rtmsg(unsigned char rtm_type)
590 {
591 	if (!(verbose & LDPD_OPT_VERBOSE2))
592 		return;
593 
594 	if (rtm_type > 0 &&
595 	    rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0]))
596 		log_debug("kernel message: %s", msgtypes[rtm_type]);
597 	else
598 		log_debug("kernel message: rtm_type %d out of range",
599 		    rtm_type);
600 }
601