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