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 73char *pname = NULL; 74u_int32_t loglevel = LLV_BASE; 75int f_foreground = 0; 76 77int print_location = 0; 78 79static struct log *logp = NULL; 80static char *logfile = NULL; 81 82static char *plog_common __P((int, const char *, const char *, struct sockaddr *)); 83 84static 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 97static char * 98plog_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 167void 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 177void 178plogv(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 204void 205plogdump(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 246void 247ploginit() 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 259void 260plogset(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 */ 274char* 275binsanitize(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