xref: /openbsd/usr.sbin/ldpd/log.c (revision 84f16a94)
1*84f16a94Sclaudio /*	$OpenBSD: log.c,v 1.11 2013/06/01 20:13:04 claudio Exp $ */
2ab0c2486Smichele 
3ab0c2486Smichele /*
4ab0c2486Smichele  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5ab0c2486Smichele  *
6ab0c2486Smichele  * Permission to use, copy, modify, and distribute this software for any
7ab0c2486Smichele  * purpose with or without fee is hereby granted, provided that the above
8ab0c2486Smichele  * copyright notice and this permission notice appear in all copies.
9ab0c2486Smichele  *
10ab0c2486Smichele  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11ab0c2486Smichele  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12ab0c2486Smichele  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13ab0c2486Smichele  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14ab0c2486Smichele  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15ab0c2486Smichele  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16ab0c2486Smichele  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17ab0c2486Smichele  */
18ab0c2486Smichele 
190211d6d6Sclaudio #include <sys/types.h>
200211d6d6Sclaudio #include <sys/socket.h>
210211d6d6Sclaudio #include <netinet/in.h>
220211d6d6Sclaudio #include <arpa/inet.h>
230211d6d6Sclaudio 
24ab0c2486Smichele #include <errno.h>
25ab0c2486Smichele #include <stdarg.h>
26ab0c2486Smichele #include <stdio.h>
27ab0c2486Smichele #include <stdlib.h>
28ab0c2486Smichele #include <string.h>
29ab0c2486Smichele #include <syslog.h>
30ab0c2486Smichele #include <unistd.h>
31ab0c2486Smichele 
32ab0c2486Smichele #include "ldpd.h"
33ab0c2486Smichele #include "log.h"
34ab0c2486Smichele 
35ab0c2486Smichele static const char * const procnames[] = {
36ab0c2486Smichele 	"parent",
37ab0c2486Smichele 	"ldpe",
38ab0c2486Smichele 	"lde"
39ab0c2486Smichele };
40ab0c2486Smichele 
41ab0c2486Smichele int	debug;
427dc5fe12Sclaudio int	verbose;
43ab0c2486Smichele 
44ab0c2486Smichele void	 logit(int, const char *, ...);
45ab0c2486Smichele 
46ab0c2486Smichele void
47ab0c2486Smichele log_init(int n_debug)
48ab0c2486Smichele {
49ab0c2486Smichele 	extern char	*__progname;
50ab0c2486Smichele 
51ab0c2486Smichele 	debug = n_debug;
52ab0c2486Smichele 
53ab0c2486Smichele 	if (!debug)
54ab0c2486Smichele 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
55ab0c2486Smichele 
56ab0c2486Smichele 	tzset();
57ab0c2486Smichele }
58ab0c2486Smichele 
59ab0c2486Smichele void
607dc5fe12Sclaudio log_verbose(int v)
617dc5fe12Sclaudio {
627dc5fe12Sclaudio 	verbose = v;
637dc5fe12Sclaudio }
647dc5fe12Sclaudio 
657dc5fe12Sclaudio void
66ab0c2486Smichele logit(int pri, const char *fmt, ...)
67ab0c2486Smichele {
68ab0c2486Smichele 	va_list	ap;
69ab0c2486Smichele 
70ab0c2486Smichele 	va_start(ap, fmt);
71ab0c2486Smichele 	vlog(pri, fmt, ap);
72ab0c2486Smichele 	va_end(ap);
73ab0c2486Smichele }
74ab0c2486Smichele 
75ab0c2486Smichele void
76ab0c2486Smichele vlog(int pri, const char *fmt, va_list ap)
77ab0c2486Smichele {
78ab0c2486Smichele 	char	*nfmt;
79ab0c2486Smichele 
80ab0c2486Smichele 	if (debug) {
81ab0c2486Smichele 		/* best effort in out of mem situations */
82ab0c2486Smichele 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
83ab0c2486Smichele 			vfprintf(stderr, fmt, ap);
84ab0c2486Smichele 			fprintf(stderr, "\n");
85ab0c2486Smichele 		} else {
86ab0c2486Smichele 			vfprintf(stderr, nfmt, ap);
87ab0c2486Smichele 			free(nfmt);
88ab0c2486Smichele 		}
89ab0c2486Smichele 		fflush(stderr);
90ab0c2486Smichele 	} else
91ab0c2486Smichele 		vsyslog(pri, fmt, ap);
92ab0c2486Smichele }
93ab0c2486Smichele 
94ab0c2486Smichele void
95ab0c2486Smichele log_warn(const char *emsg, ...)
96ab0c2486Smichele {
97ab0c2486Smichele 	char	*nfmt;
98ab0c2486Smichele 	va_list	 ap;
99ab0c2486Smichele 
100ab0c2486Smichele 	/* best effort to even work in out of memory situations */
101ab0c2486Smichele 	if (emsg == NULL)
102ab0c2486Smichele 		logit(LOG_CRIT, "%s", strerror(errno));
103ab0c2486Smichele 	else {
104ab0c2486Smichele 		va_start(ap, emsg);
105ab0c2486Smichele 
106ab0c2486Smichele 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
107ab0c2486Smichele 			/* we tried it... */
108ab0c2486Smichele 			vlog(LOG_CRIT, emsg, ap);
109ab0c2486Smichele 			logit(LOG_CRIT, "%s", strerror(errno));
110ab0c2486Smichele 		} else {
111ab0c2486Smichele 			vlog(LOG_CRIT, nfmt, ap);
112ab0c2486Smichele 			free(nfmt);
113ab0c2486Smichele 		}
114ab0c2486Smichele 		va_end(ap);
115ab0c2486Smichele 	}
116ab0c2486Smichele }
117ab0c2486Smichele 
118ab0c2486Smichele void
119ab0c2486Smichele log_warnx(const char *emsg, ...)
120ab0c2486Smichele {
121ab0c2486Smichele 	va_list	 ap;
122ab0c2486Smichele 
123ab0c2486Smichele 	va_start(ap, emsg);
124ab0c2486Smichele 	vlog(LOG_CRIT, emsg, ap);
125ab0c2486Smichele 	va_end(ap);
126ab0c2486Smichele }
127ab0c2486Smichele 
128ab0c2486Smichele void
129ab0c2486Smichele log_info(const char *emsg, ...)
130ab0c2486Smichele {
131ab0c2486Smichele 	va_list	 ap;
132ab0c2486Smichele 
133ab0c2486Smichele 	va_start(ap, emsg);
134ab0c2486Smichele 	vlog(LOG_INFO, emsg, ap);
135ab0c2486Smichele 	va_end(ap);
136ab0c2486Smichele }
137ab0c2486Smichele 
138ab0c2486Smichele void
139ab0c2486Smichele log_debug(const char *emsg, ...)
140ab0c2486Smichele {
141ab0c2486Smichele 	va_list	 ap;
142ab0c2486Smichele 
143*84f16a94Sclaudio 	if (verbose & LDPD_OPT_VERBOSE) {
144ab0c2486Smichele 		va_start(ap, emsg);
145ab0c2486Smichele 		vlog(LOG_DEBUG, emsg, ap);
146ab0c2486Smichele 		va_end(ap);
147ab0c2486Smichele 	}
148ab0c2486Smichele }
149ab0c2486Smichele 
150ab0c2486Smichele void
151ab0c2486Smichele fatal(const char *emsg)
152ab0c2486Smichele {
153ab0c2486Smichele 	if (emsg == NULL)
154ab0c2486Smichele 		logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
155ab0c2486Smichele 		    strerror(errno));
156ab0c2486Smichele 	else
157ab0c2486Smichele 		if (errno)
158ab0c2486Smichele 			logit(LOG_CRIT, "fatal in %s: %s: %s",
159ab0c2486Smichele 			    procnames[ldpd_process], emsg, strerror(errno));
160ab0c2486Smichele 		else
161ab0c2486Smichele 			logit(LOG_CRIT, "fatal in %s: %s",
162ab0c2486Smichele 			    procnames[ldpd_process], emsg);
163ab0c2486Smichele 
164ab0c2486Smichele 	if (ldpd_process == PROC_MAIN)
165ab0c2486Smichele 		exit(1);
166ab0c2486Smichele 	else				/* parent copes via SIGCHLD */
167ab0c2486Smichele 		_exit(1);
168ab0c2486Smichele }
169ab0c2486Smichele 
170ab0c2486Smichele void
171ab0c2486Smichele fatalx(const char *emsg)
172ab0c2486Smichele {
173ab0c2486Smichele 	errno = 0;
174ab0c2486Smichele 	fatal(emsg);
175ab0c2486Smichele }
176ab0c2486Smichele 
177ab0c2486Smichele /* names */
178ab0c2486Smichele const char *
179ab0c2486Smichele nbr_state_name(int state)
180ab0c2486Smichele {
181ab0c2486Smichele 	switch (state) {
182ab0c2486Smichele 	case NBR_STA_DOWN:
183ab0c2486Smichele 		return ("DOWN");
184ab0c2486Smichele 	case NBR_STA_PRESENT:
185ab0c2486Smichele 		return ("PRESENT");
186ab0c2486Smichele 	case NBR_STA_INITIAL:
187ab0c2486Smichele 		return ("INITIALIZED");
188ab0c2486Smichele 	case NBR_STA_OPENREC:
189ab0c2486Smichele 		return ("OPENREC");
190ab0c2486Smichele 	case NBR_STA_OPENSENT:
191ab0c2486Smichele 		return ("OPENSENT");
192ab0c2486Smichele 	case NBR_STA_OPER:
193ab0c2486Smichele 		return ("OPERATIONAL");
194ab0c2486Smichele 	default:
195ab0c2486Smichele 		return ("UNKNW");
196ab0c2486Smichele 	}
197ab0c2486Smichele }
198ab0c2486Smichele 
199ab0c2486Smichele const char *
200ab0c2486Smichele if_state_name(int state)
201ab0c2486Smichele {
202ab0c2486Smichele 	switch (state) {
203ab0c2486Smichele 	case IF_STA_DOWN:
204ab0c2486Smichele 		return ("DOWN");
205ab0c2486Smichele 	case IF_STA_ACTIVE:
206ab0c2486Smichele 		return ("ACTIVE");
207ab0c2486Smichele 	default:
208ab0c2486Smichele 		return ("UNKNW");
209ab0c2486Smichele 	}
210ab0c2486Smichele }
211ab0c2486Smichele 
212ab0c2486Smichele const char *
213ab0c2486Smichele if_type_name(enum iface_type type)
214ab0c2486Smichele {
215ab0c2486Smichele 	switch (type) {
216ab0c2486Smichele 	case IF_TYPE_POINTOPOINT:
217ab0c2486Smichele 		return ("POINTOPOINT");
218ab0c2486Smichele 	case IF_TYPE_BROADCAST:
219ab0c2486Smichele 		return ("BROADCAST");
220ab0c2486Smichele 	}
221ab0c2486Smichele 	/* NOTREACHED */
222ab0c2486Smichele 	return ("UNKNOWN");
223ab0c2486Smichele }
22497f1ae41Sclaudio 
22597f1ae41Sclaudio const char *
22697f1ae41Sclaudio notification_name(u_int32_t status)
22797f1ae41Sclaudio {
22897f1ae41Sclaudio 	static char buf[16];
22997f1ae41Sclaudio 
23097f1ae41Sclaudio 	switch (status) {
23197f1ae41Sclaudio 	case S_SUCCESS:
23297f1ae41Sclaudio 		return ("Success");
23397f1ae41Sclaudio 	case S_BAD_LDP_ID:
23497f1ae41Sclaudio 		return ("Bad LDP Identifier");
23597f1ae41Sclaudio 	case S_BAD_PROTO_VER:
23697f1ae41Sclaudio 		return ("Bad Protocol Version");
23797f1ae41Sclaudio 	case S_BAD_PDU_LEN:
23897f1ae41Sclaudio 		return ("Bad PDU Length");
23997f1ae41Sclaudio 	case S_UNKNOWN_MSG:
24097f1ae41Sclaudio 		return ("Unknown Message Type");
24197f1ae41Sclaudio 	case S_BAD_MSG_LEN:
24297f1ae41Sclaudio 		return ("Bad Message Length");
24397f1ae41Sclaudio 	case S_UNKNOWN_TLV:
24497f1ae41Sclaudio 		return ("Unknown TLV");
24597f1ae41Sclaudio 	case S_BAD_TLV_LEN:
24697f1ae41Sclaudio 		return ("Bad TLV Length");
24797f1ae41Sclaudio 	case S_BAD_TLV_VAL:
24897f1ae41Sclaudio 		return ("Malformed TLV Value");
24997f1ae41Sclaudio 	case S_HOLDTIME_EXP:
25097f1ae41Sclaudio 		return ("Hold Timer Expired");
25197f1ae41Sclaudio 	case S_SHUTDOWN:
25297f1ae41Sclaudio 		return ("Shutdown");
25397f1ae41Sclaudio 	case S_LOOP_DETECTED:
25497f1ae41Sclaudio 		return ("Loop Detected");
25597f1ae41Sclaudio 	case S_UNKNOWN_FEC:
25697f1ae41Sclaudio 		return ("Unknown FEC");
25797f1ae41Sclaudio 	case S_NO_ROUTE:
25897f1ae41Sclaudio 		return ("No Route");
25997f1ae41Sclaudio 	case S_NO_LABEL_RES:
26097f1ae41Sclaudio 		return ("No Label Resources");
26197f1ae41Sclaudio 	case S_AVAILABLE:
26297f1ae41Sclaudio 		return ("Label Resources Available");
26397f1ae41Sclaudio 	case S_NO_HELLO:
26497f1ae41Sclaudio 		return ("Session Rejected, No Hello");
26597f1ae41Sclaudio 	case S_PARM_ADV_MODE:
26697f1ae41Sclaudio 		return ("Rejected Advertisement Mode Parameter");
26797f1ae41Sclaudio 	case S_MAX_PDU_LEN:
26897f1ae41Sclaudio 		return ("Rejected Max PDU Length Parameter");
26997f1ae41Sclaudio 	case S_PARM_L_RANGE:
27097f1ae41Sclaudio 		return ("Rejected Label Range Parameter");
27197f1ae41Sclaudio 	case S_KEEPALIVE_TMR:
27297f1ae41Sclaudio 		return ("KeepAlive Timer Expired");
27397f1ae41Sclaudio 	case S_LAB_REQ_ABRT:
27497f1ae41Sclaudio 		return ("Label Request Aborted");
27597f1ae41Sclaudio 	case S_MISS_MSG:
27697f1ae41Sclaudio 		return ("Missing Message Parameters");
27797f1ae41Sclaudio 	case S_UNSUP_ADDR:
27897f1ae41Sclaudio 		return ("Unsupported Address Family");
27997f1ae41Sclaudio 	case S_KEEPALIVE_BAD:
28097f1ae41Sclaudio 		return ("Bad KeepAlive Time");
28197f1ae41Sclaudio 	case S_INTERN_ERR:
28297f1ae41Sclaudio 		return ("Internal Error");
28397f1ae41Sclaudio 	default:
28497f1ae41Sclaudio 		snprintf(buf, sizeof(buf), "[%08x]", status);
28597f1ae41Sclaudio 		return (buf);
28697f1ae41Sclaudio 	}
28797f1ae41Sclaudio }
2880211d6d6Sclaudio 
2890211d6d6Sclaudio const char *
2900211d6d6Sclaudio log_fec(struct map *map)
2910211d6d6Sclaudio {
2920211d6d6Sclaudio 	static char	buf[32];
2930211d6d6Sclaudio 	char		pstr[32];
2940211d6d6Sclaudio 
29540858acaSclaudio 	if (snprintf(buf, sizeof(buf), "%s/%u",
2960211d6d6Sclaudio 	    inet_ntop(AF_INET, &map->prefix, pstr, sizeof(pstr)),
2970211d6d6Sclaudio 	    map->prefixlen) == -1)
29840858acaSclaudio 		return ("???");
2990211d6d6Sclaudio 
3000211d6d6Sclaudio 	return (buf);
3010211d6d6Sclaudio }
302*84f16a94Sclaudio 
303*84f16a94Sclaudio static char *msgtypes[] = {
304*84f16a94Sclaudio 	"",
305*84f16a94Sclaudio 	"RTM_ADD: Add Route",
306*84f16a94Sclaudio 	"RTM_DELETE: Delete Route",
307*84f16a94Sclaudio 	"RTM_CHANGE: Change Metrics or flags",
308*84f16a94Sclaudio 	"RTM_GET: Report Metrics",
309*84f16a94Sclaudio 	"RTM_LOSING: Kernel Suspects Partitioning",
310*84f16a94Sclaudio 	"RTM_REDIRECT: Told to use different route",
311*84f16a94Sclaudio 	"RTM_MISS: Lookup failed on this address",
312*84f16a94Sclaudio 	"RTM_LOCK: fix specified metrics",
313*84f16a94Sclaudio 	"RTM_OLDADD: caused by SIOCADDRT",
314*84f16a94Sclaudio 	"RTM_OLDDEL: caused by SIOCDELRT",
315*84f16a94Sclaudio 	"RTM_RESOLVE: Route created by cloning",
316*84f16a94Sclaudio 	"RTM_NEWADDR: address being added to iface",
317*84f16a94Sclaudio 	"RTM_DELADDR: address being removed from iface",
318*84f16a94Sclaudio 	"RTM_IFINFO: iface status change",
319*84f16a94Sclaudio 	"RTM_IFANNOUNCE: iface arrival/departure",
320*84f16a94Sclaudio 	"RTM_DESYNC: route socket overflow",
321*84f16a94Sclaudio };
322*84f16a94Sclaudio 
323*84f16a94Sclaudio void
324*84f16a94Sclaudio log_rtmsg(u_char rtm_type)
325*84f16a94Sclaudio {
326*84f16a94Sclaudio 	if (!(verbose & LDPD_OPT_VERBOSE2))
327*84f16a94Sclaudio 		return;
328*84f16a94Sclaudio 
329*84f16a94Sclaudio 	if (rtm_type > 0 &&
330*84f16a94Sclaudio 	    rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0]))
331*84f16a94Sclaudio 		log_debug("rtmsg_process: %s", msgtypes[rtm_type]);
332*84f16a94Sclaudio 	else
333*84f16a94Sclaudio 		log_debug("rtmsg_process: rtm_type %d out of range",
334*84f16a94Sclaudio 		    rtm_type);
335*84f16a94Sclaudio }
336