11ae349f5Scvs2svn /*- 21ae349f5Scvs2svn * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 31ae349f5Scvs2svn * All rights reserved. 41ae349f5Scvs2svn * 51ae349f5Scvs2svn * Redistribution and use in source and binary forms, with or without 61ae349f5Scvs2svn * modification, are permitted provided that the following conditions 71ae349f5Scvs2svn * are met: 81ae349f5Scvs2svn * 1. Redistributions of source code must retain the above copyright 91ae349f5Scvs2svn * notice, this list of conditions and the following disclaimer. 101ae349f5Scvs2svn * 2. Redistributions in binary form must reproduce the above copyright 111ae349f5Scvs2svn * notice, this list of conditions and the following disclaimer in the 121ae349f5Scvs2svn * documentation and/or other materials provided with the distribution. 131ae349f5Scvs2svn * 141ae349f5Scvs2svn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151ae349f5Scvs2svn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161ae349f5Scvs2svn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171ae349f5Scvs2svn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181ae349f5Scvs2svn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191ae349f5Scvs2svn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201ae349f5Scvs2svn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211ae349f5Scvs2svn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221ae349f5Scvs2svn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231ae349f5Scvs2svn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241ae349f5Scvs2svn * SUCH DAMAGE. 251ae349f5Scvs2svn * 26b6217683SBrian Somers * $Id: log.c,v 1.25.2.1 1998/02/10 03:23:25 brian Exp $ 271ae349f5Scvs2svn */ 281ae349f5Scvs2svn 291ae349f5Scvs2svn #include <sys/param.h> 301ae349f5Scvs2svn #include <netinet/in.h> 311ae349f5Scvs2svn 321ae349f5Scvs2svn #include <stdarg.h> 331ae349f5Scvs2svn #include <stdio.h> 34b6217683SBrian Somers #include <string.h> 351ae349f5Scvs2svn #include <syslog.h> 3685b542cfSBrian Somers #include <termios.h> 371ae349f5Scvs2svn 381ae349f5Scvs2svn #include "command.h" 391ae349f5Scvs2svn #include "mbuf.h" 401ae349f5Scvs2svn #include "log.h" 411ae349f5Scvs2svn #include "loadalias.h" 421ae349f5Scvs2svn #include "defs.h" 431ae349f5Scvs2svn #include "vars.h" 4485b542cfSBrian Somers #include "descriptor.h" 4585b542cfSBrian Somers #include "prompt.h" 461ae349f5Scvs2svn 471ae349f5Scvs2svn static const char *LogNames[] = { 481ae349f5Scvs2svn "Async", 491ae349f5Scvs2svn "Carrier", 501ae349f5Scvs2svn "CCP", 511ae349f5Scvs2svn "Chat", 521ae349f5Scvs2svn "Command", 531ae349f5Scvs2svn "Connect", 541ae349f5Scvs2svn "Debug", 551ae349f5Scvs2svn "HDLC", 561ae349f5Scvs2svn "ID0", 571ae349f5Scvs2svn "IPCP", 581ae349f5Scvs2svn "LCP", 591ae349f5Scvs2svn "Link", 601ae349f5Scvs2svn "LQM", 611ae349f5Scvs2svn "Phase", 621ae349f5Scvs2svn "TCP/IP", 631ae349f5Scvs2svn "Tun", 641ae349f5Scvs2svn "Warning", 651ae349f5Scvs2svn "Error", 661ae349f5Scvs2svn "Alert" 671ae349f5Scvs2svn }; 681ae349f5Scvs2svn 691ae349f5Scvs2svn #define MSK(n) (1<<((n)-1)) 701ae349f5Scvs2svn 711ae349f5Scvs2svn static u_long LogMask = MSK(LogLINK) | MSK(LogCARRIER) | MSK(LogPHASE); 721ae349f5Scvs2svn static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 731ae349f5Scvs2svn static int LogTunno = -1; 74b6217683SBrian Somers static struct prompt *logprompt; /* Where to log local stuff */ 75b6217683SBrian Somers 76b6217683SBrian Somers void 77b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 78b6217683SBrian Somers { 79b6217683SBrian Somers if (prompt) { 80b6217683SBrian Somers prompt->lognext = logprompt; 81b6217683SBrian Somers logprompt = prompt; 82b6217683SBrian Somers LogMaskLocal |= prompt->logmask; 83b6217683SBrian Somers } 84b6217683SBrian Somers } 85b6217683SBrian Somers 86b6217683SBrian Somers void 87b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 88b6217683SBrian Somers { 89b6217683SBrian Somers if (prompt) { 90b6217683SBrian Somers struct prompt **p; 91b6217683SBrian Somers 92b6217683SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 93b6217683SBrian Somers for (p = &logprompt; *p; p = &(*p)->lognext) { 94b6217683SBrian Somers if (*p == prompt) { 95b6217683SBrian Somers *p = (*p)->lognext; 96b6217683SBrian Somers prompt->lognext = NULL; 97b6217683SBrian Somers if (!*p) 98b6217683SBrian Somers break; 99b6217683SBrian Somers } 100b6217683SBrian Somers LogMaskLocal |= (*p)->logmask; 101b6217683SBrian Somers } 102b6217683SBrian Somers } 103b6217683SBrian Somers } 1041ae349f5Scvs2svn 1051ae349f5Scvs2svn static int 1061ae349f5Scvs2svn syslogLevel(int lev) 1071ae349f5Scvs2svn { 1081ae349f5Scvs2svn switch (lev) { 1091ae349f5Scvs2svn case LogDEBUG:return LOG_DEBUG; 1101ae349f5Scvs2svn case LogWARN: 1111ae349f5Scvs2svn return LOG_WARNING; 1121ae349f5Scvs2svn case LogERROR: 1131ae349f5Scvs2svn return LOG_ERR; 1141ae349f5Scvs2svn case LogALERT: 1151ae349f5Scvs2svn return LOG_ALERT; 1161ae349f5Scvs2svn } 1171ae349f5Scvs2svn return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 1181ae349f5Scvs2svn } 1191ae349f5Scvs2svn 1201ae349f5Scvs2svn const char * 1211ae349f5Scvs2svn LogName(int id) 1221ae349f5Scvs2svn { 1231ae349f5Scvs2svn return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 1241ae349f5Scvs2svn } 1251ae349f5Scvs2svn 1261ae349f5Scvs2svn void 1271ae349f5Scvs2svn LogKeep(int id) 1281ae349f5Scvs2svn { 1291ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1301ae349f5Scvs2svn LogMask |= MSK(id); 1311ae349f5Scvs2svn } 1321ae349f5Scvs2svn 1331ae349f5Scvs2svn void 134b6217683SBrian Somers LogKeepLocal(int id, u_long *mask) 1351ae349f5Scvs2svn { 136b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 1371ae349f5Scvs2svn LogMaskLocal |= MSK(id); 138b6217683SBrian Somers *mask |= MSK(id); 139b6217683SBrian Somers } 1401ae349f5Scvs2svn } 1411ae349f5Scvs2svn 1421ae349f5Scvs2svn void 1431ae349f5Scvs2svn LogDiscard(int id) 1441ae349f5Scvs2svn { 1451ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1461ae349f5Scvs2svn LogMask &= ~MSK(id); 1471ae349f5Scvs2svn } 1481ae349f5Scvs2svn 1491ae349f5Scvs2svn void 150b6217683SBrian Somers LogDiscardLocal(int id, u_long *mask) 1511ae349f5Scvs2svn { 152b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 1531ae349f5Scvs2svn LogMaskLocal &= ~MSK(id); 154b6217683SBrian Somers *mask &= ~MSK(id); 155b6217683SBrian Somers } 1561ae349f5Scvs2svn } 1571ae349f5Scvs2svn 1581ae349f5Scvs2svn void 1591ae349f5Scvs2svn LogDiscardAll() 1601ae349f5Scvs2svn { 1611ae349f5Scvs2svn LogMask = 0; 1621ae349f5Scvs2svn } 1631ae349f5Scvs2svn 1641ae349f5Scvs2svn void 165b6217683SBrian Somers LogDiscardAllLocal(u_long *mask) 1661ae349f5Scvs2svn { 167b6217683SBrian Somers LogMaskLocal = *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 1681ae349f5Scvs2svn } 1691ae349f5Scvs2svn 1701ae349f5Scvs2svn int 1711ae349f5Scvs2svn LogIsKept(int id) 1721ae349f5Scvs2svn { 1731ae349f5Scvs2svn if (id < LogMIN || id > LogMAX) 1741ae349f5Scvs2svn return 0; 1751ae349f5Scvs2svn if (id > LogMAXCONF) 1761ae349f5Scvs2svn return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 1771ae349f5Scvs2svn 1781ae349f5Scvs2svn return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 1791ae349f5Scvs2svn ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 1801ae349f5Scvs2svn } 1811ae349f5Scvs2svn 182b6217683SBrian Somers int 183b6217683SBrian Somers LogIsKeptLocal(int id, u_long mask) 184b6217683SBrian Somers { 185b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 186b6217683SBrian Somers return 0; 187b6217683SBrian Somers if (id > LogMAXCONF) 188b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 189b6217683SBrian Somers 190b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 191b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 192b6217683SBrian Somers } 193b6217683SBrian Somers 1941ae349f5Scvs2svn void 1951ae349f5Scvs2svn LogOpen(const char *Name) 1961ae349f5Scvs2svn { 1971ae349f5Scvs2svn openlog(Name, LOG_PID, LOG_DAEMON); 1981ae349f5Scvs2svn } 1991ae349f5Scvs2svn 2001ae349f5Scvs2svn void 2011ae349f5Scvs2svn LogSetTun(int tunno) 2021ae349f5Scvs2svn { 2031ae349f5Scvs2svn LogTunno = tunno; 2041ae349f5Scvs2svn } 2051ae349f5Scvs2svn 2061ae349f5Scvs2svn void 2071ae349f5Scvs2svn LogClose() 2081ae349f5Scvs2svn { 2091ae349f5Scvs2svn closelog(); 2101ae349f5Scvs2svn LogTunno = -1; 2111ae349f5Scvs2svn } 2121ae349f5Scvs2svn 2131ae349f5Scvs2svn void 2141ae349f5Scvs2svn LogPrintf(int lev, const char *fmt,...) 2151ae349f5Scvs2svn { 2161ae349f5Scvs2svn va_list ap; 217b6217683SBrian Somers struct prompt *prompt; 2181ae349f5Scvs2svn 2191ae349f5Scvs2svn va_start(ap, fmt); 2201ae349f5Scvs2svn if (LogIsKept(lev)) { 2211ae349f5Scvs2svn static char nfmt[200]; 2221ae349f5Scvs2svn 223b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && logprompt) { 2241ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 2251ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2261ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2271ae349f5Scvs2svn else 2281ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 229b6217683SBrian Somers 230b6217683SBrian Somers for (prompt = logprompt; prompt; prompt = prompt->lognext) 231b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 232b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 2331ae349f5Scvs2svn } 2341ae349f5Scvs2svn 235b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) { 2361ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 2371ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2381ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2391ae349f5Scvs2svn else 2401ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 2411ae349f5Scvs2svn vsyslog(syslogLevel(lev), nfmt, ap); 2421ae349f5Scvs2svn } 2431ae349f5Scvs2svn } 2441ae349f5Scvs2svn va_end(ap); 2451ae349f5Scvs2svn } 2461ae349f5Scvs2svn 2471ae349f5Scvs2svn void 2481ae349f5Scvs2svn LogDumpBp(int lev, const char *hdr, const struct mbuf * bp) 2491ae349f5Scvs2svn { 2501ae349f5Scvs2svn if (LogIsKept(lev)) { 2511ae349f5Scvs2svn char buf[50]; 2521ae349f5Scvs2svn char *b; 2531ae349f5Scvs2svn u_char *ptr; 2541ae349f5Scvs2svn int f; 2551ae349f5Scvs2svn 2561ae349f5Scvs2svn if (hdr && *hdr) 2571ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2581ae349f5Scvs2svn 2591ae349f5Scvs2svn b = buf; 2601ae349f5Scvs2svn do { 2611ae349f5Scvs2svn f = bp->cnt; 2621ae349f5Scvs2svn ptr = MBUF_CTOP(bp); 2631ae349f5Scvs2svn while (f--) { 2641ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2651ae349f5Scvs2svn b += 3; 2661ae349f5Scvs2svn if (b == buf + sizeof buf - 2) { 2671ae349f5Scvs2svn strcpy(b, "\n"); 2681ae349f5Scvs2svn LogPrintf(lev, buf); 2691ae349f5Scvs2svn b = buf; 2701ae349f5Scvs2svn } 2711ae349f5Scvs2svn } 2721ae349f5Scvs2svn } while ((bp = bp->next) != NULL); 2731ae349f5Scvs2svn 2741ae349f5Scvs2svn if (b > buf) { 2751ae349f5Scvs2svn strcpy(b, "\n"); 2761ae349f5Scvs2svn LogPrintf(lev, buf); 2771ae349f5Scvs2svn } 2781ae349f5Scvs2svn } 2791ae349f5Scvs2svn } 2801ae349f5Scvs2svn 2811ae349f5Scvs2svn void 2821ae349f5Scvs2svn LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 2831ae349f5Scvs2svn { 2841ae349f5Scvs2svn if (LogIsKept(lev)) { 2851ae349f5Scvs2svn char buf[50]; 2861ae349f5Scvs2svn char *b; 2871ae349f5Scvs2svn 2881ae349f5Scvs2svn if (hdr && *hdr) 2891ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2901ae349f5Scvs2svn while (n > 0) { 2911ae349f5Scvs2svn b = buf; 2921ae349f5Scvs2svn for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 2931ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2941ae349f5Scvs2svn strcpy(b, "\n"); 2951ae349f5Scvs2svn LogPrintf(lev, buf); 2961ae349f5Scvs2svn } 2971ae349f5Scvs2svn } 2981ae349f5Scvs2svn } 299b6217683SBrian Somers 300b6217683SBrian Somers int 301b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 302b6217683SBrian Somers { 303b6217683SBrian Somers int i; 304b6217683SBrian Somers 305b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 306b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 307b6217683SBrian Somers if (LogIsKept(i) & LOG_KEPT_SYSLOG) 308b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 309b6217683SBrian Somers 310b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 311b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 312b6217683SBrian Somers if (LogIsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 313b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 314b6217683SBrian Somers 315b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 316b6217683SBrian Somers 317b6217683SBrian Somers return 0; 318b6217683SBrian Somers } 319b6217683SBrian Somers 320b6217683SBrian Somers int 321b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 322b6217683SBrian Somers { 323b6217683SBrian Somers int i, res, argc, local; 324b6217683SBrian Somers char const *const *argv, *argp; 325b6217683SBrian Somers 326b6217683SBrian Somers argc = arg->argc; 327b6217683SBrian Somers argv = arg->argv; 328b6217683SBrian Somers res = 0; 329b6217683SBrian Somers 330b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 331b6217683SBrian Somers local = 0; 332b6217683SBrian Somers else { 333b6217683SBrian Somers if (arg->prompt == NULL) { 334b6217683SBrian Somers LogPrintf(LogWARN, "set log local: Only available on the command line\n"); 335b6217683SBrian Somers return 1; 336b6217683SBrian Somers } 337b6217683SBrian Somers argc--; 338b6217683SBrian Somers argv++; 339b6217683SBrian Somers local = 1; 340b6217683SBrian Somers } 341b6217683SBrian Somers 342b6217683SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) 343b6217683SBrian Somers if (local) 344b6217683SBrian Somers LogDiscardAllLocal(&arg->prompt->logmask); 345b6217683SBrian Somers else 346b6217683SBrian Somers LogDiscardAll(); 347b6217683SBrian Somers 348b6217683SBrian Somers while (argc--) { 349b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 350b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 351b6217683SBrian Somers if (strcasecmp(argp, LogName(i)) == 0) { 352b6217683SBrian Somers if (**argv == '-') 353b6217683SBrian Somers if (local) 354b6217683SBrian Somers LogDiscardLocal(i, &arg->prompt->logmask); 355b6217683SBrian Somers else 356b6217683SBrian Somers LogDiscard(i); 357b6217683SBrian Somers else if (local) 358b6217683SBrian Somers LogKeepLocal(i, &arg->prompt->logmask); 359b6217683SBrian Somers else 360b6217683SBrian Somers LogKeep(i); 361b6217683SBrian Somers break; 362b6217683SBrian Somers } 363b6217683SBrian Somers if (i > LogMAX) { 364b6217683SBrian Somers LogPrintf(LogWARN, "%s: Invalid log value\n", argp); 365b6217683SBrian Somers res = -1; 366b6217683SBrian Somers } 367b6217683SBrian Somers argv++; 368b6217683SBrian Somers } 369b6217683SBrian Somers return res; 370b6217683SBrian Somers } 371b6217683SBrian Somers 372b6217683SBrian Somers int 373b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 374b6217683SBrian Somers { 375b6217683SBrian Somers struct prompt *p; 376b6217683SBrian Somers 377b6217683SBrian Somers for (p = logprompt; p; p = p->lognext) 378b6217683SBrian Somers prompt_Printf(arg->prompt, "%s%s\n", p->who, p == arg->prompt ? " *" : ""); 379b6217683SBrian Somers 380b6217683SBrian Somers return 0; 381b6217683SBrian Somers } 382