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