xref: /openbsd-src/usr.sbin/ospf6d/log.c (revision 2777ee89d0e541ec819d05abee114837837abbec)
1 /*	$OpenBSD: log.c,v 1.11 2014/11/03 07:40:31 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
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) {
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[ospfd_process],
155 		    strerror(errno));
156 	else
157 		if (errno)
158 			logit(LOG_CRIT, "fatal in %s: %s: %s",
159 			    procnames[ospfd_process], emsg, strerror(errno));
160 		else
161 			logit(LOG_CRIT, "fatal in %s: %s",
162 			    procnames[ospfd_process], emsg);
163 
164 	if (ospfd_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 const char *
178 log_in6addr(const struct in6_addr *addr)
179 {
180 	struct sockaddr_in6	sa_in6;
181 
182 	bzero(&sa_in6, sizeof(sa_in6));
183 	sa_in6.sin6_len = sizeof(sa_in6);
184 	sa_in6.sin6_family = AF_INET6;
185 	memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr));
186 
187 	/*
188 	 * Destination addresses contain embedded scopes.
189 	 * They must be recovered for ospf6ctl show fib.
190 	 */
191 	recoverscope(&sa_in6);
192 
193 	return (log_sockaddr(&sa_in6));
194 }
195 
196 const char *
197 log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
198 {
199 	struct sockaddr_in6	sa_in6;
200 
201 	bzero(&sa_in6, sizeof(sa_in6));
202 	sa_in6.sin6_len = sizeof(sa_in6);
203 	sa_in6.sin6_family = AF_INET6;
204 	memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr));
205 
206 	addscope(&sa_in6, ifindex);
207 
208 	return (log_sockaddr(&sa_in6));
209 }
210 
211 #define NUM_LOGS	4
212 const char *
213 log_rtr_id(u_int32_t id)
214 {
215 	static char	buf[NUM_LOGS][16];
216 	static int	round = 0;
217 	struct in_addr	addr;
218 
219 	round = (round + 1) % NUM_LOGS;
220 
221 	addr.s_addr = id;
222 	if (inet_ntop(AF_INET, &addr, buf[round], 16) == NULL)
223 		return ("?");
224 	else
225 		return buf[round];
226 }
227 
228 const char *
229 log_sockaddr(void *vp)
230 {
231 	static char	buf[NUM_LOGS][NI_MAXHOST];
232 	static int	round = 0;
233 	struct sockaddr	*sa = vp;
234 
235 	round = (round + 1) % NUM_LOGS;
236 
237 	if (getnameinfo(sa, sa->sa_len, buf[round], NI_MAXHOST, NULL, 0,
238 	    NI_NUMERICHOST))
239 		return ("(unknown)");
240 	else
241 		return (buf[round]);
242 }
243 
244 /* names */
245 const char *
246 nbr_state_name(int state)
247 {
248 	switch (state) {
249 	case NBR_STA_DOWN:
250 		return ("DOWN");
251 	case NBR_STA_ATTEMPT:
252 		return ("ATTMP");
253 	case NBR_STA_INIT:
254 		return ("INIT");
255 	case NBR_STA_2_WAY:
256 		return ("2-WAY");
257 	case NBR_STA_XSTRT:
258 		return ("EXSTA");
259 	case NBR_STA_SNAP:
260 		return ("SNAP");
261 	case NBR_STA_XCHNG:
262 		return ("EXCHG");
263 	case NBR_STA_LOAD:
264 		return ("LOAD");
265 	case NBR_STA_FULL:
266 		return ("FULL");
267 	default:
268 		return ("UNKNW");
269 	}
270 }
271 
272 const char *
273 if_state_name(int state)
274 {
275 	switch (state) {
276 	case IF_STA_DOWN:
277 		return ("DOWN");
278 	case IF_STA_LOOPBACK:
279 		return ("LOOP");
280 	case IF_STA_WAITING:
281 		return ("WAIT");
282 	case IF_STA_POINTTOPOINT:
283 		return ("P2P");
284 	case IF_STA_DROTHER:
285 		return ("OTHER");
286 	case IF_STA_BACKUP:
287 		return ("BCKUP");
288 	case IF_STA_DR:
289 		return ("DR");
290 	default:
291 		return ("UNKNW");
292 	}
293 }
294 
295 const char *
296 if_type_name(enum iface_type type)
297 {
298 	switch (type) {
299 	case IF_TYPE_POINTOPOINT:
300 		return ("POINTOPOINT");
301 	case IF_TYPE_BROADCAST:
302 		return ("BROADCAST");
303 	case IF_TYPE_NBMA:
304 		return ("NBMA");
305 	case IF_TYPE_POINTOMULTIPOINT:
306 		return ("POINTOMULTIPOINT");
307 	case IF_TYPE_VIRTUALLINK:
308 		return ("VIRTUALLINK");
309 	}
310 	/* NOTREACHED */
311 	return ("UNKNOWN");
312 }
313 
314 const char *
315 dst_type_name(enum dst_type type)
316 {
317 	switch (type) {
318 	case DT_NET:
319 		return ("Network");
320 	case DT_RTR:
321 		return ("Router");
322 	}
323 	/* NOTREACHED */
324 	return ("unknown");
325 }
326 
327 const char *
328 path_type_name(enum path_type type)
329 {
330 	switch (type) {
331 	case PT_INTRA_AREA:
332 		return ("Intra-Area");
333 	case PT_INTER_AREA:
334 		return ("Inter-Area");
335 	case PT_TYPE1_EXT:
336 		return ("Type 1 ext");
337 	case PT_TYPE2_EXT:
338 		return ("Type 2 ext");
339 	}
340 	/* NOTREACHED */
341 	return ("unknown");
342 }
343