xref: /openbsd-src/usr.sbin/ldpd/log.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: log.c,v 1.12 2013/06/04 02:25:28 claudio 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	 logit(int, const char *, ...);
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 ("UNKNW");
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 ("UNKNW");
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 	default:
282 		snprintf(buf, sizeof(buf), "[%08x]", status);
283 		return (buf);
284 	}
285 }
286 
287 const char *
288 log_fec(struct map *map)
289 {
290 	static char	buf[32];
291 	char		pstr[32];
292 
293 	if (snprintf(buf, sizeof(buf), "%s/%u",
294 	    inet_ntop(AF_INET, &map->prefix, pstr, sizeof(pstr)),
295 	    map->prefixlen) == -1)
296 		return ("???");
297 
298 	return (buf);
299 }
300 
301 static char *msgtypes[] = {
302 	"",
303 	"RTM_ADD: Add Route",
304 	"RTM_DELETE: Delete Route",
305 	"RTM_CHANGE: Change Metrics or flags",
306 	"RTM_GET: Report Metrics",
307 	"RTM_LOSING: Kernel Suspects Partitioning",
308 	"RTM_REDIRECT: Told to use different route",
309 	"RTM_MISS: Lookup failed on this address",
310 	"RTM_LOCK: fix specified metrics",
311 	"RTM_OLDADD: caused by SIOCADDRT",
312 	"RTM_OLDDEL: caused by SIOCDELRT",
313 	"RTM_RESOLVE: Route created by cloning",
314 	"RTM_NEWADDR: address being added to iface",
315 	"RTM_DELADDR: address being removed from iface",
316 	"RTM_IFINFO: iface status change",
317 	"RTM_IFANNOUNCE: iface arrival/departure",
318 	"RTM_DESYNC: route socket overflow",
319 };
320 
321 void
322 log_rtmsg(u_char rtm_type)
323 {
324 	if (!(verbose & LDPD_OPT_VERBOSE2))
325 		return;
326 
327 	if (rtm_type > 0 &&
328 	    rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0]))
329 		log_debug("rtmsg_process: %s", msgtypes[rtm_type]);
330 	else
331 		log_debug("rtmsg_process: rtm_type %d out of range",
332 		    rtm_type);
333 }
334