xref: /freebsd/usr.sbin/ppp/log.c (revision 2764b86afdc99a30f4b1a4da2c04db8aa7aa785d)
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  *
262764b86aSBrian Somers  *	$Id: log.c,v 1.25.2.5 1998/04/06 09:12:31 brian Exp $
271ae349f5Scvs2svn  */
281ae349f5Scvs2svn 
292764b86aSBrian Somers #include <sys/types.h>
301ae349f5Scvs2svn 
311ae349f5Scvs2svn #include <stdarg.h>
321ae349f5Scvs2svn #include <stdio.h>
33b6217683SBrian Somers #include <string.h>
341ae349f5Scvs2svn #include <syslog.h>
3585b542cfSBrian Somers #include <termios.h>
361ae349f5Scvs2svn 
371ae349f5Scvs2svn #include "command.h"
381ae349f5Scvs2svn #include "mbuf.h"
391ae349f5Scvs2svn #include "log.h"
4085b542cfSBrian Somers #include "descriptor.h"
4185b542cfSBrian Somers #include "prompt.h"
421ae349f5Scvs2svn 
431ae349f5Scvs2svn static const char *LogNames[] = {
441ae349f5Scvs2svn   "Async",
451ae349f5Scvs2svn   "Carrier",
461ae349f5Scvs2svn   "CCP",
471ae349f5Scvs2svn   "Chat",
481ae349f5Scvs2svn   "Command",
491ae349f5Scvs2svn   "Connect",
501ae349f5Scvs2svn   "Debug",
511ae349f5Scvs2svn   "HDLC",
521ae349f5Scvs2svn   "ID0",
531ae349f5Scvs2svn   "IPCP",
541ae349f5Scvs2svn   "LCP",
551ae349f5Scvs2svn   "Link",
561ae349f5Scvs2svn   "LQM",
571ae349f5Scvs2svn   "Phase",
581ae349f5Scvs2svn   "TCP/IP",
591ae349f5Scvs2svn   "Tun",
601ae349f5Scvs2svn   "Warning",
611ae349f5Scvs2svn   "Error",
621ae349f5Scvs2svn   "Alert"
631ae349f5Scvs2svn };
641ae349f5Scvs2svn 
651ae349f5Scvs2svn #define MSK(n) (1<<((n)-1))
661ae349f5Scvs2svn 
671ae349f5Scvs2svn static u_long LogMask = MSK(LogLINK) | MSK(LogCARRIER) | MSK(LogPHASE);
681ae349f5Scvs2svn static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
691ae349f5Scvs2svn static int LogTunno = -1;
70b6217683SBrian Somers static struct prompt *logprompt;	/* Where to log local stuff */
71b6217683SBrian Somers 
72b6217683SBrian Somers void
73b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt)
74b6217683SBrian Somers {
75b6217683SBrian Somers   if (prompt) {
76b6217683SBrian Somers     prompt->lognext = logprompt;
77b6217683SBrian Somers     logprompt = prompt;
78b6217683SBrian Somers     LogMaskLocal |= prompt->logmask;
79b6217683SBrian Somers   }
80b6217683SBrian Somers }
81b6217683SBrian Somers 
8267568487SBrian Somers static void
8367568487SBrian Somers LogSetMaskLocal(void)
8467568487SBrian Somers {
8567568487SBrian Somers   struct prompt *p;
8667568487SBrian Somers 
8767568487SBrian Somers   LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
8867568487SBrian Somers   for (p = logprompt; p; p = p->lognext)
8967568487SBrian Somers     LogMaskLocal |= p->logmask;
9067568487SBrian Somers }
9167568487SBrian Somers 
92b6217683SBrian Somers void
93b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt)
94b6217683SBrian Somers {
95b6217683SBrian Somers   if (prompt) {
96b6217683SBrian Somers     struct prompt **p;
97b6217683SBrian Somers 
9867568487SBrian Somers     for (p = &logprompt; *p; p = &(*p)->lognext)
99b6217683SBrian Somers       if (*p == prompt) {
10067568487SBrian Somers         *p = prompt->lognext;
101b6217683SBrian Somers         prompt->lognext = NULL;
102b6217683SBrian Somers         break;
103b6217683SBrian Somers       }
10467568487SBrian Somers     LogSetMaskLocal();
105b6217683SBrian Somers   }
106b6217683SBrian Somers }
1071ae349f5Scvs2svn 
1081ae349f5Scvs2svn static int
1091ae349f5Scvs2svn syslogLevel(int lev)
1101ae349f5Scvs2svn {
1111ae349f5Scvs2svn   switch (lev) {
1121ae349f5Scvs2svn     case LogDEBUG:return LOG_DEBUG;
1131ae349f5Scvs2svn   case LogWARN:
1141ae349f5Scvs2svn     return LOG_WARNING;
1151ae349f5Scvs2svn   case LogERROR:
1161ae349f5Scvs2svn     return LOG_ERR;
1171ae349f5Scvs2svn   case LogALERT:
1181ae349f5Scvs2svn     return LOG_ALERT;
1191ae349f5Scvs2svn   }
1201ae349f5Scvs2svn   return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0;
1211ae349f5Scvs2svn }
1221ae349f5Scvs2svn 
1231ae349f5Scvs2svn const char *
1241ae349f5Scvs2svn LogName(int id)
1251ae349f5Scvs2svn {
1261ae349f5Scvs2svn   return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1];
1271ae349f5Scvs2svn }
1281ae349f5Scvs2svn 
1291ae349f5Scvs2svn void
1301ae349f5Scvs2svn LogKeep(int id)
1311ae349f5Scvs2svn {
1321ae349f5Scvs2svn   if (id >= LogMIN && id <= LogMAXCONF)
1331ae349f5Scvs2svn     LogMask |= MSK(id);
1341ae349f5Scvs2svn }
1351ae349f5Scvs2svn 
1361ae349f5Scvs2svn void
137b6217683SBrian Somers LogKeepLocal(int id, u_long *mask)
1381ae349f5Scvs2svn {
139b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
1401ae349f5Scvs2svn     LogMaskLocal |= MSK(id);
141b6217683SBrian Somers     *mask |= MSK(id);
142b6217683SBrian Somers   }
1431ae349f5Scvs2svn }
1441ae349f5Scvs2svn 
1451ae349f5Scvs2svn void
1461ae349f5Scvs2svn LogDiscard(int id)
1471ae349f5Scvs2svn {
1481ae349f5Scvs2svn   if (id >= LogMIN && id <= LogMAXCONF)
1491ae349f5Scvs2svn     LogMask &= ~MSK(id);
1501ae349f5Scvs2svn }
1511ae349f5Scvs2svn 
1521ae349f5Scvs2svn void
153b6217683SBrian Somers LogDiscardLocal(int id, u_long *mask)
1541ae349f5Scvs2svn {
155b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
156b6217683SBrian Somers     *mask &= ~MSK(id);
15767568487SBrian Somers     LogSetMaskLocal();
158b6217683SBrian Somers   }
1591ae349f5Scvs2svn }
1601ae349f5Scvs2svn 
1611ae349f5Scvs2svn void
1621ae349f5Scvs2svn LogDiscardAll()
1631ae349f5Scvs2svn {
1641ae349f5Scvs2svn   LogMask = 0;
1651ae349f5Scvs2svn }
1661ae349f5Scvs2svn 
1671ae349f5Scvs2svn void
168b6217683SBrian Somers LogDiscardAllLocal(u_long *mask)
1691ae349f5Scvs2svn {
17067568487SBrian Somers   *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
17167568487SBrian Somers   LogSetMaskLocal();
1721ae349f5Scvs2svn }
1731ae349f5Scvs2svn 
1741ae349f5Scvs2svn int
1751ae349f5Scvs2svn LogIsKept(int id)
1761ae349f5Scvs2svn {
1771ae349f5Scvs2svn   if (id < LogMIN || id > LogMAX)
1781ae349f5Scvs2svn     return 0;
1791ae349f5Scvs2svn   if (id > LogMAXCONF)
1801ae349f5Scvs2svn     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
1811ae349f5Scvs2svn 
1821ae349f5Scvs2svn   return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
1831ae349f5Scvs2svn     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
1841ae349f5Scvs2svn }
1851ae349f5Scvs2svn 
186b6217683SBrian Somers int
187b6217683SBrian Somers LogIsKeptLocal(int id, u_long mask)
188b6217683SBrian Somers {
189b6217683SBrian Somers   if (id < LogMIN || id > LogMAX)
190b6217683SBrian Somers     return 0;
191b6217683SBrian Somers   if (id > LogMAXCONF)
192b6217683SBrian Somers     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
193b6217683SBrian Somers 
194b6217683SBrian Somers   return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
195b6217683SBrian Somers     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
196b6217683SBrian Somers }
197b6217683SBrian Somers 
1981ae349f5Scvs2svn void
1991ae349f5Scvs2svn LogOpen(const char *Name)
2001ae349f5Scvs2svn {
2011ae349f5Scvs2svn   openlog(Name, LOG_PID, LOG_DAEMON);
2021ae349f5Scvs2svn }
2031ae349f5Scvs2svn 
2041ae349f5Scvs2svn void
2051ae349f5Scvs2svn LogSetTun(int tunno)
2061ae349f5Scvs2svn {
2071ae349f5Scvs2svn   LogTunno = tunno;
2081ae349f5Scvs2svn }
2091ae349f5Scvs2svn 
2101ae349f5Scvs2svn void
2111ae349f5Scvs2svn LogClose()
2121ae349f5Scvs2svn {
2131ae349f5Scvs2svn   closelog();
2141ae349f5Scvs2svn   LogTunno = -1;
2151ae349f5Scvs2svn }
2161ae349f5Scvs2svn 
2171ae349f5Scvs2svn void
2181ae349f5Scvs2svn LogPrintf(int lev, const char *fmt,...)
2191ae349f5Scvs2svn {
2201ae349f5Scvs2svn   va_list ap;
221b6217683SBrian Somers   struct prompt *prompt;
2221ae349f5Scvs2svn 
2231ae349f5Scvs2svn   va_start(ap, fmt);
2241ae349f5Scvs2svn   if (LogIsKept(lev)) {
2251ae349f5Scvs2svn     static char nfmt[200];
2261ae349f5Scvs2svn 
227b6217683SBrian Somers     if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && logprompt) {
2281ae349f5Scvs2svn       if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
2291ae349f5Scvs2svn         snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s",
2301ae349f5Scvs2svn 	         LogTunno, LogName(lev), fmt);
2311ae349f5Scvs2svn       else
2321ae349f5Scvs2svn         snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt);
233b6217683SBrian Somers 
234b6217683SBrian Somers       for (prompt = logprompt; prompt; prompt = prompt->lognext)
235b6217683SBrian Somers         if (lev > LogMAXCONF || (prompt->logmask & MSK(lev)))
236b6217683SBrian Somers           prompt_vPrintf(prompt, nfmt, ap);
2371ae349f5Scvs2svn     }
2381ae349f5Scvs2svn 
239b6217683SBrian Somers     if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) {
2401ae349f5Scvs2svn       if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
2411ae349f5Scvs2svn         snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s",
2421ae349f5Scvs2svn 	         LogTunno, LogName(lev), fmt);
2431ae349f5Scvs2svn       else
2441ae349f5Scvs2svn         snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt);
2451ae349f5Scvs2svn       vsyslog(syslogLevel(lev), nfmt, ap);
2461ae349f5Scvs2svn     }
2471ae349f5Scvs2svn   }
2481ae349f5Scvs2svn   va_end(ap);
2491ae349f5Scvs2svn }
2501ae349f5Scvs2svn 
2511ae349f5Scvs2svn void
2521ae349f5Scvs2svn LogDumpBp(int lev, const char *hdr, const struct mbuf * bp)
2531ae349f5Scvs2svn {
2541ae349f5Scvs2svn   if (LogIsKept(lev)) {
2551ae349f5Scvs2svn     char buf[50];
2561ae349f5Scvs2svn     char *b;
2571ae349f5Scvs2svn     u_char *ptr;
2581ae349f5Scvs2svn     int f;
2591ae349f5Scvs2svn 
2601ae349f5Scvs2svn     if (hdr && *hdr)
2611ae349f5Scvs2svn       LogPrintf(lev, "%s\n", hdr);
2621ae349f5Scvs2svn 
2631ae349f5Scvs2svn     b = buf;
2641ae349f5Scvs2svn     do {
2651ae349f5Scvs2svn       f = bp->cnt;
2661ae349f5Scvs2svn       ptr = MBUF_CTOP(bp);
2671ae349f5Scvs2svn       while (f--) {
2681ae349f5Scvs2svn 	sprintf(b, " %02x", (int) *ptr++);
2691ae349f5Scvs2svn         b += 3;
2701ae349f5Scvs2svn         if (b == buf + sizeof buf - 2) {
2711ae349f5Scvs2svn           strcpy(b, "\n");
2721ae349f5Scvs2svn           LogPrintf(lev, buf);
2731ae349f5Scvs2svn           b = buf;
2741ae349f5Scvs2svn         }
2751ae349f5Scvs2svn       }
2761ae349f5Scvs2svn     } while ((bp = bp->next) != NULL);
2771ae349f5Scvs2svn 
2781ae349f5Scvs2svn     if (b > buf) {
2791ae349f5Scvs2svn       strcpy(b, "\n");
2801ae349f5Scvs2svn       LogPrintf(lev, buf);
2811ae349f5Scvs2svn     }
2821ae349f5Scvs2svn   }
2831ae349f5Scvs2svn }
2841ae349f5Scvs2svn 
2851ae349f5Scvs2svn void
2861ae349f5Scvs2svn LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n)
2871ae349f5Scvs2svn {
2881ae349f5Scvs2svn   if (LogIsKept(lev)) {
2891ae349f5Scvs2svn     char buf[50];
2901ae349f5Scvs2svn     char *b;
2911ae349f5Scvs2svn 
2921ae349f5Scvs2svn     if (hdr && *hdr)
2931ae349f5Scvs2svn       LogPrintf(lev, "%s\n", hdr);
2941ae349f5Scvs2svn     while (n > 0) {
2951ae349f5Scvs2svn       b = buf;
2961ae349f5Scvs2svn       for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3)
2971ae349f5Scvs2svn 	sprintf(b, " %02x", (int) *ptr++);
2981ae349f5Scvs2svn       strcpy(b, "\n");
2991ae349f5Scvs2svn       LogPrintf(lev, buf);
3001ae349f5Scvs2svn     }
3011ae349f5Scvs2svn   }
3021ae349f5Scvs2svn }
303b6217683SBrian Somers 
304b6217683SBrian Somers int
305b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg)
306b6217683SBrian Somers {
307b6217683SBrian Somers   int i;
308b6217683SBrian Somers 
309b6217683SBrian Somers   prompt_Printf(arg->prompt, "Log:  ");
310b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
311b6217683SBrian Somers     if (LogIsKept(i) & LOG_KEPT_SYSLOG)
312b6217683SBrian Somers       prompt_Printf(arg->prompt, " %s", LogName(i));
313b6217683SBrian Somers 
314b6217683SBrian Somers   prompt_Printf(arg->prompt, "\nLocal:");
315b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
316b6217683SBrian Somers     if (LogIsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL)
317b6217683SBrian Somers       prompt_Printf(arg->prompt, " %s", LogName(i));
318b6217683SBrian Somers 
319b6217683SBrian Somers   prompt_Printf(arg->prompt, "\n");
320b6217683SBrian Somers 
321b6217683SBrian Somers   return 0;
322b6217683SBrian Somers }
323b6217683SBrian Somers 
324b6217683SBrian Somers int
325b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg)
326b6217683SBrian Somers {
327b6217683SBrian Somers   int i, res, argc, local;
328b6217683SBrian Somers   char const *const *argv, *argp;
329b6217683SBrian Somers 
330b6217683SBrian Somers   argc = arg->argc;
331b6217683SBrian Somers   argv = arg->argv;
332b6217683SBrian Somers   res = 0;
333b6217683SBrian Somers 
334b6217683SBrian Somers   if (argc == 0 || strcasecmp(argv[0], "local"))
335b6217683SBrian Somers     local = 0;
336b6217683SBrian Somers   else {
337b6217683SBrian Somers     if (arg->prompt == NULL) {
338b6217683SBrian Somers       LogPrintf(LogWARN, "set log local: Only available on the command line\n");
339b6217683SBrian Somers       return 1;
340b6217683SBrian Somers     }
341b6217683SBrian Somers     argc--;
342b6217683SBrian Somers     argv++;
343b6217683SBrian Somers     local = 1;
344b6217683SBrian Somers   }
345b6217683SBrian Somers 
346b6217683SBrian Somers   if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-'))
347b6217683SBrian Somers     if (local)
348b6217683SBrian Somers       LogDiscardAllLocal(&arg->prompt->logmask);
349b6217683SBrian Somers     else
350b6217683SBrian Somers       LogDiscardAll();
351b6217683SBrian Somers 
352b6217683SBrian Somers   while (argc--) {
353b6217683SBrian Somers     argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
354b6217683SBrian Somers     for (i = LogMIN; i <= LogMAX; i++)
355b6217683SBrian Somers       if (strcasecmp(argp, LogName(i)) == 0) {
356b6217683SBrian Somers 	if (**argv == '-')
357b6217683SBrian Somers           if (local)
358b6217683SBrian Somers             LogDiscardLocal(i, &arg->prompt->logmask);
359b6217683SBrian Somers           else
360b6217683SBrian Somers 	    LogDiscard(i);
361b6217683SBrian Somers 	else if (local)
362b6217683SBrian Somers           LogKeepLocal(i, &arg->prompt->logmask);
363b6217683SBrian Somers         else
364b6217683SBrian Somers           LogKeep(i);
365b6217683SBrian Somers 	break;
366b6217683SBrian Somers       }
367b6217683SBrian Somers     if (i > LogMAX) {
368b6217683SBrian Somers       LogPrintf(LogWARN, "%s: Invalid log value\n", argp);
369b6217683SBrian Somers       res = -1;
370b6217683SBrian Somers     }
371b6217683SBrian Somers     argv++;
372b6217683SBrian Somers   }
373b6217683SBrian Somers   return res;
374b6217683SBrian Somers }
375b6217683SBrian Somers 
376b6217683SBrian Somers int
377b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg)
378b6217683SBrian Somers {
379b6217683SBrian Somers   struct prompt *p;
380b6217683SBrian Somers 
381f91ad6b0SBrian Somers   for (p = logprompt; p; p = p->lognext) {
382f91ad6b0SBrian Somers     prompt_Printf(arg->prompt, "%s", p->who);
383f91ad6b0SBrian Somers     if (p == arg->prompt)
384f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " *");
385f91ad6b0SBrian Somers     if (!p->active)
386f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " ^Z");
387f91ad6b0SBrian Somers     prompt_Printf(arg->prompt, "\n");
388f91ad6b0SBrian Somers   }
389b6217683SBrian Somers 
390b6217683SBrian Somers   return 0;
391b6217683SBrian Somers }
392