]>
Commit | Line | Data |
---|---|---|
8429abe0 RW |
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 | ||
eac6e3f0 | 19 | #include <zebra.h> |
8429abe0 RW |
20 | |
21 | #include "ldpd.h" | |
22 | #include "ldpe.h" | |
23 | #include "lde.h" | |
24 | #include "log.h" | |
25 | ||
eac6e3f0 RW |
26 | #include <lib/log.h> |
27 | #include "mpls.h" | |
28 | ||
8429abe0 RW |
29 | static const char * const procnames[] = { |
30 | "parent", | |
31 | "ldpe", | |
32 | "lde" | |
33 | }; | |
34 | ||
eac6e3f0 | 35 | void vlog(int, const char *, va_list); |
8429abe0 RW |
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 | ||
eac6e3f0 | 47 | void |
8429abe0 RW |
48 | vlog(int pri, const char *fmt, va_list ap) |
49 | { | |
eac6e3f0 | 50 | char buf[1024]; |
8429abe0 | 51 | |
eac6e3f0 RW |
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 | } | |
8429abe0 RW |
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 | ||
eac6e3f0 RW |
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 | ||
8429abe0 RW |
121 | void |
122 | log_debug(const char *emsg, ...) | |
123 | { | |
124 | va_list ap; | |
125 | ||
eac6e3f0 RW |
126 | va_start(ap, emsg); |
127 | vlog(LOG_DEBUG, emsg, ap); | |
128 | va_end(ap); | |
8429abe0 RW |
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 | ||
eac6e3f0 | 165 | if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0, |
8429abe0 RW |
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)); | |
eac6e3f0 | 178 | #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
8429abe0 | 179 | sa_in6.sin6_len = sizeof(sa_in6); |
eac6e3f0 | 180 | #endif |
8429abe0 RW |
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)); | |
eac6e3f0 | 195 | #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
8429abe0 | 196 | sa_in6.sin6_len = sizeof(sa_in6); |
eac6e3f0 | 197 | #endif |
8429abe0 RW |
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 | ||
eac6e3f0 RW |
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 | ||
8429abe0 RW |
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[64]; | |
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), "pwid %u (%s)", | |
331 | map->fec.pwid.pwid, | |
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"); | |
eac6e3f0 | 384 | #ifdef AF_MPLS |
8429abe0 RW |
385 | case AF_MPLS: |
386 | return ("mpls"); | |
eac6e3f0 | 387 | #endif |
8429abe0 RW |
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_ADDR: | |
468 | return ("address"); | |
469 | case MSG_TYPE_ADDRWITHDRAW: | |
470 | return ("address withdraw"); | |
471 | case MSG_TYPE_LABELMAPPING: | |
472 | return ("label mapping"); | |
473 | case MSG_TYPE_LABELREQUEST: | |
474 | return ("label request"); | |
475 | case MSG_TYPE_LABELWITHDRAW: | |
476 | return ("label withdraw"); | |
477 | case MSG_TYPE_LABELRELEASE: | |
478 | return ("label release"); | |
479 | case MSG_TYPE_LABELABORTREQ: | |
480 | default: | |
481 | snprintf(buf, sizeof(buf), "[%08x]", msg); | |
482 | return (buf); | |
483 | } | |
484 | } | |
485 | ||
486 | const char * | |
487 | status_code_name(uint32_t status) | |
488 | { | |
489 | static char buf[16]; | |
490 | ||
491 | switch (status) { | |
492 | case S_SUCCESS: | |
493 | return ("Success"); | |
494 | case S_BAD_LDP_ID: | |
495 | return ("Bad LDP Identifier"); | |
496 | case S_BAD_PROTO_VER: | |
497 | return ("Bad Protocol Version"); | |
498 | case S_BAD_PDU_LEN: | |
499 | return ("Bad PDU Length"); | |
500 | case S_UNKNOWN_MSG: | |
501 | return ("Unknown Message Type"); | |
502 | case S_BAD_MSG_LEN: | |
503 | return ("Bad Message Length"); | |
504 | case S_UNKNOWN_TLV: | |
505 | return ("Unknown TLV"); | |
506 | case S_BAD_TLV_LEN: | |
507 | return ("Bad TLV Length"); | |
508 | case S_BAD_TLV_VAL: | |
509 | return ("Malformed TLV Value"); | |
510 | case S_HOLDTIME_EXP: | |
511 | return ("Hold Timer Expired"); | |
512 | case S_SHUTDOWN: | |
513 | return ("Shutdown"); | |
514 | case S_LOOP_DETECTED: | |
515 | return ("Loop Detected"); | |
516 | case S_UNKNOWN_FEC: | |
517 | return ("Unknown FEC"); | |
518 | case S_NO_ROUTE: | |
519 | return ("No Route"); | |
520 | case S_NO_LABEL_RES: | |
521 | return ("No Label Resources"); | |
522 | case S_AVAILABLE: | |
523 | return ("Label Resources Available"); | |
524 | case S_NO_HELLO: | |
525 | return ("Session Rejected, No Hello"); | |
526 | case S_PARM_ADV_MODE: | |
527 | return ("Rejected Advertisement Mode Parameter"); | |
528 | case S_MAX_PDU_LEN: | |
529 | return ("Rejected Max PDU Length Parameter"); | |
530 | case S_PARM_L_RANGE: | |
531 | return ("Rejected Label Range Parameter"); | |
532 | case S_KEEPALIVE_TMR: | |
533 | return ("KeepAlive Timer Expired"); | |
534 | case S_LAB_REQ_ABRT: | |
535 | return ("Label Request Aborted"); | |
536 | case S_MISS_MSG: | |
537 | return ("Missing Message Parameters"); | |
538 | case S_UNSUP_ADDR: | |
539 | return ("Unsupported Address Family"); | |
540 | case S_KEEPALIVE_BAD: | |
541 | return ("Bad KeepAlive Time"); | |
542 | case S_INTERN_ERR: | |
543 | return ("Internal Error"); | |
544 | case S_ILLEGAL_CBIT: | |
545 | return ("Illegal C-Bit"); | |
546 | case S_WRONG_CBIT: | |
547 | return ("Wrong C-Bit"); | |
548 | case S_INCPT_BITRATE: | |
549 | return ("Incompatible bit-rate"); | |
550 | case S_CEP_MISCONF: | |
551 | return ("CEP-TDM mis-configuration"); | |
552 | case S_PW_STATUS: | |
553 | return ("PW Status"); | |
554 | case S_UNASSIGN_TAI: | |
555 | return ("Unassigned/Unrecognized TAI"); | |
556 | case S_MISCONF_ERR: | |
557 | return ("Generic Misconfiguration Error"); | |
558 | case S_WITHDRAW_MTHD: | |
559 | return ("Label Withdraw PW Status Method"); | |
560 | case S_TRANS_MISMTCH: | |
561 | return ("Transport Connection Mismatch"); | |
562 | case S_DS_NONCMPLNCE: | |
563 | return ("Dual-Stack Noncompliance"); | |
564 | default: | |
565 | snprintf(buf, sizeof(buf), "[%08x]", status); | |
566 | return (buf); | |
567 | } | |
568 | } | |
569 | ||
570 | const char * | |
571 | pw_type_name(uint16_t pw_type) | |
572 | { | |
573 | static char buf[64]; | |
574 | ||
575 | switch (pw_type) { | |
576 | case PW_TYPE_ETHERNET_TAGGED: | |
577 | return ("Eth Tagged"); | |
578 | case PW_TYPE_ETHERNET: | |
579 | return ("Ethernet"); | |
580 | default: | |
581 | snprintf(buf, sizeof(buf), "[%0x]", pw_type); | |
582 | return (buf); | |
583 | } | |
584 | } |