xref: /freebsd/usr.sbin/ppp/log.c (revision b6217683dc0269a53b799399522dbdfb5a4919cc)
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