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