xref: /openbsd-src/usr.sbin/ospf6d/log.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: log.c,v 1.10 2012/10/22 07:28:49 bluhm Exp $ */
2 
3 /*
4  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 
25 #include <netdb.h>
26 #include <errno.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <syslog.h>
32 #include <unistd.h>
33 
34 #include "ospf6d.h"
35 #include "log.h"
36 
37 static const char * const procnames[] = {
38 	"parent",
39 	"ospfe",
40 	"rde"
41 };
42 
43 int	debug;
44 int	verbose;
45 
46 void	 logit(int, const char *, ...);
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 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) {
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[ospfd_process],
157 		    strerror(errno));
158 	else
159 		if (errno)
160 			logit(LOG_CRIT, "fatal in %s: %s: %s",
161 			    procnames[ospfd_process], emsg, strerror(errno));
162 		else
163 			logit(LOG_CRIT, "fatal in %s: %s",
164 			    procnames[ospfd_process], emsg);
165 
166 	if (ospfd_process == PROC_MAIN)
167 		exit(1);
168 	else				/* parent copes via SIGCHLD */
169 		_exit(1);
170 }
171 
172 void
173 fatalx(const char *emsg)
174 {
175 	errno = 0;
176 	fatal(emsg);
177 }
178 
179 const char *
180 log_in6addr(const struct in6_addr *addr)
181 {
182 	struct sockaddr_in6	sa_in6;
183 
184 	bzero(&sa_in6, sizeof(sa_in6));
185 	sa_in6.sin6_len = sizeof(sa_in6);
186 	sa_in6.sin6_family = AF_INET6;
187 	memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr));
188 
189 	/*
190 	 * Destination addresses contain embedded scopes.
191 	 * They must be recovered for ospf6ctl show fib.
192 	 */
193 	recoverscope(&sa_in6);
194 
195 	return (log_sockaddr(&sa_in6));
196 }
197 
198 const char *
199 log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
200 {
201 	struct sockaddr_in6	sa_in6;
202 
203 	bzero(&sa_in6, sizeof(sa_in6));
204 	sa_in6.sin6_len = sizeof(sa_in6);
205 	sa_in6.sin6_family = AF_INET6;
206 	memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr));
207 
208 	addscope(&sa_in6, ifindex);
209 
210 	return (log_sockaddr(&sa_in6));
211 }
212 
213 #define NUM_LOGS	4
214 const char *
215 log_rtr_id(u_int32_t id)
216 {
217 	static char	buf[NUM_LOGS][16];
218 	static int	round = 0;
219 	struct in_addr	addr;
220 
221 	round = (round + 1) % NUM_LOGS;
222 
223 	addr.s_addr = id;
224 	if (inet_ntop(AF_INET, &addr, buf[round], 16) == NULL)
225 		return ("?");
226 	else
227 		return buf[round];
228 }
229 
230 const char *
231 log_sockaddr(void *vp)
232 {
233 	static char	buf[NUM_LOGS][NI_MAXHOST];
234 	static int	round = 0;
235 	struct sockaddr	*sa = vp;
236 
237 	round = (round + 1) % NUM_LOGS;
238 
239 	if (getnameinfo(sa, sa->sa_len, buf[round], NI_MAXHOST, NULL, 0,
240 	    NI_NUMERICHOST))
241 		return ("(unknown)");
242 	else
243 		return (buf[round]);
244 }
245 
246 /* names */
247 const char *
248 nbr_state_name(int state)
249 {
250 	switch (state) {
251 	case NBR_STA_DOWN:
252 		return ("DOWN");
253 	case NBR_STA_ATTEMPT:
254 		return ("ATTMP");
255 	case NBR_STA_INIT:
256 		return ("INIT");
257 	case NBR_STA_2_WAY:
258 		return ("2-WAY");
259 	case NBR_STA_XSTRT:
260 		return ("EXSTA");
261 	case NBR_STA_SNAP:
262 		return ("SNAP");
263 	case NBR_STA_XCHNG:
264 		return ("EXCHG");
265 	case NBR_STA_LOAD:
266 		return ("LOAD");
267 	case NBR_STA_FULL:
268 		return ("FULL");
269 	default:
270 		return ("UNKNW");
271 	}
272 }
273 
274 const char *
275 if_state_name(int state)
276 {
277 	switch (state) {
278 	case IF_STA_DOWN:
279 		return ("DOWN");
280 	case IF_STA_LOOPBACK:
281 		return ("LOOP");
282 	case IF_STA_WAITING:
283 		return ("WAIT");
284 	case IF_STA_POINTTOPOINT:
285 		return ("P2P");
286 	case IF_STA_DROTHER:
287 		return ("OTHER");
288 	case IF_STA_BACKUP:
289 		return ("BCKUP");
290 	case IF_STA_DR:
291 		return ("DR");
292 	default:
293 		return ("UNKNW");
294 	}
295 }
296 
297 const char *
298 if_type_name(enum iface_type type)
299 {
300 	switch (type) {
301 	case IF_TYPE_POINTOPOINT:
302 		return ("POINTOPOINT");
303 	case IF_TYPE_BROADCAST:
304 		return ("BROADCAST");
305 	case IF_TYPE_NBMA:
306 		return ("NBMA");
307 	case IF_TYPE_POINTOMULTIPOINT:
308 		return ("POINTOMULTIPOINT");
309 	case IF_TYPE_VIRTUALLINK:
310 		return ("VIRTUALLINK");
311 	}
312 	/* NOTREACHED */
313 	return ("UNKNOWN");
314 }
315 
316 const char *
317 dst_type_name(enum dst_type type)
318 {
319 	switch (type) {
320 	case DT_NET:
321 		return ("Network");
322 	case DT_RTR:
323 		return ("Router");
324 	}
325 	/* NOTREACHED */
326 	return ("unknown");
327 }
328 
329 const char *
330 path_type_name(enum path_type type)
331 {
332 	switch (type) {
333 	case PT_INTRA_AREA:
334 		return ("Intra-Area");
335 	case PT_INTER_AREA:
336 		return ("Inter-Area");
337 	case PT_TYPE1_EXT:
338 		return ("Type 1 ext");
339 	case PT_TYPE2_EXT:
340 		return ("Type 2 ext");
341 	}
342 	/* NOTREACHED */
343 	return ("unknown");
344 }
345