1 /* $OpenBSD: log.c,v 1.24 2016/05/23 18:55:21 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 <sys/types.h> 20 #include <sys/socket.h> 21 #include <netinet/in.h> 22 #include <arpa/inet.h> 23 24 #include <errno.h> 25 #include <stdarg.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <syslog.h> 30 #include <unistd.h> 31 32 #include "ldpd.h" 33 #include "ldpe.h" 34 #include "lde.h" 35 #include "log.h" 36 37 static const char * const procnames[] = { 38 "parent", 39 "ldpe", 40 "lde" 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 & LDPD_OPT_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[ldpd_process], 155 strerror(errno)); 156 else 157 if (errno) 158 logit(LOG_CRIT, "fatal in %s: %s: %s", 159 procnames[ldpd_process], emsg, strerror(errno)); 160 else 161 logit(LOG_CRIT, "fatal in %s: %s", 162 procnames[ldpd_process], emsg); 163 164 if (ldpd_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 /* names */ 178 const char * 179 socket_name(int type) 180 { 181 switch (type) { 182 case LDP_SOCKET_DISC: 183 return ("discovery"); 184 case LDP_SOCKET_EDISC: 185 return ("extended discovery"); 186 case LDP_SOCKET_SESSION: 187 return ("session"); 188 default: 189 return ("UNKNOWN"); 190 } 191 } 192 193 const char * 194 nbr_state_name(int state) 195 { 196 switch (state) { 197 case NBR_STA_PRESENT: 198 return ("PRESENT"); 199 case NBR_STA_INITIAL: 200 return ("INITIALIZED"); 201 case NBR_STA_OPENREC: 202 return ("OPENREC"); 203 case NBR_STA_OPENSENT: 204 return ("OPENSENT"); 205 case NBR_STA_OPER: 206 return ("OPERATIONAL"); 207 default: 208 return ("UNKNOWN"); 209 } 210 } 211 212 const char * 213 if_state_name(int state) 214 { 215 switch (state) { 216 case IF_STA_DOWN: 217 return ("DOWN"); 218 case IF_STA_ACTIVE: 219 return ("ACTIVE"); 220 default: 221 return ("UNKNOWN"); 222 } 223 } 224 225 const char * 226 if_type_name(enum iface_type type) 227 { 228 switch (type) { 229 case IF_TYPE_POINTOPOINT: 230 return ("POINTOPOINT"); 231 case IF_TYPE_BROADCAST: 232 return ("BROADCAST"); 233 } 234 /* NOTREACHED */ 235 return ("UNKNOWN"); 236 } 237 238 const char * 239 notification_name(uint32_t status) 240 { 241 static char buf[16]; 242 243 switch (status) { 244 case S_SUCCESS: 245 return ("Success"); 246 case S_BAD_LDP_ID: 247 return ("Bad LDP Identifier"); 248 case S_BAD_PROTO_VER: 249 return ("Bad Protocol Version"); 250 case S_BAD_PDU_LEN: 251 return ("Bad PDU Length"); 252 case S_UNKNOWN_MSG: 253 return ("Unknown Message Type"); 254 case S_BAD_MSG_LEN: 255 return ("Bad Message Length"); 256 case S_UNKNOWN_TLV: 257 return ("Unknown TLV"); 258 case S_BAD_TLV_LEN: 259 return ("Bad TLV Length"); 260 case S_BAD_TLV_VAL: 261 return ("Malformed TLV Value"); 262 case S_HOLDTIME_EXP: 263 return ("Hold Timer Expired"); 264 case S_SHUTDOWN: 265 return ("Shutdown"); 266 case S_LOOP_DETECTED: 267 return ("Loop Detected"); 268 case S_UNKNOWN_FEC: 269 return ("Unknown FEC"); 270 case S_NO_ROUTE: 271 return ("No Route"); 272 case S_NO_LABEL_RES: 273 return ("No Label Resources"); 274 case S_AVAILABLE: 275 return ("Label Resources Available"); 276 case S_NO_HELLO: 277 return ("Session Rejected, No Hello"); 278 case S_PARM_ADV_MODE: 279 return ("Rejected Advertisement Mode Parameter"); 280 case S_MAX_PDU_LEN: 281 return ("Rejected Max PDU Length Parameter"); 282 case S_PARM_L_RANGE: 283 return ("Rejected Label Range Parameter"); 284 case S_KEEPALIVE_TMR: 285 return ("KeepAlive Timer Expired"); 286 case S_LAB_REQ_ABRT: 287 return ("Label Request Aborted"); 288 case S_MISS_MSG: 289 return ("Missing Message Parameters"); 290 case S_UNSUP_ADDR: 291 return ("Unsupported Address Family"); 292 case S_KEEPALIVE_BAD: 293 return ("Bad KeepAlive Time"); 294 case S_INTERN_ERR: 295 return ("Internal Error"); 296 case S_ILLEGAL_CBIT: 297 return ("Illegal C-Bit"); 298 case S_WRONG_CBIT: 299 return ("Wrong C-Bit"); 300 case S_INCPT_BITRATE: 301 return ("Incompatible bit-rate"); 302 case S_CEP_MISCONF: 303 return ("CEP-TDM mis-configuration"); 304 case S_PW_STATUS: 305 return ("PW Status"); 306 case S_UNASSIGN_TAI: 307 return ("Unassigned/Unrecognized TAI"); 308 case S_MISCONF_ERR: 309 return ("Generic Misconfiguration Error"); 310 case S_WITHDRAW_MTHD: 311 return ("Label Withdraw PW Status Method"); 312 default: 313 snprintf(buf, sizeof(buf), "[%08x]", status); 314 return (buf); 315 } 316 } 317 318 const char * 319 pw_type_name(uint16_t pw_type) 320 { 321 static char buf[64]; 322 323 switch (pw_type) { 324 case PW_TYPE_ETHERNET_TAGGED: 325 return ("Eth Tagged"); 326 case PW_TYPE_ETHERNET: 327 return ("Ethernet"); 328 default: 329 snprintf(buf, sizeof(buf), "[%0x]", pw_type); 330 return (buf); 331 } 332 } 333 334 char * 335 log_hello_src(const struct hello_source *src) 336 { 337 static char buffer[64]; 338 339 switch (src->type) { 340 case HELLO_LINK: 341 snprintf(buffer, sizeof(buffer), "iface %s", 342 src->link.iface->name); 343 break; 344 case HELLO_TARGETED: 345 snprintf(buffer, sizeof(buffer), "source %s", 346 inet_ntoa(src->target->addr)); 347 break; 348 } 349 350 return (buffer); 351 } 352 353 const char * 354 log_map(const struct map *map) 355 { 356 static char buf[64]; 357 char pstr[64]; 358 359 switch (map->type) { 360 case MAP_TYPE_WILDCARD: 361 if (snprintf(buf, sizeof(buf), "wildcard") < 0) 362 return ("???"); 363 break; 364 case MAP_TYPE_PREFIX: 365 if (snprintf(buf, sizeof(buf), "%s/%u", 366 inet_ntop(AF_INET, &map->fec.ipv4.prefix, pstr, 367 sizeof(pstr)), map->fec.ipv4.prefixlen) == -1) 368 return ("???"); 369 break; 370 case MAP_TYPE_PWID: 371 if (snprintf(buf, sizeof(buf), "pwid %u (%s)", 372 map->fec.pwid.pwid, 373 pw_type_name(map->fec.pwid.type)) == -1) 374 return ("???"); 375 break; 376 default: 377 return ("???"); 378 } 379 380 return (buf); 381 } 382 383 const char * 384 log_fec(const struct fec *fec) 385 { 386 static char buf[64]; 387 char pstr[32]; 388 389 switch (fec->type) { 390 case FEC_TYPE_IPV4: 391 if (snprintf(buf, sizeof(buf), "%s/%u", 392 inet_ntop(AF_INET, &fec->u.ipv4.prefix, pstr, 393 sizeof(pstr)), fec->u.ipv4.prefixlen) == -1) 394 return ("???"); 395 break; 396 case FEC_TYPE_PWID: 397 if (snprintf(buf, sizeof(buf), 398 "pwid %u (%s) - %s", 399 fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type), 400 inet_ntoa(fec->u.pwid.lsr_id)) == -1) 401 return ("???"); 402 break; 403 default: 404 return ("???"); 405 } 406 407 return (buf); 408 } 409 410 static char *msgtypes[] = { 411 "", 412 "RTM_ADD: Add Route", 413 "RTM_DELETE: Delete Route", 414 "RTM_CHANGE: Change Metrics or flags", 415 "RTM_GET: Report Metrics", 416 "RTM_LOSING: Kernel Suspects Partitioning", 417 "RTM_REDIRECT: Told to use different route", 418 "RTM_MISS: Lookup failed on this address", 419 "RTM_LOCK: fix specified metrics", 420 "RTM_OLDADD: caused by SIOCADDRT", 421 "RTM_OLDDEL: caused by SIOCDELRT", 422 "RTM_RESOLVE: Route created by cloning", 423 "RTM_NEWADDR: address being added to iface", 424 "RTM_DELADDR: address being removed from iface", 425 "RTM_IFINFO: iface status change", 426 "RTM_IFANNOUNCE: iface arrival/departure", 427 "RTM_DESYNC: route socket overflow", 428 }; 429 430 void 431 log_rtmsg(unsigned char rtm_type) 432 { 433 if (!(verbose & LDPD_OPT_VERBOSE2)) 434 return; 435 436 if (rtm_type > 0 && 437 rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0])) 438 log_debug("kernel message: %s", msgtypes[rtm_type]); 439 else 440 log_debug("kernel message: rtm_type %d out of range", 441 rtm_type); 442 } 443