1 /* $OpenBSD: log.c,v 1.15 2015/07/21 04:52:29 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 "lde.h" 34 #include "log.h" 35 36 static const char * const procnames[] = { 37 "parent", 38 "ldpe", 39 "lde" 40 }; 41 42 int debug; 43 int verbose; 44 45 void 46 log_init(int n_debug) 47 { 48 extern char *__progname; 49 50 debug = n_debug; 51 52 if (!debug) 53 openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); 54 55 tzset(); 56 } 57 58 void 59 log_verbose(int v) 60 { 61 verbose = v; 62 } 63 64 void 65 logit(int pri, const char *fmt, ...) 66 { 67 va_list ap; 68 69 va_start(ap, fmt); 70 vlog(pri, fmt, ap); 71 va_end(ap); 72 } 73 74 void 75 vlog(int pri, const char *fmt, va_list ap) 76 { 77 char *nfmt; 78 79 if (debug) { 80 /* best effort in out of mem situations */ 81 if (asprintf(&nfmt, "%s\n", fmt) == -1) { 82 vfprintf(stderr, fmt, ap); 83 fprintf(stderr, "\n"); 84 } else { 85 vfprintf(stderr, nfmt, ap); 86 free(nfmt); 87 } 88 fflush(stderr); 89 } else 90 vsyslog(pri, fmt, ap); 91 } 92 93 void 94 log_warn(const char *emsg, ...) 95 { 96 char *nfmt; 97 va_list ap; 98 99 /* best effort to even work in out of memory situations */ 100 if (emsg == NULL) 101 logit(LOG_CRIT, "%s", strerror(errno)); 102 else { 103 va_start(ap, emsg); 104 105 if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) { 106 /* we tried it... */ 107 vlog(LOG_CRIT, emsg, ap); 108 logit(LOG_CRIT, "%s", strerror(errno)); 109 } else { 110 vlog(LOG_CRIT, nfmt, ap); 111 free(nfmt); 112 } 113 va_end(ap); 114 } 115 } 116 117 void 118 log_warnx(const char *emsg, ...) 119 { 120 va_list ap; 121 122 va_start(ap, emsg); 123 vlog(LOG_CRIT, emsg, ap); 124 va_end(ap); 125 } 126 127 void 128 log_info(const char *emsg, ...) 129 { 130 va_list ap; 131 132 va_start(ap, emsg); 133 vlog(LOG_INFO, emsg, ap); 134 va_end(ap); 135 } 136 137 void 138 log_debug(const char *emsg, ...) 139 { 140 va_list ap; 141 142 if (verbose & LDPD_OPT_VERBOSE) { 143 va_start(ap, emsg); 144 vlog(LOG_DEBUG, emsg, ap); 145 va_end(ap); 146 } 147 } 148 149 void 150 fatal(const char *emsg) 151 { 152 if (emsg == NULL) 153 logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process], 154 strerror(errno)); 155 else 156 if (errno) 157 logit(LOG_CRIT, "fatal in %s: %s: %s", 158 procnames[ldpd_process], emsg, strerror(errno)); 159 else 160 logit(LOG_CRIT, "fatal in %s: %s", 161 procnames[ldpd_process], emsg); 162 163 if (ldpd_process == PROC_MAIN) 164 exit(1); 165 else /* parent copes via SIGCHLD */ 166 _exit(1); 167 } 168 169 void 170 fatalx(const char *emsg) 171 { 172 errno = 0; 173 fatal(emsg); 174 } 175 176 /* names */ 177 const char * 178 nbr_state_name(int state) 179 { 180 switch (state) { 181 case NBR_STA_PRESENT: 182 return ("PRESENT"); 183 case NBR_STA_INITIAL: 184 return ("INITIALIZED"); 185 case NBR_STA_OPENREC: 186 return ("OPENREC"); 187 case NBR_STA_OPENSENT: 188 return ("OPENSENT"); 189 case NBR_STA_OPER: 190 return ("OPERATIONAL"); 191 default: 192 return ("UNKNW"); 193 } 194 } 195 196 const char * 197 if_state_name(int state) 198 { 199 switch (state) { 200 case IF_STA_DOWN: 201 return ("DOWN"); 202 case IF_STA_ACTIVE: 203 return ("ACTIVE"); 204 default: 205 return ("UNKNW"); 206 } 207 } 208 209 const char * 210 if_type_name(enum iface_type type) 211 { 212 switch (type) { 213 case IF_TYPE_POINTOPOINT: 214 return ("POINTOPOINT"); 215 case IF_TYPE_BROADCAST: 216 return ("BROADCAST"); 217 } 218 /* NOTREACHED */ 219 return ("UNKNOWN"); 220 } 221 222 const char * 223 notification_name(u_int32_t status) 224 { 225 static char buf[16]; 226 227 switch (status) { 228 case S_SUCCESS: 229 return ("Success"); 230 case S_BAD_LDP_ID: 231 return ("Bad LDP Identifier"); 232 case S_BAD_PROTO_VER: 233 return ("Bad Protocol Version"); 234 case S_BAD_PDU_LEN: 235 return ("Bad PDU Length"); 236 case S_UNKNOWN_MSG: 237 return ("Unknown Message Type"); 238 case S_BAD_MSG_LEN: 239 return ("Bad Message Length"); 240 case S_UNKNOWN_TLV: 241 return ("Unknown TLV"); 242 case S_BAD_TLV_LEN: 243 return ("Bad TLV Length"); 244 case S_BAD_TLV_VAL: 245 return ("Malformed TLV Value"); 246 case S_HOLDTIME_EXP: 247 return ("Hold Timer Expired"); 248 case S_SHUTDOWN: 249 return ("Shutdown"); 250 case S_LOOP_DETECTED: 251 return ("Loop Detected"); 252 case S_UNKNOWN_FEC: 253 return ("Unknown FEC"); 254 case S_NO_ROUTE: 255 return ("No Route"); 256 case S_NO_LABEL_RES: 257 return ("No Label Resources"); 258 case S_AVAILABLE: 259 return ("Label Resources Available"); 260 case S_NO_HELLO: 261 return ("Session Rejected, No Hello"); 262 case S_PARM_ADV_MODE: 263 return ("Rejected Advertisement Mode Parameter"); 264 case S_MAX_PDU_LEN: 265 return ("Rejected Max PDU Length Parameter"); 266 case S_PARM_L_RANGE: 267 return ("Rejected Label Range Parameter"); 268 case S_KEEPALIVE_TMR: 269 return ("KeepAlive Timer Expired"); 270 case S_LAB_REQ_ABRT: 271 return ("Label Request Aborted"); 272 case S_MISS_MSG: 273 return ("Missing Message Parameters"); 274 case S_UNSUP_ADDR: 275 return ("Unsupported Address Family"); 276 case S_KEEPALIVE_BAD: 277 return ("Bad KeepAlive Time"); 278 case S_INTERN_ERR: 279 return ("Internal Error"); 280 case S_ILLEGAL_CBIT: 281 return ("Illegal C-Bit"); 282 case S_WRONG_CBIT: 283 return ("Wrong C-Bit"); 284 case S_INCPT_BITRATE: 285 return ("Incompatible bit-rate"); 286 case S_CEP_MISCONF: 287 return ("CEP-TDM mis-configuration"); 288 case S_PW_STATUS: 289 return ("PW Status"); 290 case S_UNASSIGN_TAI: 291 return ("Unassigned/Unrecognized TAI"); 292 case S_MISCONF_ERR: 293 return ("Generic Misconfiguration Error"); 294 case S_WITHDRAW_MTHD: 295 return ("Label Withdraw PW Status Method"); 296 default: 297 snprintf(buf, sizeof(buf), "[%08x]", status); 298 return (buf); 299 } 300 } 301 302 const char * 303 pw_type_name(u_int16_t pw_type) 304 { 305 static char buf[64]; 306 307 switch (pw_type) { 308 case PW_TYPE_ETHERNET_TAGGED: 309 return ("Eth Tagged"); 310 case PW_TYPE_ETHERNET: 311 return ("Ethernet"); 312 default: 313 snprintf(buf, sizeof(buf), "[%0x]", pw_type); 314 return (buf); 315 } 316 } 317 318 const char * 319 log_map(struct map *map) 320 { 321 static char buf[64]; 322 char pstr[64]; 323 324 switch (map->type) { 325 case FEC_WILDCARD: 326 if (snprintf(buf, sizeof(buf), "wildcard")) 327 return ("???"); 328 break; 329 case FEC_PREFIX: 330 if (snprintf(buf, sizeof(buf), "%s/%u", 331 inet_ntop(AF_INET, &map->fec.ipv4.prefix, pstr, 332 sizeof(pstr)), map->fec.ipv4.prefixlen) == -1) 333 return ("???"); 334 break; 335 case FEC_PWID: 336 if (snprintf(buf, sizeof(buf), "pwid %u (%s)", 337 map->fec.pwid.pwid, 338 pw_type_name(map->fec.pwid.type)) == -1) 339 return ("???"); 340 break; 341 default: 342 return ("???"); 343 } 344 345 return (buf); 346 } 347 348 const char * 349 log_fec(struct fec *fec) 350 { 351 static char buf[64]; 352 char pstr[32]; 353 354 switch (fec->type) { 355 case FEC_TYPE_IPV4: 356 if (snprintf(buf, sizeof(buf), "%s/%u", 357 inet_ntop(AF_INET, &fec->u.ipv4.prefix, pstr, 358 sizeof(pstr)), fec->u.ipv4.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.nexthop)) == -1) 366 return ("???"); 367 break; 368 default: 369 return ("???"); 370 } 371 372 return (buf); 373 } 374 375 static char *msgtypes[] = { 376 "", 377 "RTM_ADD: Add Route", 378 "RTM_DELETE: Delete Route", 379 "RTM_CHANGE: Change Metrics or flags", 380 "RTM_GET: Report Metrics", 381 "RTM_LOSING: Kernel Suspects Partitioning", 382 "RTM_REDIRECT: Told to use different route", 383 "RTM_MISS: Lookup failed on this address", 384 "RTM_LOCK: fix specified metrics", 385 "RTM_OLDADD: caused by SIOCADDRT", 386 "RTM_OLDDEL: caused by SIOCDELRT", 387 "RTM_RESOLVE: Route created by cloning", 388 "RTM_NEWADDR: address being added to iface", 389 "RTM_DELADDR: address being removed from iface", 390 "RTM_IFINFO: iface status change", 391 "RTM_IFANNOUNCE: iface arrival/departure", 392 "RTM_DESYNC: route socket overflow", 393 }; 394 395 void 396 log_rtmsg(u_char rtm_type) 397 { 398 if (!(verbose & LDPD_OPT_VERBOSE2)) 399 return; 400 401 if (rtm_type > 0 && 402 rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0])) 403 log_debug("rtmsg_process: %s", msgtypes[rtm_type]); 404 else 405 log_debug("rtmsg_process: rtm_type %d out of range", 406 rtm_type); 407 } 408