]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/log.c
Merge remote-tracking branch 'origin/master' into EIGRP
[mirror_frr.git] / ldpd / log.c
1 /* $OpenBSD$ */
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 <zebra.h>
20
21 #include "ldpd.h"
22 #include "ldpe.h"
23 #include "lde.h"
24 #include "log.h"
25
26 #include <lib/log.h>
27 #include <lib/log_int.h>
28 #include "mpls.h"
29
30 static const char * const procnames[] = {
31 "parent",
32 "ldpe",
33 "lde"
34 };
35
36 void vlog(int, const char *, va_list);
37
38 void
39 logit(int pri, const char *fmt, ...)
40 {
41 va_list ap;
42
43 va_start(ap, fmt);
44 vlog(pri, fmt, ap);
45 va_end(ap);
46 }
47
48 void
49 vlog(int pri, const char *fmt, va_list ap)
50 {
51 char buf[1024];
52
53 switch (ldpd_process) {
54 case PROC_LDE_ENGINE:
55 vsnprintf(buf, sizeof(buf), fmt, ap);
56 lde_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
57 break;
58 case PROC_LDP_ENGINE:
59 vsnprintf(buf, sizeof(buf), fmt, ap);
60 ldpe_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
61 break;
62 case PROC_MAIN:
63 vzlog(pri, fmt, ap);
64 break;
65 }
66 }
67
68 void
69 log_warn(const char *emsg, ...)
70 {
71 char *nfmt;
72 va_list ap;
73
74 /* best effort to even work in out of memory situations */
75 if (emsg == NULL)
76 logit(LOG_CRIT, "%s", strerror(errno));
77 else {
78 va_start(ap, emsg);
79
80 if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
81 /* we tried it... */
82 vlog(LOG_CRIT, emsg, ap);
83 logit(LOG_CRIT, "%s", strerror(errno));
84 } else {
85 vlog(LOG_CRIT, nfmt, ap);
86 free(nfmt);
87 }
88 va_end(ap);
89 }
90 }
91
92 void
93 log_warnx(const char *emsg, ...)
94 {
95 va_list ap;
96
97 va_start(ap, emsg);
98 vlog(LOG_CRIT, emsg, ap);
99 va_end(ap);
100 }
101
102 void
103 log_info(const char *emsg, ...)
104 {
105 va_list ap;
106
107 va_start(ap, emsg);
108 vlog(LOG_INFO, emsg, ap);
109 va_end(ap);
110 }
111
112 void
113 log_notice(const char *emsg, ...)
114 {
115 va_list ap;
116
117 va_start(ap, emsg);
118 vlog(LOG_NOTICE, emsg, ap);
119 va_end(ap);
120 }
121
122 void
123 log_debug(const char *emsg, ...)
124 {
125 va_list ap;
126
127 va_start(ap, emsg);
128 vlog(LOG_DEBUG, emsg, ap);
129 va_end(ap);
130 }
131
132 void
133 fatal(const char *emsg)
134 {
135 if (emsg == NULL)
136 logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
137 strerror(errno));
138 else
139 if (errno)
140 logit(LOG_CRIT, "fatal in %s: %s: %s",
141 procnames[ldpd_process], emsg, strerror(errno));
142 else
143 logit(LOG_CRIT, "fatal in %s: %s",
144 procnames[ldpd_process], emsg);
145
146 exit(1);
147 }
148
149 void
150 fatalx(const char *emsg)
151 {
152 errno = 0;
153 fatal(emsg);
154 }
155
156 #define NUM_LOGS 4
157 const char *
158 log_sockaddr(void *vp)
159 {
160 static char buf[NUM_LOGS][NI_MAXHOST];
161 static int round = 0;
162 struct sockaddr *sa = vp;
163
164 round = (round + 1) % NUM_LOGS;
165
166 if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
167 NI_NUMERICHOST))
168 return ("(unknown)");
169 else
170 return (buf[round]);
171 }
172
173 const char *
174 log_in6addr(const struct in6_addr *addr)
175 {
176 struct sockaddr_in6 sa_in6;
177
178 memset(&sa_in6, 0, sizeof(sa_in6));
179 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
180 sa_in6.sin6_len = sizeof(sa_in6);
181 #endif
182 sa_in6.sin6_family = AF_INET6;
183 sa_in6.sin6_addr = *addr;
184
185 recoverscope(&sa_in6);
186
187 return (log_sockaddr(&sa_in6));
188 }
189
190 const char *
191 log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
192 {
193 struct sockaddr_in6 sa_in6;
194
195 memset(&sa_in6, 0, sizeof(sa_in6));
196 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
197 sa_in6.sin6_len = sizeof(sa_in6);
198 #endif
199 sa_in6.sin6_family = AF_INET6;
200 sa_in6.sin6_addr = *addr;
201
202 addscope(&sa_in6, ifindex);
203
204 return (log_sockaddr(&sa_in6));
205 }
206
207 const char *
208 log_addr(int af, const union ldpd_addr *addr)
209 {
210 static char buf[NUM_LOGS][INET6_ADDRSTRLEN];
211 static int round = 0;
212
213 switch (af) {
214 case AF_INET:
215 round = (round + 1) % NUM_LOGS;
216 if (inet_ntop(AF_INET, &addr->v4, buf[round],
217 sizeof(buf[round])) == NULL)
218 return ("???");
219 return (buf[round]);
220 case AF_INET6:
221 return (log_in6addr(&addr->v6));
222 default:
223 break;
224 }
225
226 return ("???");
227 }
228
229 #define TF_BUFS 4
230 #define TF_LEN 32
231
232 char *
233 log_label(uint32_t label)
234 {
235 char *buf;
236 static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
237 static int idx = 0;
238
239 buf = tfbuf[idx++];
240 if (idx == TF_BUFS)
241 idx = 0;
242
243 switch (label) {
244 case NO_LABEL:
245 snprintf(buf, TF_LEN, "-");
246 break;
247 case MPLS_LABEL_IMPLNULL:
248 snprintf(buf, TF_LEN, "imp-null");
249 break;
250 case MPLS_LABEL_IPV4NULL:
251 case MPLS_LABEL_IPV6NULL:
252 snprintf(buf, TF_LEN, "exp-null");
253 break;
254 default:
255 snprintf(buf, TF_LEN, "%u", label);
256 break;
257 }
258
259 return (buf);
260 }
261
262 const char *
263 log_time(time_t t)
264 {
265 char *buf;
266 static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
267 static int idx = 0;
268 unsigned int sec, min, hrs, day, week;
269
270 buf = tfbuf[idx++];
271 if (idx == TF_BUFS)
272 idx = 0;
273
274 week = t;
275
276 sec = week % 60;
277 week /= 60;
278 min = week % 60;
279 week /= 60;
280 hrs = week % 24;
281 week /= 24;
282 day = week % 7;
283 week /= 7;
284
285 if (week > 0)
286 snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
287 else if (day > 0)
288 snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
289 else
290 snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
291
292 return (buf);
293 }
294
295 char *
296 log_hello_src(const struct hello_source *src)
297 {
298 static char buf[64];
299
300 switch (src->type) {
301 case HELLO_LINK:
302 snprintf(buf, sizeof(buf), "iface %s",
303 src->link.ia->iface->name);
304 break;
305 case HELLO_TARGETED:
306 snprintf(buf, sizeof(buf), "source %s",
307 log_addr(src->target->af, &src->target->addr));
308 break;
309 }
310
311 return (buf);
312 }
313
314 const char *
315 log_map(const struct map *map)
316 {
317 static char buf[128];
318
319 switch (map->type) {
320 case MAP_TYPE_WILDCARD:
321 if (snprintf(buf, sizeof(buf), "wildcard") < 0)
322 return ("???");
323 break;
324 case MAP_TYPE_PREFIX:
325 if (snprintf(buf, sizeof(buf), "%s/%u",
326 log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
327 map->fec.prefix.prefixlen) == -1)
328 return ("???");
329 break;
330 case MAP_TYPE_PWID:
331 if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
332 map->fec.pwid.pwid, map->fec.pwid.group_id,
333 pw_type_name(map->fec.pwid.type)) == -1)
334 return ("???");
335 break;
336 case MAP_TYPE_TYPED_WCARD:
337 if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
338 return ("???");
339 switch (map->fec.twcard.type) {
340 case MAP_TYPE_PREFIX:
341 if (snprintf(buf + strlen(buf), sizeof(buf) -
342 strlen(buf), " (prefix, address-family %s)",
343 af_name(map->fec.twcard.u.prefix_af)) < 0)
344 return ("???");
345 break;
346 case MAP_TYPE_PWID:
347 if (snprintf(buf + strlen(buf), sizeof(buf) -
348 strlen(buf), " (pwid, type %s)",
349 pw_type_name(map->fec.twcard.u.pw_type)) < 0)
350 return ("???");
351 break;
352 default:
353 if (snprintf(buf + strlen(buf), sizeof(buf) -
354 strlen(buf), " (unknown type)") < 0)
355 return ("???");
356 break;
357 }
358 break;
359 default:
360 return ("???");
361 }
362
363 return (buf);
364 }
365
366 const char *
367 log_fec(const struct fec *fec)
368 {
369 static char buf[64];
370 union ldpd_addr addr;
371
372 switch (fec->type) {
373 case FEC_TYPE_IPV4:
374 addr.v4 = fec->u.ipv4.prefix;
375 if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
376 log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
377 return ("???");
378 break;
379 case FEC_TYPE_IPV6:
380 addr.v6 = fec->u.ipv6.prefix;
381 if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
382 log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
383 return ("???");
384 break;
385 case FEC_TYPE_PWID:
386 if (snprintf(buf, sizeof(buf),
387 "pwid %u (%s) - %s",
388 fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
389 inet_ntoa(fec->u.pwid.lsr_id)) == -1)
390 return ("???");
391 break;
392 default:
393 return ("???");
394 }
395
396 return (buf);
397 }
398
399 /* names */
400 const char *
401 af_name(int af)
402 {
403 switch (af) {
404 case AF_INET:
405 return ("ipv4");
406 case AF_INET6:
407 return ("ipv6");
408 #ifdef AF_MPLS
409 case AF_MPLS:
410 return ("mpls");
411 #endif
412 default:
413 return ("UNKNOWN");
414 }
415 }
416
417 const char *
418 socket_name(int type)
419 {
420 switch (type) {
421 case LDP_SOCKET_DISC:
422 return ("discovery");
423 case LDP_SOCKET_EDISC:
424 return ("extended discovery");
425 case LDP_SOCKET_SESSION:
426 return ("session");
427 default:
428 return ("UNKNOWN");
429 }
430 }
431
432 const char *
433 nbr_state_name(int state)
434 {
435 switch (state) {
436 case NBR_STA_PRESENT:
437 return ("PRESENT");
438 case NBR_STA_INITIAL:
439 return ("INITIALIZED");
440 case NBR_STA_OPENREC:
441 return ("OPENREC");
442 case NBR_STA_OPENSENT:
443 return ("OPENSENT");
444 case NBR_STA_OPER:
445 return ("OPERATIONAL");
446 default:
447 return ("UNKNOWN");
448 }
449 }
450
451 const char *
452 if_state_name(int state)
453 {
454 switch (state) {
455 case IF_STA_DOWN:
456 return ("DOWN");
457 case IF_STA_ACTIVE:
458 return ("ACTIVE");
459 default:
460 return ("UNKNOWN");
461 }
462 }
463
464 const char *
465 if_type_name(enum iface_type type)
466 {
467 switch (type) {
468 case IF_TYPE_POINTOPOINT:
469 return ("POINTOPOINT");
470 case IF_TYPE_BROADCAST:
471 return ("BROADCAST");
472 }
473 /* NOTREACHED */
474 return ("UNKNOWN");
475 }
476
477 const char *
478 msg_name(uint16_t msg)
479 {
480 static char buf[16];
481
482 switch (msg) {
483 case MSG_TYPE_NOTIFICATION:
484 return ("notification");
485 case MSG_TYPE_HELLO:
486 return ("hello");
487 case MSG_TYPE_INIT:
488 return ("initialization");
489 case MSG_TYPE_KEEPALIVE:
490 return ("keepalive");
491 case MSG_TYPE_CAPABILITY:
492 return ("capability");
493 case MSG_TYPE_ADDR:
494 return ("address");
495 case MSG_TYPE_ADDRWITHDRAW:
496 return ("address withdraw");
497 case MSG_TYPE_LABELMAPPING:
498 return ("label mapping");
499 case MSG_TYPE_LABELREQUEST:
500 return ("label request");
501 case MSG_TYPE_LABELWITHDRAW:
502 return ("label withdraw");
503 case MSG_TYPE_LABELRELEASE:
504 return ("label release");
505 case MSG_TYPE_LABELABORTREQ:
506 default:
507 snprintf(buf, sizeof(buf), "[%08x]", msg);
508 return (buf);
509 }
510 }
511
512 const char *
513 status_code_name(uint32_t status)
514 {
515 static char buf[16];
516
517 switch (status) {
518 case S_SUCCESS:
519 return ("Success");
520 case S_BAD_LDP_ID:
521 return ("Bad LDP Identifier");
522 case S_BAD_PROTO_VER:
523 return ("Bad Protocol Version");
524 case S_BAD_PDU_LEN:
525 return ("Bad PDU Length");
526 case S_UNKNOWN_MSG:
527 return ("Unknown Message Type");
528 case S_BAD_MSG_LEN:
529 return ("Bad Message Length");
530 case S_UNKNOWN_TLV:
531 return ("Unknown TLV");
532 case S_BAD_TLV_LEN:
533 return ("Bad TLV Length");
534 case S_BAD_TLV_VAL:
535 return ("Malformed TLV Value");
536 case S_HOLDTIME_EXP:
537 return ("Hold Timer Expired");
538 case S_SHUTDOWN:
539 return ("Shutdown");
540 case S_LOOP_DETECTED:
541 return ("Loop Detected");
542 case S_UNKNOWN_FEC:
543 return ("Unknown FEC");
544 case S_NO_ROUTE:
545 return ("No Route");
546 case S_NO_LABEL_RES:
547 return ("No Label Resources");
548 case S_AVAILABLE:
549 return ("Label Resources Available");
550 case S_NO_HELLO:
551 return ("Session Rejected, No Hello");
552 case S_PARM_ADV_MODE:
553 return ("Rejected Advertisement Mode Parameter");
554 case S_MAX_PDU_LEN:
555 return ("Rejected Max PDU Length Parameter");
556 case S_PARM_L_RANGE:
557 return ("Rejected Label Range Parameter");
558 case S_KEEPALIVE_TMR:
559 return ("KeepAlive Timer Expired");
560 case S_LAB_REQ_ABRT:
561 return ("Label Request Aborted");
562 case S_MISS_MSG:
563 return ("Missing Message Parameters");
564 case S_UNSUP_ADDR:
565 return ("Unsupported Address Family");
566 case S_KEEPALIVE_BAD:
567 return ("Bad KeepAlive Time");
568 case S_INTERN_ERR:
569 return ("Internal Error");
570 case S_ILLEGAL_CBIT:
571 return ("Illegal C-Bit");
572 case S_WRONG_CBIT:
573 return ("Wrong C-Bit");
574 case S_INCPT_BITRATE:
575 return ("Incompatible bit-rate");
576 case S_CEP_MISCONF:
577 return ("CEP-TDM mis-configuration");
578 case S_PW_STATUS:
579 return ("PW Status");
580 case S_UNASSIGN_TAI:
581 return ("Unassigned/Unrecognized TAI");
582 case S_MISCONF_ERR:
583 return ("Generic Misconfiguration Error");
584 case S_WITHDRAW_MTHD:
585 return ("Label Withdraw PW Status Method");
586 case S_UNSSUPORTDCAP:
587 return ("Unsupported Capability");
588 case S_ENDOFLIB:
589 return ("End-of-LIB");
590 case S_TRANS_MISMTCH:
591 return ("Transport Connection Mismatch");
592 case S_DS_NONCMPLNCE:
593 return ("Dual-Stack Noncompliance");
594 default:
595 snprintf(buf, sizeof(buf), "[%08x]", status);
596 return (buf);
597 }
598 }
599
600 const char *
601 pw_type_name(uint16_t pw_type)
602 {
603 static char buf[64];
604
605 switch (pw_type) {
606 case PW_TYPE_ETHERNET_TAGGED:
607 return ("Eth Tagged");
608 case PW_TYPE_ETHERNET:
609 return ("Ethernet");
610 case PW_TYPE_WILDCARD:
611 return ("Wildcard");
612 default:
613 snprintf(buf, sizeof(buf), "[%0x]", pw_type);
614 return (buf);
615 }
616 }