xref: /openbsd/usr.sbin/ldpd/log.c (revision d99a8fc3)
1 /*	$OpenBSD: log.c,v 1.20 2016/05/23 16:20:59 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 <netinet/in.h>
22 #include <arpa/inet.h>
23 
24 #include <errno.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <unistd.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 int	debug;
44 int	verbose;
45 
46 void
47 log_init(int n_debug)
48 {
49 	extern char	*__progname;
50 
51 	debug = n_debug;
52 
53 	if (!debug)
54 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
55 
56 	tzset();
57 }
58 
59 void
60 log_verbose(int v)
61 {
62 	verbose = v;
63 }
64 
65 void
66 logit(int pri, const char *fmt, ...)
67 {
68 	va_list	ap;
69 
70 	va_start(ap, fmt);
71 	vlog(pri, fmt, ap);
72 	va_end(ap);
73 }
74 
75 void
76 vlog(int pri, const char *fmt, va_list ap)
77 {
78 	char	*nfmt;
79 
80 	if (debug) {
81 		/* best effort in out of mem situations */
82 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
83 			vfprintf(stderr, fmt, ap);
84 			fprintf(stderr, "\n");
85 		} else {
86 			vfprintf(stderr, nfmt, ap);
87 			free(nfmt);
88 		}
89 		fflush(stderr);
90 	} else
91 		vsyslog(pri, fmt, ap);
92 }
93 
94 void
95 log_warn(const char *emsg, ...)
96 {
97 	char	*nfmt;
98 	va_list	 ap;
99 
100 	/* best effort to even work in out of memory situations */
101 	if (emsg == NULL)
102 		logit(LOG_CRIT, "%s", strerror(errno));
103 	else {
104 		va_start(ap, emsg);
105 
106 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
107 			/* we tried it... */
108 			vlog(LOG_CRIT, emsg, ap);
109 			logit(LOG_CRIT, "%s", strerror(errno));
110 		} else {
111 			vlog(LOG_CRIT, nfmt, ap);
112 			free(nfmt);
113 		}
114 		va_end(ap);
115 	}
116 }
117 
118 void
119 log_warnx(const char *emsg, ...)
120 {
121 	va_list	 ap;
122 
123 	va_start(ap, emsg);
124 	vlog(LOG_CRIT, emsg, ap);
125 	va_end(ap);
126 }
127 
128 void
129 log_info(const char *emsg, ...)
130 {
131 	va_list	 ap;
132 
133 	va_start(ap, emsg);
134 	vlog(LOG_INFO, emsg, ap);
135 	va_end(ap);
136 }
137 
138 void
139 log_debug(const char *emsg, ...)
140 {
141 	va_list	 ap;
142 
143 	if (verbose & LDPD_OPT_VERBOSE) {
144 		va_start(ap, emsg);
145 		vlog(LOG_DEBUG, emsg, ap);
146 		va_end(ap);
147 	}
148 }
149 
150 void
151 fatal(const char *emsg)
152 {
153 	if (emsg == NULL)
154 		logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
155 		    strerror(errno));
156 	else
157 		if (errno)
158 			logit(LOG_CRIT, "fatal in %s: %s: %s",
159 			    procnames[ldpd_process], emsg, strerror(errno));
160 		else
161 			logit(LOG_CRIT, "fatal in %s: %s",
162 			    procnames[ldpd_process], emsg);
163 
164 	if (ldpd_process == PROC_MAIN)
165 		exit(1);
166 	else				/* parent copes via SIGCHLD */
167 		_exit(1);
168 }
169 
170 void
171 fatalx(const char *emsg)
172 {
173 	errno = 0;
174 	fatal(emsg);
175 }
176 
177 /* names */
178 const char *
179 nbr_state_name(int state)
180 {
181 	switch (state) {
182 	case NBR_STA_PRESENT:
183 		return ("PRESENT");
184 	case NBR_STA_INITIAL:
185 		return ("INITIALIZED");
186 	case NBR_STA_OPENREC:
187 		return ("OPENREC");
188 	case NBR_STA_OPENSENT:
189 		return ("OPENSENT");
190 	case NBR_STA_OPER:
191 		return ("OPERATIONAL");
192 	default:
193 		return ("UNKNOWN");
194 	}
195 }
196 
197 const char *
198 if_state_name(int state)
199 {
200 	switch (state) {
201 	case IF_STA_DOWN:
202 		return ("DOWN");
203 	case IF_STA_ACTIVE:
204 		return ("ACTIVE");
205 	default:
206 		return ("UNKNOWN");
207 	}
208 }
209 
210 const char *
211 if_type_name(enum iface_type type)
212 {
213 	switch (type) {
214 	case IF_TYPE_POINTOPOINT:
215 		return ("POINTOPOINT");
216 	case IF_TYPE_BROADCAST:
217 		return ("BROADCAST");
218 	}
219 	/* NOTREACHED */
220 	return ("UNKNOWN");
221 }
222 
223 const char *
224 notification_name(u_int32_t status)
225 {
226 	static char buf[16];
227 
228 	switch (status) {
229 	case S_SUCCESS:
230 		return ("Success");
231 	case S_BAD_LDP_ID:
232 		return ("Bad LDP Identifier");
233 	case S_BAD_PROTO_VER:
234 		return ("Bad Protocol Version");
235 	case S_BAD_PDU_LEN:
236 		return ("Bad PDU Length");
237 	case S_UNKNOWN_MSG:
238 		return ("Unknown Message Type");
239 	case S_BAD_MSG_LEN:
240 		return ("Bad Message Length");
241 	case S_UNKNOWN_TLV:
242 		return ("Unknown TLV");
243 	case S_BAD_TLV_LEN:
244 		return ("Bad TLV Length");
245 	case S_BAD_TLV_VAL:
246 		return ("Malformed TLV Value");
247 	case S_HOLDTIME_EXP:
248 		return ("Hold Timer Expired");
249 	case S_SHUTDOWN:
250 		return ("Shutdown");
251 	case S_LOOP_DETECTED:
252 		return ("Loop Detected");
253 	case S_UNKNOWN_FEC:
254 		return ("Unknown FEC");
255 	case S_NO_ROUTE:
256 		return ("No Route");
257 	case S_NO_LABEL_RES:
258 		return ("No Label Resources");
259 	case S_AVAILABLE:
260 		return ("Label Resources Available");
261 	case S_NO_HELLO:
262 		return ("Session Rejected, No Hello");
263 	case S_PARM_ADV_MODE:
264 		return ("Rejected Advertisement Mode Parameter");
265 	case S_MAX_PDU_LEN:
266 		return ("Rejected Max PDU Length Parameter");
267 	case S_PARM_L_RANGE:
268 		return ("Rejected Label Range Parameter");
269 	case S_KEEPALIVE_TMR:
270 		return ("KeepAlive Timer Expired");
271 	case S_LAB_REQ_ABRT:
272 		return ("Label Request Aborted");
273 	case S_MISS_MSG:
274 		return ("Missing Message Parameters");
275 	case S_UNSUP_ADDR:
276 		return ("Unsupported Address Family");
277 	case S_KEEPALIVE_BAD:
278 		return ("Bad KeepAlive Time");
279 	case S_INTERN_ERR:
280 		return ("Internal Error");
281 	case S_ILLEGAL_CBIT:
282 		return ("Illegal C-Bit");
283 	case S_WRONG_CBIT:
284 		return ("Wrong C-Bit");
285 	case S_INCPT_BITRATE:
286 		return ("Incompatible bit-rate");
287 	case S_CEP_MISCONF:
288 		return ("CEP-TDM mis-configuration");
289 	case S_PW_STATUS:
290 		return ("PW Status");
291 	case S_UNASSIGN_TAI:
292 		return ("Unassigned/Unrecognized TAI");
293 	case S_MISCONF_ERR:
294 		return ("Generic Misconfiguration Error");
295 	case S_WITHDRAW_MTHD:
296 		return ("Label Withdraw PW Status Method");
297 	default:
298 		snprintf(buf, sizeof(buf), "[%08x]", status);
299 		return (buf);
300 	}
301 }
302 
303 const char *
304 pw_type_name(u_int16_t pw_type)
305 {
306 	static char buf[64];
307 
308 	switch (pw_type) {
309 	case PW_TYPE_ETHERNET_TAGGED:
310 		return ("Eth Tagged");
311 	case PW_TYPE_ETHERNET:
312 		return ("Ethernet");
313 	default:
314 		snprintf(buf, sizeof(buf), "[%0x]", pw_type);
315 		return (buf);
316 	}
317 }
318 
319 char *
320 log_hello_src(const struct hello_source *src)
321 {
322 	static char buffer[64];
323 
324 	switch (src->type) {
325 	case HELLO_LINK:
326 		snprintf(buffer, sizeof(buffer), "iface %s",
327 		    src->link.iface->name);
328 		break;
329 	case HELLO_TARGETED:
330 		snprintf(buffer, sizeof(buffer), "source %s",
331 		    inet_ntoa(src->target->addr));
332 		break;
333 	}
334 
335 	return (buffer);
336 }
337 
338 const char *
339 log_map(struct map *map)
340 {
341 	static char	buf[64];
342 	char		pstr[64];
343 
344 	switch (map->type) {
345 	case MAP_TYPE_WILDCARD:
346 		if (snprintf(buf, sizeof(buf), "wildcard") < 0)
347 			return ("???");
348 		break;
349 	case MAP_TYPE_PREFIX:
350 		if (snprintf(buf, sizeof(buf), "%s/%u",
351 		    inet_ntop(AF_INET, &map->fec.ipv4.prefix, pstr,
352 		    sizeof(pstr)), map->fec.ipv4.prefixlen) == -1)
353 			return ("???");
354 		break;
355 	case MAP_TYPE_PWID:
356 		if (snprintf(buf, sizeof(buf), "pwid %u (%s)",
357 		    map->fec.pwid.pwid,
358 		    pw_type_name(map->fec.pwid.type)) == -1)
359 			return ("???");
360 		break;
361 	default:
362 		return ("???");
363 	}
364 
365 	return (buf);
366 }
367 
368 const char *
369 log_fec(struct fec *fec)
370 {
371 	static char	buf[64];
372 	char		pstr[32];
373 
374 	switch (fec->type) {
375 	case FEC_TYPE_IPV4:
376 		if (snprintf(buf, sizeof(buf), "%s/%u",
377 		    inet_ntop(AF_INET, &fec->u.ipv4.prefix, pstr,
378 		    sizeof(pstr)), fec->u.ipv4.prefixlen) == -1)
379 			return ("???");
380 		break;
381 	case FEC_TYPE_PWID:
382 		if (snprintf(buf, sizeof(buf),
383 		    "pwid %u (%s) - %s",
384 		    fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
385 		    inet_ntoa(fec->u.pwid.nexthop)) == -1)
386 			return ("???");
387 		break;
388 	default:
389 		return ("???");
390 	}
391 
392 	return (buf);
393 }
394 
395 static char *msgtypes[] = {
396 	"",
397 	"RTM_ADD: Add Route",
398 	"RTM_DELETE: Delete Route",
399 	"RTM_CHANGE: Change Metrics or flags",
400 	"RTM_GET: Report Metrics",
401 	"RTM_LOSING: Kernel Suspects Partitioning",
402 	"RTM_REDIRECT: Told to use different route",
403 	"RTM_MISS: Lookup failed on this address",
404 	"RTM_LOCK: fix specified metrics",
405 	"RTM_OLDADD: caused by SIOCADDRT",
406 	"RTM_OLDDEL: caused by SIOCDELRT",
407 	"RTM_RESOLVE: Route created by cloning",
408 	"RTM_NEWADDR: address being added to iface",
409 	"RTM_DELADDR: address being removed from iface",
410 	"RTM_IFINFO: iface status change",
411 	"RTM_IFANNOUNCE: iface arrival/departure",
412 	"RTM_DESYNC: route socket overflow",
413 };
414 
415 void
416 log_rtmsg(u_char rtm_type)
417 {
418 	if (!(verbose & LDPD_OPT_VERBOSE2))
419 		return;
420 
421 	if (rtm_type > 0 &&
422 	    rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0]))
423 		log_debug("kernel message: %s", msgtypes[rtm_type]);
424 	else
425 		log_debug("kernel message: rtm_type %d out of range",
426 		    rtm_type);
427 }
428