xref: /openbsd-src/usr.sbin/eigrpd/log.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: log.c,v 1.3 2016/04/15 13:10:56 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 <errno.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <syslog.h>
25 #include <unistd.h>
26 #include <arpa/inet.h>
27 #include <netdb.h>
28 
29 #include "eigrpd.h"
30 #include "rde.h"
31 #include "log.h"
32 
33 static const char * const procnames[] = {
34 	"parent",
35 	"eigrpe",
36 	"rde"
37 };
38 
39 int	debug;
40 int	verbose;
41 
42 void
43 log_init(int n_debug)
44 {
45 	extern char	*__progname;
46 
47 	debug = n_debug;
48 
49 	if (!debug)
50 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
51 
52 	tzset();
53 }
54 
55 void
56 log_verbose(int v)
57 {
58 	verbose = v;
59 }
60 
61 void
62 logit(int pri, const char *fmt, ...)
63 {
64 	va_list	ap;
65 
66 	va_start(ap, fmt);
67 	vlog(pri, fmt, ap);
68 	va_end(ap);
69 }
70 
71 void
72 vlog(int pri, const char *fmt, va_list ap)
73 {
74 	char	*nfmt;
75 
76 	if (debug) {
77 		/* best effort in out of mem situations */
78 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
79 			vfprintf(stderr, fmt, ap);
80 			fprintf(stderr, "\n");
81 		} else {
82 			vfprintf(stderr, nfmt, ap);
83 			free(nfmt);
84 		}
85 		fflush(stderr);
86 	} else
87 		vsyslog(pri, fmt, ap);
88 }
89 
90 void
91 log_warn(const char *emsg, ...)
92 {
93 	char	*nfmt;
94 	va_list	 ap;
95 
96 	/* best effort to even work in out of memory situations */
97 	if (emsg == NULL)
98 		logit(LOG_CRIT, "%s", strerror(errno));
99 	else {
100 		va_start(ap, emsg);
101 
102 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
103 			/* we tried it... */
104 			vlog(LOG_CRIT, emsg, ap);
105 			logit(LOG_CRIT, "%s", strerror(errno));
106 		} else {
107 			vlog(LOG_CRIT, nfmt, ap);
108 			free(nfmt);
109 		}
110 		va_end(ap);
111 	}
112 }
113 
114 void
115 log_warnx(const char *emsg, ...)
116 {
117 	va_list	 ap;
118 
119 	va_start(ap, emsg);
120 	vlog(LOG_CRIT, emsg, ap);
121 	va_end(ap);
122 }
123 
124 void
125 log_info(const char *emsg, ...)
126 {
127 	va_list	 ap;
128 
129 	va_start(ap, emsg);
130 	vlog(LOG_INFO, emsg, ap);
131 	va_end(ap);
132 }
133 
134 void
135 log_debug(const char *emsg, ...)
136 {
137 	va_list	 ap;
138 
139 	if (verbose) {
140 		va_start(ap, emsg);
141 		vlog(LOG_DEBUG, emsg, ap);
142 		va_end(ap);
143 	}
144 }
145 
146 void
147 fatal(const char *emsg)
148 {
149 	if (emsg == NULL)
150 		logit(LOG_CRIT, "fatal in %s: %s", procnames[eigrpd_process],
151 		    strerror(errno));
152 	else
153 		if (errno)
154 			logit(LOG_CRIT, "fatal in %s: %s: %s",
155 			    procnames[eigrpd_process], emsg, strerror(errno));
156 		else
157 			logit(LOG_CRIT, "fatal in %s: %s",
158 			    procnames[eigrpd_process], emsg);
159 
160 	if (eigrpd_process == PROC_MAIN)
161 		exit(1);
162 	else				/* parent copes via SIGCHLD */
163 		_exit(1);
164 }
165 
166 void
167 fatalx(const char *emsg)
168 {
169 	errno = 0;
170 	fatal(emsg);
171 }
172 
173 #define NUM_LOGS	4
174 const char *
175 log_sockaddr(void *vp)
176 {
177 	static char	 buf[NUM_LOGS][NI_MAXHOST];
178 	static int	 round = 0;
179 	struct sockaddr	*sa = vp;
180 
181 	round = (round + 1) % NUM_LOGS;
182 
183 	if (getnameinfo(sa, sa->sa_len, buf[round], NI_MAXHOST, NULL, 0,
184 	    NI_NUMERICHOST))
185 		return ("(unknown)");
186 	else
187 		return (buf[round]);
188 }
189 
190 const char *
191 log_in6addr(const struct in6_addr *addr)
192 {
193 	struct sockaddr_in6	sa_in6;
194 
195 	memset(&sa_in6, 0, sizeof(sa_in6));
196 	sa_in6.sin6_len = sizeof(sa_in6);
197 	sa_in6.sin6_family = AF_INET6;
198 	sa_in6.sin6_addr = *addr;
199 
200 	recoverscope(&sa_in6);
201 
202 	return (log_sockaddr(&sa_in6));
203 }
204 
205 const char *
206 log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
207 {
208 	struct sockaddr_in6	sa_in6;
209 
210 	memset(&sa_in6, 0, sizeof(sa_in6));
211 	sa_in6.sin6_len = sizeof(sa_in6);
212 	sa_in6.sin6_family = AF_INET6;
213 	sa_in6.sin6_addr = *addr;
214 
215 	addscope(&sa_in6, ifindex);
216 
217 	return (log_sockaddr(&sa_in6));
218 }
219 
220 const char *
221 log_addr(int af, union eigrpd_addr *addr)
222 {
223 	static char	 buf[NUM_LOGS][INET6_ADDRSTRLEN];
224 	static int	 round = 0;
225 
226 	switch (af) {
227 	case AF_INET:
228 		round = (round + 1) % NUM_LOGS;
229 		if (inet_ntop(AF_INET, &addr->v4, buf[round],
230 		    sizeof(buf[round])) == NULL)
231 			return ("???");
232 		return (buf[round]);
233 	case AF_INET6:
234 		return (log_in6addr(&addr->v6));
235 	default:
236 		break;
237 	}
238 
239 	return ("???");
240 }
241 
242 const char *
243 log_prefix(struct rt_node *rn)
244 {
245 	static char	buf[64];
246 
247 	if (snprintf(buf, sizeof(buf), "%s/%u", log_addr(rn->eigrp->af,
248 	    &rn->prefix), rn->prefixlen) == -1)
249 		return ("???");
250 
251 	return (buf);
252 }
253 
254 const char *
255 log_route_origin(int af, struct rde_nbr *nbr)
256 {
257 	if (nbr->flags & F_RDE_NBR_SELF) {
258 		if (nbr->flags & F_RDE_NBR_REDIST)
259 			return ("redistribute");
260 		if (nbr->flags & F_RDE_NBR_SUMMARY)
261 			return ("summary");
262 		else
263 			return ("connected");
264 	}
265 
266 	return (log_addr(af, &nbr->addr));
267 }
268 
269 const char *
270 opcode_name(uint8_t opcode)
271 {
272 	switch (opcode) {
273 	case EIGRP_OPC_UPDATE:
274 		return ("UPDATE");
275 	case EIGRP_OPC_REQUEST:
276 		return ("REQUEST");
277 	case EIGRP_OPC_QUERY:
278 		return ("QUERY");
279 	case EIGRP_OPC_REPLY:
280 		return ("REPLY");
281 	case EIGRP_OPC_HELLO:
282 		return ("HELLO");
283 	case EIGRP_OPC_PROBE:
284 		return ("PROBE");
285 	case EIGRP_OPC_SIAQUERY:
286 		return ("SIAQUERY");
287 	case EIGRP_OPC_SIAREPLY:
288 		return ("SIAREPLY");
289 	default:
290 		return ("UNKNOWN");
291 	}
292 }
293 
294 const char *
295 af_name(int af)
296 {
297 	switch (af) {
298 	case AF_INET:
299 		return ("ipv4");
300 	case AF_INET6:
301 		return ("ipv6");
302 	default:
303 		return ("UNKNOWN");
304 	}
305 }
306 
307 const char *
308 if_type_name(enum iface_type type)
309 {
310 	switch (type) {
311 	case IF_TYPE_POINTOPOINT:
312 		return ("POINTOPOINT");
313 	case IF_TYPE_BROADCAST:
314 		return ("BROADCAST");
315 	}
316 	/* NOTREACHED */
317 	return ("UNKNOWN");
318 }
319 
320 const char *
321 dual_state_name(int state)
322 {
323 	switch (state) {
324 	case DUAL_STA_PASSIVE:
325 		return ("PASSIVE");
326 	case DUAL_STA_ACTIVE0:
327 		return ("ACTIVE(Oij=0)");
328 	case DUAL_STA_ACTIVE1:
329 		return ("ACTIVE(Oij=1)");
330 	case DUAL_STA_ACTIVE2:
331 		return ("ACTIVE(Oij=2)");
332 	case DUAL_STA_ACTIVE3:
333 		return ("ACTIVE(Oij=3)");
334 	default:
335 		return ("UNKNOWN");
336 	}
337 }
338 
339 const char *
340 ext_proto_name(int proto)
341 {
342 	switch (proto) {
343 	case EIGRP_EXT_PROTO_IGRP:
344 		return ("IGRP");
345 	case EIGRP_EXT_PROTO_EIGRP:
346 		return ("EIGRP");
347 	case EIGRP_EXT_PROTO_STATIC:
348 		return ("Static");
349 	case EIGRP_EXT_PROTO_RIP:
350 		return ("RIP");
351 	case EIGRP_EXT_PROTO_HELLO:
352 		return ("HELLO");
353 	case EIGRP_EXT_PROTO_OSPF:
354 		return ("OSPF");
355 	case EIGRP_EXT_PROTO_ISIS:
356 		return ("ISIS");
357 	case EIGRP_EXT_PROTO_EGP:
358 		return ("EGP");
359 	case EIGRP_EXT_PROTO_BGP:
360 		return ("BGP");
361 	case EIGRP_EXT_PROTO_IDRP:
362 		return ("IDRP");
363 	case EIGRP_EXT_PROTO_CONN:
364 		return ("Connected");
365 	default:
366 		return ("UNKNOWN");
367 	}
368 }
369