1 /* $NetBSD: plog.c,v 1.9 2025/03/08 16:39:08 christos 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 uint32_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(int, const char *, const char *, struct sockaddr *); 83 84 static struct plogtags { 85 const 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(int pri, const char *fmt, const char *func, struct sockaddr *sa) 99 { 100 static char buf[800]; /* XXX shoule be allocated every time ? */ 101 void *addr; 102 char *p; 103 size_t reslen; 104 size_t len; 105 106 p = buf; 107 reslen = sizeof(buf); 108 109 if (logfile || f_foreground) { 110 time_t t; 111 struct tm *tm; 112 113 t = time(0); 114 tm = localtime(&t); 115 len = strftime(p, reslen, "%Y-%m-%d %T: ", tm); 116 p += len; 117 reslen -= len; 118 } 119 120 if (sa && reslen > 3) { 121 addr = NULL; 122 switch (sa->sa_family) { 123 case AF_INET: 124 addr = &((struct sockaddr_in*)sa)->sin_addr; 125 break; 126 case AF_INET6: 127 addr = &((struct sockaddr_in6*)sa)->sin6_addr; 128 break; 129 } 130 if (inet_ntop(sa->sa_family, addr, p + 1, reslen - 3) != NULL) { 131 *p++ = '['; 132 len = strlen(p); 133 p += len; 134 *p++ = ']'; 135 *p++ = ' '; 136 reslen -= len + 3; 137 } 138 } 139 140 if (pri < ARRAYLEN(ptab)) { 141 len = snprintf(p, reslen, "%s: ", ptab[pri].name); 142 p += len; 143 reslen -= len; 144 } 145 146 if (print_location) 147 len = snprintf(p, reslen, "%s: %s", func, fmt); 148 else 149 len = snprintf(p, reslen, "%s", fmt); 150 p += len; 151 reslen -= len; 152 153 /* Force nul termination */ 154 if (reslen == 0) 155 p[-1] = 0; 156 157 #ifdef BROKEN_PRINTF 158 while ((p = strstr(buf,"%z")) != NULL) 159 p[1] = 'l'; 160 #endif 161 162 return buf; 163 } 164 165 void 166 _plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) 167 { 168 va_list ap; 169 170 va_start(ap, fmt); 171 plogv(pri, func, sa, fmt, ap); 172 va_end(ap); 173 } 174 175 void 176 plogv(int pri, const char *func, struct sockaddr *sa, 177 const char *fmt, va_list ap) 178 { 179 char *newfmt; 180 va_list ap_bak; 181 182 if (pri > loglevel) 183 return; 184 185 newfmt = plog_common(pri, fmt, func, sa); 186 187 VA_COPY(ap_bak, ap); 188 189 if (f_foreground) 190 vprintf(newfmt, ap); 191 192 if (logfile) 193 log_vaprint(logp, newfmt, ap_bak); 194 else { 195 if (pri < ARRAYLEN(ptab)) 196 vsyslog(ptab[pri].priority, newfmt, ap_bak); 197 else 198 vsyslog(LOG_ALERT, newfmt, ap_bak); 199 } 200 } 201 202 void 203 plogdump(int pri, const void *data, size_t len) 204 { 205 caddr_t buf; 206 size_t buflen; 207 int i, j; 208 209 if (pri > loglevel) 210 return; 211 212 /* 213 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes 214 * + 2 newline + '\0' 215 */ 216 buflen = (len * 2) + (len / 4) + (len / 32) + 3; 217 buf = racoon_malloc(buflen); 218 219 i = 0; 220 j = 0; 221 while (j < len) { 222 if (j % 32 == 0) 223 buf[i++] = '\n'; 224 else 225 if (j % 4 == 0) 226 buf[i++] = ' '; 227 snprintf(&buf[i], buflen - i, "%02x", 228 ((const unsigned char *)data)[j] & 0xff); 229 i += 2; 230 j++; 231 } 232 if (buflen - i >= 2) { 233 buf[i++] = '\n'; 234 buf[i] = '\0'; 235 } 236 plog(pri, LOCATION, NULL, "%s", buf); 237 238 racoon_free(buf); 239 } 240 241 void 242 ploginit(void) 243 { 244 if (logfile) { 245 logp = log_open(250, logfile); 246 if (logp == NULL) 247 errx(1, "ERROR: failed to open log file %s.", logfile); 248 return; 249 } 250 251 openlog(pname, LOG_NDELAY, LOG_DAEMON); 252 } 253 254 void 255 plogset(char *file) 256 { 257 if (logfile != NULL) 258 racoon_free(logfile); 259 logfile = racoon_strdup(file); 260 STRDUP_FATAL(logfile); 261 } 262 263 /* 264 Returns a printable string from (possibly) binary data ; 265 concatenates all unprintable chars to one space. 266 XXX Maybe the printable chars range is too large... 267 */ 268 char* 269 binsanitize(char *binstr, size_t n) 270 { 271 int p,q; 272 char* d; 273 274 d = racoon_malloc(n + 1); 275 for (p = 0, q = 0; p < n; p++) { 276 if (isgraph((unsigned char)binstr[p])) { 277 d[q++] = binstr[p]; 278 } else { 279 if (q && d[q - 1] != ' ') 280 d[q++] = ' '; 281 } 282 } 283 d[q++] = '\0'; 284 285 return d; 286 } 287 288