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 * 26f91ad6b0SBrian Somers * $Id: log.c,v 1.25.2.3 1998/04/03 19:26:40 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 8667568487SBrian Somers static void 8767568487SBrian Somers LogSetMaskLocal(void) 8867568487SBrian Somers { 8967568487SBrian Somers struct prompt *p; 9067568487SBrian Somers 9167568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 9267568487SBrian Somers for (p = logprompt; p; p = p->lognext) 9367568487SBrian Somers LogMaskLocal |= p->logmask; 9467568487SBrian Somers } 9567568487SBrian Somers 96b6217683SBrian Somers void 97b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 98b6217683SBrian Somers { 99b6217683SBrian Somers if (prompt) { 100b6217683SBrian Somers struct prompt **p; 101b6217683SBrian Somers 10267568487SBrian Somers for (p = &logprompt; *p; p = &(*p)->lognext) 103b6217683SBrian Somers if (*p == prompt) { 10467568487SBrian Somers *p = prompt->lognext; 105b6217683SBrian Somers prompt->lognext = NULL; 106b6217683SBrian Somers break; 107b6217683SBrian Somers } 10867568487SBrian Somers LogSetMaskLocal(); 109b6217683SBrian Somers } 110b6217683SBrian Somers } 1111ae349f5Scvs2svn 1121ae349f5Scvs2svn static int 1131ae349f5Scvs2svn syslogLevel(int lev) 1141ae349f5Scvs2svn { 1151ae349f5Scvs2svn switch (lev) { 1161ae349f5Scvs2svn case LogDEBUG:return LOG_DEBUG; 1171ae349f5Scvs2svn case LogWARN: 1181ae349f5Scvs2svn return LOG_WARNING; 1191ae349f5Scvs2svn case LogERROR: 1201ae349f5Scvs2svn return LOG_ERR; 1211ae349f5Scvs2svn case LogALERT: 1221ae349f5Scvs2svn return LOG_ALERT; 1231ae349f5Scvs2svn } 1241ae349f5Scvs2svn return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 1251ae349f5Scvs2svn } 1261ae349f5Scvs2svn 1271ae349f5Scvs2svn const char * 1281ae349f5Scvs2svn LogName(int id) 1291ae349f5Scvs2svn { 1301ae349f5Scvs2svn return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 1311ae349f5Scvs2svn } 1321ae349f5Scvs2svn 1331ae349f5Scvs2svn void 1341ae349f5Scvs2svn LogKeep(int id) 1351ae349f5Scvs2svn { 1361ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1371ae349f5Scvs2svn LogMask |= MSK(id); 1381ae349f5Scvs2svn } 1391ae349f5Scvs2svn 1401ae349f5Scvs2svn void 141b6217683SBrian Somers LogKeepLocal(int id, u_long *mask) 1421ae349f5Scvs2svn { 143b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 1441ae349f5Scvs2svn LogMaskLocal |= MSK(id); 145b6217683SBrian Somers *mask |= MSK(id); 146b6217683SBrian Somers } 1471ae349f5Scvs2svn } 1481ae349f5Scvs2svn 1491ae349f5Scvs2svn void 1501ae349f5Scvs2svn LogDiscard(int id) 1511ae349f5Scvs2svn { 1521ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1531ae349f5Scvs2svn LogMask &= ~MSK(id); 1541ae349f5Scvs2svn } 1551ae349f5Scvs2svn 1561ae349f5Scvs2svn void 157b6217683SBrian Somers LogDiscardLocal(int id, u_long *mask) 1581ae349f5Scvs2svn { 159b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 160b6217683SBrian Somers *mask &= ~MSK(id); 16167568487SBrian Somers LogSetMaskLocal(); 162b6217683SBrian Somers } 1631ae349f5Scvs2svn } 1641ae349f5Scvs2svn 1651ae349f5Scvs2svn void 1661ae349f5Scvs2svn LogDiscardAll() 1671ae349f5Scvs2svn { 1681ae349f5Scvs2svn LogMask = 0; 1691ae349f5Scvs2svn } 1701ae349f5Scvs2svn 1711ae349f5Scvs2svn void 172b6217683SBrian Somers LogDiscardAllLocal(u_long *mask) 1731ae349f5Scvs2svn { 17467568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 17567568487SBrian Somers LogSetMaskLocal(); 1761ae349f5Scvs2svn } 1771ae349f5Scvs2svn 1781ae349f5Scvs2svn int 1791ae349f5Scvs2svn LogIsKept(int id) 1801ae349f5Scvs2svn { 1811ae349f5Scvs2svn if (id < LogMIN || id > LogMAX) 1821ae349f5Scvs2svn return 0; 1831ae349f5Scvs2svn if (id > LogMAXCONF) 1841ae349f5Scvs2svn return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 1851ae349f5Scvs2svn 1861ae349f5Scvs2svn return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 1871ae349f5Scvs2svn ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 1881ae349f5Scvs2svn } 1891ae349f5Scvs2svn 190b6217683SBrian Somers int 191b6217683SBrian Somers LogIsKeptLocal(int id, u_long mask) 192b6217683SBrian Somers { 193b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 194b6217683SBrian Somers return 0; 195b6217683SBrian Somers if (id > LogMAXCONF) 196b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 197b6217683SBrian Somers 198b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 199b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 200b6217683SBrian Somers } 201b6217683SBrian Somers 2021ae349f5Scvs2svn void 2031ae349f5Scvs2svn LogOpen(const char *Name) 2041ae349f5Scvs2svn { 2051ae349f5Scvs2svn openlog(Name, LOG_PID, LOG_DAEMON); 2061ae349f5Scvs2svn } 2071ae349f5Scvs2svn 2081ae349f5Scvs2svn void 2091ae349f5Scvs2svn LogSetTun(int tunno) 2101ae349f5Scvs2svn { 2111ae349f5Scvs2svn LogTunno = tunno; 2121ae349f5Scvs2svn } 2131ae349f5Scvs2svn 2141ae349f5Scvs2svn void 2151ae349f5Scvs2svn LogClose() 2161ae349f5Scvs2svn { 2171ae349f5Scvs2svn closelog(); 2181ae349f5Scvs2svn LogTunno = -1; 2191ae349f5Scvs2svn } 2201ae349f5Scvs2svn 2211ae349f5Scvs2svn void 2221ae349f5Scvs2svn LogPrintf(int lev, const char *fmt,...) 2231ae349f5Scvs2svn { 2241ae349f5Scvs2svn va_list ap; 225b6217683SBrian Somers struct prompt *prompt; 2261ae349f5Scvs2svn 2271ae349f5Scvs2svn va_start(ap, fmt); 2281ae349f5Scvs2svn if (LogIsKept(lev)) { 2291ae349f5Scvs2svn static char nfmt[200]; 2301ae349f5Scvs2svn 231b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && logprompt) { 2321ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 2331ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2341ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2351ae349f5Scvs2svn else 2361ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 237b6217683SBrian Somers 238b6217683SBrian Somers for (prompt = logprompt; prompt; prompt = prompt->lognext) 239b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 240b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 2411ae349f5Scvs2svn } 2421ae349f5Scvs2svn 243b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) { 2441ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 2451ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2461ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2471ae349f5Scvs2svn else 2481ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 2491ae349f5Scvs2svn vsyslog(syslogLevel(lev), nfmt, ap); 2501ae349f5Scvs2svn } 2511ae349f5Scvs2svn } 2521ae349f5Scvs2svn va_end(ap); 2531ae349f5Scvs2svn } 2541ae349f5Scvs2svn 2551ae349f5Scvs2svn void 2561ae349f5Scvs2svn LogDumpBp(int lev, const char *hdr, const struct mbuf * bp) 2571ae349f5Scvs2svn { 2581ae349f5Scvs2svn if (LogIsKept(lev)) { 2591ae349f5Scvs2svn char buf[50]; 2601ae349f5Scvs2svn char *b; 2611ae349f5Scvs2svn u_char *ptr; 2621ae349f5Scvs2svn int f; 2631ae349f5Scvs2svn 2641ae349f5Scvs2svn if (hdr && *hdr) 2651ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2661ae349f5Scvs2svn 2671ae349f5Scvs2svn b = buf; 2681ae349f5Scvs2svn do { 2691ae349f5Scvs2svn f = bp->cnt; 2701ae349f5Scvs2svn ptr = MBUF_CTOP(bp); 2711ae349f5Scvs2svn while (f--) { 2721ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2731ae349f5Scvs2svn b += 3; 2741ae349f5Scvs2svn if (b == buf + sizeof buf - 2) { 2751ae349f5Scvs2svn strcpy(b, "\n"); 2761ae349f5Scvs2svn LogPrintf(lev, buf); 2771ae349f5Scvs2svn b = buf; 2781ae349f5Scvs2svn } 2791ae349f5Scvs2svn } 2801ae349f5Scvs2svn } while ((bp = bp->next) != NULL); 2811ae349f5Scvs2svn 2821ae349f5Scvs2svn if (b > buf) { 2831ae349f5Scvs2svn strcpy(b, "\n"); 2841ae349f5Scvs2svn LogPrintf(lev, buf); 2851ae349f5Scvs2svn } 2861ae349f5Scvs2svn } 2871ae349f5Scvs2svn } 2881ae349f5Scvs2svn 2891ae349f5Scvs2svn void 2901ae349f5Scvs2svn LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 2911ae349f5Scvs2svn { 2921ae349f5Scvs2svn if (LogIsKept(lev)) { 2931ae349f5Scvs2svn char buf[50]; 2941ae349f5Scvs2svn char *b; 2951ae349f5Scvs2svn 2961ae349f5Scvs2svn if (hdr && *hdr) 2971ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2981ae349f5Scvs2svn while (n > 0) { 2991ae349f5Scvs2svn b = buf; 3001ae349f5Scvs2svn for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 3011ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 3021ae349f5Scvs2svn strcpy(b, "\n"); 3031ae349f5Scvs2svn LogPrintf(lev, buf); 3041ae349f5Scvs2svn } 3051ae349f5Scvs2svn } 3061ae349f5Scvs2svn } 307b6217683SBrian Somers 308b6217683SBrian Somers int 309b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 310b6217683SBrian Somers { 311b6217683SBrian Somers int i; 312b6217683SBrian Somers 313b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 314b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 315b6217683SBrian Somers if (LogIsKept(i) & LOG_KEPT_SYSLOG) 316b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 317b6217683SBrian Somers 318b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 319b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 320b6217683SBrian Somers if (LogIsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 321b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 322b6217683SBrian Somers 323b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 324b6217683SBrian Somers 325b6217683SBrian Somers return 0; 326b6217683SBrian Somers } 327b6217683SBrian Somers 328b6217683SBrian Somers int 329b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 330b6217683SBrian Somers { 331b6217683SBrian Somers int i, res, argc, local; 332b6217683SBrian Somers char const *const *argv, *argp; 333b6217683SBrian Somers 334b6217683SBrian Somers argc = arg->argc; 335b6217683SBrian Somers argv = arg->argv; 336b6217683SBrian Somers res = 0; 337b6217683SBrian Somers 338b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 339b6217683SBrian Somers local = 0; 340b6217683SBrian Somers else { 341b6217683SBrian Somers if (arg->prompt == NULL) { 342b6217683SBrian Somers LogPrintf(LogWARN, "set log local: Only available on the command line\n"); 343b6217683SBrian Somers return 1; 344b6217683SBrian Somers } 345b6217683SBrian Somers argc--; 346b6217683SBrian Somers argv++; 347b6217683SBrian Somers local = 1; 348b6217683SBrian Somers } 349b6217683SBrian Somers 350b6217683SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) 351b6217683SBrian Somers if (local) 352b6217683SBrian Somers LogDiscardAllLocal(&arg->prompt->logmask); 353b6217683SBrian Somers else 354b6217683SBrian Somers LogDiscardAll(); 355b6217683SBrian Somers 356b6217683SBrian Somers while (argc--) { 357b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 358b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 359b6217683SBrian Somers if (strcasecmp(argp, LogName(i)) == 0) { 360b6217683SBrian Somers if (**argv == '-') 361b6217683SBrian Somers if (local) 362b6217683SBrian Somers LogDiscardLocal(i, &arg->prompt->logmask); 363b6217683SBrian Somers else 364b6217683SBrian Somers LogDiscard(i); 365b6217683SBrian Somers else if (local) 366b6217683SBrian Somers LogKeepLocal(i, &arg->prompt->logmask); 367b6217683SBrian Somers else 368b6217683SBrian Somers LogKeep(i); 369b6217683SBrian Somers break; 370b6217683SBrian Somers } 371b6217683SBrian Somers if (i > LogMAX) { 372b6217683SBrian Somers LogPrintf(LogWARN, "%s: Invalid log value\n", argp); 373b6217683SBrian Somers res = -1; 374b6217683SBrian Somers } 375b6217683SBrian Somers argv++; 376b6217683SBrian Somers } 377b6217683SBrian Somers return res; 378b6217683SBrian Somers } 379b6217683SBrian Somers 380b6217683SBrian Somers int 381b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 382b6217683SBrian Somers { 383b6217683SBrian Somers struct prompt *p; 384b6217683SBrian Somers 385f91ad6b0SBrian Somers for (p = logprompt; p; p = p->lognext) { 386f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "%s", p->who); 387f91ad6b0SBrian Somers if (p == arg->prompt) 388f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 389f91ad6b0SBrian Somers if (!p->active) 390f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 391f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 392f91ad6b0SBrian Somers } 393b6217683SBrian Somers 394b6217683SBrian Somers return 0; 395b6217683SBrian Somers } 396