1 /* $NetBSD: plog.c,v 1.7 2011/01/28 12:51:40 tteras Exp $ */ 2 3 /* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 39 #include <arpa/inet.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <errno.h> 44 #ifdef HAVE_STDARG_H 45 #include <stdarg.h> 46 #else 47 #include <varargs.h> 48 #endif 49 #if TIME_WITH_SYS_TIME 50 # include <sys/time.h> 51 # include <time.h> 52 #else 53 # if HAVE_SYS_TIME_H 54 # include <sys/time.h> 55 # else 56 # include <time.h> 57 # endif 58 #endif 59 #include <ctype.h> 60 #include <err.h> 61 62 #include "var.h" 63 #include "misc.h" 64 #include "plog.h" 65 #include "logger.h" 66 #include "debug.h" 67 #include "gcmalloc.h" 68 69 #ifndef VA_COPY 70 # define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list)) 71 #endif 72 73 char *pname = NULL; 74 u_int32_t loglevel = LLV_BASE; 75 int f_foreground = 0; 76 77 int print_location = 0; 78 79 static struct log *logp = NULL; 80 static char *logfile = NULL; 81 82 static char *plog_common __P((int, const char *, const char *, struct sockaddr *)); 83 84 static struct plogtags { 85 char *name; 86 int priority; 87 } ptab[] = { 88 { "(not defined)", 0, }, 89 { "ERROR", LOG_INFO, }, 90 { "WARNING", LOG_INFO, }, 91 { "NOTIFY", LOG_INFO, }, 92 { "INFO", LOG_INFO, }, 93 { "DEBUG", LOG_DEBUG, }, 94 { "DEBUG2", LOG_DEBUG, }, 95 }; 96 97 static char * 98 plog_common(pri, fmt, func, sa) 99 int pri; 100 const char *fmt, *func; 101 struct sockaddr *sa; 102 { 103 static char buf[800]; /* XXX shoule be allocated every time ? */ 104 void *addr; 105 char *p; 106 int reslen, len; 107 108 p = buf; 109 reslen = sizeof(buf); 110 111 if (logfile || f_foreground) { 112 time_t t; 113 struct tm *tm; 114 115 t = time(0); 116 tm = localtime(&t); 117 len = strftime(p, reslen, "%Y-%m-%d %T: ", tm); 118 p += len; 119 reslen -= len; 120 } 121 122 if (sa && reslen > 3) { 123 addr = NULL; 124 switch (sa->sa_family) { 125 case AF_INET: 126 addr = &((struct sockaddr_in*)sa)->sin_addr; 127 break; 128 case AF_INET6: 129 addr = &((struct sockaddr_in6*)sa)->sin6_addr; 130 break; 131 } 132 if (inet_ntop(sa->sa_family, addr, p + 1, reslen - 3) != NULL) { 133 *p++ = '['; 134 len = strlen(p); 135 p += len; 136 *p++ = ']'; 137 *p++ = ' '; 138 reslen -= len + 3; 139 } 140 } 141 142 if (pri < ARRAYLEN(ptab)) { 143 len = snprintf(p, reslen, "%s: ", ptab[pri].name); 144 p += len; 145 reslen -= len; 146 } 147 148 if (print_location) 149 len = snprintf(p, reslen, "%s: %s", func, fmt); 150 else 151 len = snprintf(p, reslen, "%s", fmt); 152 p += len; 153 reslen -= len; 154 155 /* Force nul termination */ 156 if (reslen == 0) 157 p[-1] = 0; 158 159 #ifdef BROKEN_PRINTF 160 while ((p = strstr(buf,"%z")) != NULL) 161 p[1] = 'l'; 162 #endif 163 164 return buf; 165 } 166 167 void 168 _plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) 169 { 170 va_list ap; 171 172 va_start(ap, fmt); 173 plogv(pri, func, sa, fmt, ap); 174 va_end(ap); 175 } 176 177 void 178 plogv(int pri, const char *func, struct sockaddr *sa, 179 const char *fmt, va_list ap) 180 { 181 char *newfmt; 182 va_list ap_bak; 183 184 if (pri > loglevel) 185 return; 186 187 newfmt = plog_common(pri, fmt, func, sa); 188 189 VA_COPY(ap_bak, ap); 190 191 if (f_foreground) 192 vprintf(newfmt, ap); 193 194 if (logfile) 195 log_vaprint(logp, newfmt, ap_bak); 196 else { 197 if (pri < ARRAYLEN(ptab)) 198 vsyslog(ptab[pri].priority, newfmt, ap_bak); 199 else 200 vsyslog(LOG_ALERT, newfmt, ap_bak); 201 } 202 } 203 204 void 205 plogdump(pri, data, len) 206 int pri; 207 void *data; 208 size_t len; 209 { 210 caddr_t buf; 211 size_t buflen; 212 int i, j; 213 214 if (pri > loglevel) 215 return; 216 217 /* 218 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes 219 * + 2 newline + '\0' 220 */ 221 buflen = (len * 2) + (len / 4) + (len / 32) + 3; 222 buf = racoon_malloc(buflen); 223 224 i = 0; 225 j = 0; 226 while (j < len) { 227 if (j % 32 == 0) 228 buf[i++] = '\n'; 229 else 230 if (j % 4 == 0) 231 buf[i++] = ' '; 232 snprintf(&buf[i], buflen - i, "%02x", 233 ((unsigned char *)data)[j] & 0xff); 234 i += 2; 235 j++; 236 } 237 if (buflen - i >= 2) { 238 buf[i++] = '\n'; 239 buf[i] = '\0'; 240 } 241 plog(pri, LOCATION, NULL, "%s", buf); 242 243 racoon_free(buf); 244 } 245 246 void 247 ploginit() 248 { 249 if (logfile) { 250 logp = log_open(250, logfile); 251 if (logp == NULL) 252 errx(1, "ERROR: failed to open log file %s.", logfile); 253 return; 254 } 255 256 openlog(pname, LOG_NDELAY, LOG_DAEMON); 257 } 258 259 void 260 plogset(file) 261 char *file; 262 { 263 if (logfile != NULL) 264 racoon_free(logfile); 265 logfile = racoon_strdup(file); 266 STRDUP_FATAL(logfile); 267 } 268 269 /* 270 Returns a printable string from (possibly) binary data ; 271 concatenates all unprintable chars to one space. 272 XXX Maybe the printable chars range is too large... 273 */ 274 char* 275 binsanitize(binstr, n) 276 char *binstr; 277 size_t n; 278 { 279 int p,q; 280 char* d; 281 282 d = racoon_malloc(n + 1); 283 for (p = 0, q = 0; p < n; p++) { 284 if (isgraph((int)binstr[p])) { 285 d[q++] = binstr[p]; 286 } else { 287 if (q && d[q - 1] != ' ') 288 d[q++] = ' '; 289 } 290 } 291 d[q++] = '\0'; 292 293 return d; 294 } 295 296