xref: /openbsd-src/usr.sbin/ldpd/log.c (revision e5157e49389faebcb42b7237d55fbf096d9c2523)
1 /*	$OpenBSD: log.c,v 1.13 2014/11/03 18:44:36 bluhm 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 "log.h"
34 
35 static const char * const procnames[] = {
36 	"parent",
37 	"ldpe",
38 	"lde"
39 };
40 
41 int	debug;
42 int	verbose;
43 
44 void
45 log_init(int n_debug)
46 {
47 	extern char	*__progname;
48 
49 	debug = n_debug;
50 
51 	if (!debug)
52 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
53 
54 	tzset();
55 }
56 
57 void
58 log_verbose(int v)
59 {
60 	verbose = v;
61 }
62 
63 void
64 logit(int pri, const char *fmt, ...)
65 {
66 	va_list	ap;
67 
68 	va_start(ap, fmt);
69 	vlog(pri, fmt, ap);
70 	va_end(ap);
71 }
72 
73 void
74 vlog(int pri, const char *fmt, va_list ap)
75 {
76 	char	*nfmt;
77 
78 	if (debug) {
79 		/* best effort in out of mem situations */
80 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
81 			vfprintf(stderr, fmt, ap);
82 			fprintf(stderr, "\n");
83 		} else {
84 			vfprintf(stderr, nfmt, ap);
85 			free(nfmt);
86 		}
87 		fflush(stderr);
88 	} else
89 		vsyslog(pri, fmt, ap);
90 }
91 
92 void
93 log_warn(const char *emsg, ...)
94 {
95 	char	*nfmt;
96 	va_list	 ap;
97 
98 	/* best effort to even work in out of memory situations */
99 	if (emsg == NULL)
100 		logit(LOG_CRIT, "%s", strerror(errno));
101 	else {
102 		va_start(ap, emsg);
103 
104 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
105 			/* we tried it... */
106 			vlog(LOG_CRIT, emsg, ap);
107 			logit(LOG_CRIT, "%s", strerror(errno));
108 		} else {
109 			vlog(LOG_CRIT, nfmt, ap);
110 			free(nfmt);
111 		}
112 		va_end(ap);
113 	}
114 }
115 
116 void
117 log_warnx(const char *emsg, ...)
118 {
119 	va_list	 ap;
120 
121 	va_start(ap, emsg);
122 	vlog(LOG_CRIT, emsg, ap);
123 	va_end(ap);
124 }
125 
126 void
127 log_info(const char *emsg, ...)
128 {
129 	va_list	 ap;
130 
131 	va_start(ap, emsg);
132 	vlog(LOG_INFO, emsg, ap);
133 	va_end(ap);
134 }
135 
136 void
137 log_debug(const char *emsg, ...)
138 {
139 	va_list	 ap;
140 
141 	if (verbose & LDPD_OPT_VERBOSE) {
142 		va_start(ap, emsg);
143 		vlog(LOG_DEBUG, emsg, ap);
144 		va_end(ap);
145 	}
146 }
147 
148 void
149 fatal(const char *emsg)
150 {
151 	if (emsg == NULL)
152 		logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
153 		    strerror(errno));
154 	else
155 		if (errno)
156 			logit(LOG_CRIT, "fatal in %s: %s: %s",
157 			    procnames[ldpd_process], emsg, strerror(errno));
158 		else
159 			logit(LOG_CRIT, "fatal in %s: %s",
160 			    procnames[ldpd_process], emsg);
161 
162 	if (ldpd_process == PROC_MAIN)
163 		exit(1);
164 	else				/* parent copes via SIGCHLD */
165 		_exit(1);
166 }
167 
168 void
169 fatalx(const char *emsg)
170 {
171 	errno = 0;
172 	fatal(emsg);
173 }
174 
175 /* names */
176 const char *
177 nbr_state_name(int state)
178 {
179 	switch (state) {
180 	case NBR_STA_PRESENT:
181 		return ("PRESENT");
182 	case NBR_STA_INITIAL:
183 		return ("INITIALIZED");
184 	case NBR_STA_OPENREC:
185 		return ("OPENREC");
186 	case NBR_STA_OPENSENT:
187 		return ("OPENSENT");
188 	case NBR_STA_OPER:
189 		return ("OPERATIONAL");
190 	default:
191 		return ("UNKNW");
192 	}
193 }
194 
195 const char *
196 if_state_name(int state)
197 {
198 	switch (state) {
199 	case IF_STA_DOWN:
200 		return ("DOWN");
201 	case IF_STA_ACTIVE:
202 		return ("ACTIVE");
203 	default:
204 		return ("UNKNW");
205 	}
206 }
207 
208 const char *
209 if_type_name(enum iface_type type)
210 {
211 	switch (type) {
212 	case IF_TYPE_POINTOPOINT:
213 		return ("POINTOPOINT");
214 	case IF_TYPE_BROADCAST:
215 		return ("BROADCAST");
216 	}
217 	/* NOTREACHED */
218 	return ("UNKNOWN");
219 }
220 
221 const char *
222 notification_name(u_int32_t status)
223 {
224 	static char buf[16];
225 
226 	switch (status) {
227 	case S_SUCCESS:
228 		return ("Success");
229 	case S_BAD_LDP_ID:
230 		return ("Bad LDP Identifier");
231 	case S_BAD_PROTO_VER:
232 		return ("Bad Protocol Version");
233 	case S_BAD_PDU_LEN:
234 		return ("Bad PDU Length");
235 	case S_UNKNOWN_MSG:
236 		return ("Unknown Message Type");
237 	case S_BAD_MSG_LEN:
238 		return ("Bad Message Length");
239 	case S_UNKNOWN_TLV:
240 		return ("Unknown TLV");
241 	case S_BAD_TLV_LEN:
242 		return ("Bad TLV Length");
243 	case S_BAD_TLV_VAL:
244 		return ("Malformed TLV Value");
245 	case S_HOLDTIME_EXP:
246 		return ("Hold Timer Expired");
247 	case S_SHUTDOWN:
248 		return ("Shutdown");
249 	case S_LOOP_DETECTED:
250 		return ("Loop Detected");
251 	case S_UNKNOWN_FEC:
252 		return ("Unknown FEC");
253 	case S_NO_ROUTE:
254 		return ("No Route");
255 	case S_NO_LABEL_RES:
256 		return ("No Label Resources");
257 	case S_AVAILABLE:
258 		return ("Label Resources Available");
259 	case S_NO_HELLO:
260 		return ("Session Rejected, No Hello");
261 	case S_PARM_ADV_MODE:
262 		return ("Rejected Advertisement Mode Parameter");
263 	case S_MAX_PDU_LEN:
264 		return ("Rejected Max PDU Length Parameter");
265 	case S_PARM_L_RANGE:
266 		return ("Rejected Label Range Parameter");
267 	case S_KEEPALIVE_TMR:
268 		return ("KeepAlive Timer Expired");
269 	case S_LAB_REQ_ABRT:
270 		return ("Label Request Aborted");
271 	case S_MISS_MSG:
272 		return ("Missing Message Parameters");
273 	case S_UNSUP_ADDR:
274 		return ("Unsupported Address Family");
275 	case S_KEEPALIVE_BAD:
276 		return ("Bad KeepAlive Time");
277 	case S_INTERN_ERR:
278 		return ("Internal Error");
279 	default:
280 		snprintf(buf, sizeof(buf), "[%08x]", status);
281 		return (buf);
282 	}
283 }
284 
285 const char *
286 log_fec(struct map *map)
287 {
288 	static char	buf[32];
289 	char		pstr[32];
290 
291 	if (snprintf(buf, sizeof(buf), "%s/%u",
292 	    inet_ntop(AF_INET, &map->prefix, pstr, sizeof(pstr)),
293 	    map->prefixlen) == -1)
294 		return ("???");
295 
296 	return (buf);
297 }
298 
299 static char *msgtypes[] = {
300 	"",
301 	"RTM_ADD: Add Route",
302 	"RTM_DELETE: Delete Route",
303 	"RTM_CHANGE: Change Metrics or flags",
304 	"RTM_GET: Report Metrics",
305 	"RTM_LOSING: Kernel Suspects Partitioning",
306 	"RTM_REDIRECT: Told to use different route",
307 	"RTM_MISS: Lookup failed on this address",
308 	"RTM_LOCK: fix specified metrics",
309 	"RTM_OLDADD: caused by SIOCADDRT",
310 	"RTM_OLDDEL: caused by SIOCDELRT",
311 	"RTM_RESOLVE: Route created by cloning",
312 	"RTM_NEWADDR: address being added to iface",
313 	"RTM_DELADDR: address being removed from iface",
314 	"RTM_IFINFO: iface status change",
315 	"RTM_IFANNOUNCE: iface arrival/departure",
316 	"RTM_DESYNC: route socket overflow",
317 };
318 
319 void
320 log_rtmsg(u_char rtm_type)
321 {
322 	if (!(verbose & LDPD_OPT_VERBOSE2))
323 		return;
324 
325 	if (rtm_type > 0 &&
326 	    rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0]))
327 		log_debug("rtmsg_process: %s", msgtypes[rtm_type]);
328 	else
329 		log_debug("rtmsg_process: rtm_type %d out of range",
330 		    rtm_type);
331 }
332