1bdca873a0f7147133aa888087e92c901bba2e41
[ppp.git] / pppd / main.c
1 /*
2  * main.c - Point-to-Point Protocol main module
3  *
4  * Copyright (c) 1989 Carnegie Mellon University.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms are permitted
8  * provided that the above copyright notice and this paragraph are
9  * duplicated in all such forms and that any documentation,
10  * advertising materials, and other materials related to such
11  * distribution and use acknowledge that the software was developed
12  * by Carnegie Mellon University.  The name of the
13  * University may not be used to endorse or promote products derived
14  * from this software without specific prior written permission.
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  */
19
20 #ifndef lint
21 static char rcsid[] = "$Id: main.c,v 1.11 1994/05/24 11:25:33 paulus Exp $";
22 #endif
23
24 #define SETSID
25
26 #include <stdio.h>
27 #include <signal.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <syslog.h>
31 #include <netdb.h>
32 #include <utmp.h>
33 #include <pwd.h>
34 #include <sys/wait.h>
35
36 /*
37  * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless
38  * /etc/ppp/options exists.
39  */
40 #ifndef REQ_SYSOPTIONS
41 #define REQ_SYSOPTIONS  1
42 #endif
43
44 #ifdef SGTTY
45 #include <sgtty.h>
46 #else
47 #ifndef sun
48 #include <sys/ioctl.h>
49 #endif
50 #include <termios.h>
51 #endif
52
53 #include <sys/param.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <sys/socket.h>
57 #include <sys/time.h>
58
59 #include "callout.h"
60
61 #include <net/if.h>
62 #include <net/if_ppp.h>
63
64 #include <string.h>
65
66 #include "ppp.h"
67 #include "magic.h"
68 #include "fsm.h"
69 #include "lcp.h"
70 #include "ipcp.h"
71 #include "upap.h"
72 #include "chap.h"
73
74 #include "pppd.h"
75 #include "pathnames.h"
76 #include "patchlevel.h"
77
78
79 #ifndef TRUE
80 #define TRUE (1)
81 #endif /*TRUE*/
82
83 #ifndef FALSE
84 #define FALSE (0)
85 #endif /*FALSE*/
86
87 #ifdef PIDPATH
88 static char *pidpath = PIDPATH; /* filename in which pid will be stored */
89 #else
90 static char *pidpath = _PATH_PIDFILE;
91 #endif /* PIDFILE */
92
93 /* interface vars */
94 char ifname[IFNAMSIZ];          /* Interface name */
95 int ifunit;                     /* Interface unit number */
96
97 char *progname;                 /* Name of this program */
98 char hostname[MAXNAMELEN];      /* Our hostname */
99 char our_name[MAXNAMELEN];
100 char remote_name[MAXNAMELEN];
101 static char pidfilename[MAXPATHLEN];
102
103 static pid_t    pid;            /* Our pid */
104 static pid_t    pgrpid;         /* Process Group ID */
105 uid_t uid;                      /* Our real user-id */
106
107 char devname[MAXPATHLEN] = "/dev/tty";  /* Device name */
108 int default_device = TRUE;      /* use default device (stdin/out) */
109
110 int fd = -1;                    /* Device file descriptor */
111 int s;                          /* Socket file descriptor */
112
113 int phase;                      /* where the link is at */
114
115 #ifdef SGTTY
116 static struct sgttyb initsgttyb;        /* Initial TTY sgttyb */
117 #else
118 static struct termios inittermios;      /* Initial TTY termios */
119 #endif
120
121 static int initfdflags = -1;    /* Initial file descriptor flags */
122
123 static int restore_term;        /* 1 => we've munged the terminal */
124
125 u_char outpacket_buf[MTU+DLLHEADERLEN]; /* buffer for outgoing packet */
126 static u_char inpacket_buf[MTU+DLLHEADERLEN]; /* buffer for incoming packet */
127
128 int hungup;                     /* terminal has been hung up */
129 static int n_children;          /* # child processes still running */
130
131 /* configured variables */
132
133 int debug = 0;                  /* Debug flag */
134 int kdebugflag = 0;             /* Kernel debugging flag */
135 char user[MAXNAMELEN];          /* username for PAP */
136 char passwd[MAXSECRETLEN];      /* password for PAP */
137 char *connector = NULL;         /* "connect" command */
138 char *disconnector = NULL;      /* "disconnect" command */
139 int inspeed = 0;                /* Input/Output speed requested */
140 int baud_rate;                  /* bits/sec currently used */
141 u_long netmask = 0;             /* netmask to use on ppp interface */
142 int crtscts = 0;                /* use h/w flow control */
143 int nodetach = 0;               /* don't fork */
144 int modem = 0;                  /* use modem control lines */
145 int auth_required = 0;          /* require peer to authenticate */
146 int defaultroute = 0;           /* assign default route through interface */
147 int proxyarp = 0;               /* set entry in arp table */
148 int persist = 0;                /* re-initiate on termination */
149 int answer = 0;                 /* wait for incoming call */
150 int uselogin = 0;               /* check PAP info against /etc/passwd */
151 int lockflag = 0;               /* lock the serial device */
152
153
154 /* prototypes */
155 static void hup __ARGS((int));
156 static void intr __ARGS((int));
157 static void term __ARGS((int));
158 static void alrm __ARGS((int));
159 static void io __ARGS((int));
160 static void chld __ARGS((int));
161 static void incdebug __ARGS((int));
162 static void nodebug __ARGS((int));
163 void establish_ppp __ARGS((void));
164
165 void reap_kids __ARGS((void));
166 void cleanup __ARGS((int, caddr_t));
167 void die __ARGS((int));
168 void novm __ARGS((char *));
169
170 void log_packet __ARGS((u_char *, int, char *));
171 void format_packet __ARGS((u_char *, int,
172                            void (*) (void *, char *, ...), void *));
173 void pr_log __ARGS((void *, char *, ...));
174
175 extern  char    *ttyname __ARGS((int));
176 extern  char    *getlogin __ARGS((void));
177
178 /*
179  * PPP Data Link Layer "protocol" table.
180  * One entry per supported protocol.
181  */
182 static struct protent {
183     u_short protocol;
184     void (*init)();
185     void (*input)();
186     void (*protrej)();
187     int  (*printpkt)();
188     char *name;
189 } prottbl[] = {
190     { LCP, lcp_init, lcp_input, lcp_protrej, lcp_printpkt, "LCP" },
191     { IPCP, ipcp_init, ipcp_input, ipcp_protrej, ipcp_printpkt, "IPCP" },
192     { UPAP, upap_init, upap_input, upap_protrej, upap_printpkt, "PAP" },
193     { CHAP, ChapInit, ChapInput, ChapProtocolReject, ChapPrintPkt, "CHAP" },
194 };
195
196 #define N_PROTO         (sizeof(prottbl) / sizeof(prottbl[0]))
197
198 main(argc, argv)
199     int argc;
200     char *argv[];
201 {
202     int mask, i;
203     struct sigaction sa;
204     struct cmd *cmdp;
205     FILE *pidfile;
206     char *p;
207     struct passwd *pw;
208
209     p = ttyname(0);
210     if (p)
211         strcpy(devname, p);
212   
213     if (gethostname(hostname, MAXNAMELEN) < 0 ) {
214         perror("couldn't get hostname");
215         die(1);
216     }
217     hostname[MAXNAMELEN-1] = 0;
218
219     pid = getpid();
220     uid = getuid();
221
222     if (!ppp_available()) {
223         fprintf(stderr, "Sorry - PPP is not available on this system\n");
224         exit(1);
225     }
226
227     /*
228      * Initialize to the standard option set, then parse, in order,
229      * the system options file, the user's options file, and the command
230      * line arguments.
231      */
232     for (i = 0; i < N_PROTO; i++)
233         (*prottbl[i].init)(0);
234   
235     progname = *argv;
236
237     if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) ||
238         !options_from_user() ||
239         !parse_args(argc-1, argv+1) ||
240         !options_for_tty())
241         die(1);
242     check_auth_options();
243     setipdefault();
244
245     /*
246      * Initialize syslog system and magic number package.
247      */
248 #if !defined(ultrix)
249     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
250     setlogmask(LOG_UPTO(LOG_INFO));
251 #else
252     openlog("pppd", LOG_PID);
253 #define LOG_UPTO(x) (x)
254 #define setlogmask(x) (x)
255 #endif
256     if (debug)
257         setlogmask(LOG_UPTO(LOG_DEBUG));
258
259     magic_init();
260
261     p = getlogin();
262     if (p == NULL) {
263         pw = getpwuid(uid);
264         if (pw != NULL && pw->pw_name != NULL)
265             p = pw->pw_name;
266         else
267             p = "(unknown)";
268     }
269     syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d",
270            VERSION, PATCHLEVEL, p, uid);
271
272 #ifdef SETSID
273     /*
274      * Make sure we can set the serial device to be our controlling terminal.
275      */
276     if (default_device) {
277         /*
278          * No device name was specified:
279          * we are in the device's session already.
280          */
281         if ((pgrpid = getpgrp(0)) < 0) {
282             syslog(LOG_ERR, "getpgrp(0): %m");
283             die(1);
284         }
285
286     } else {
287         /*
288          * Not default device: make sure we're not a process group leader,
289          * then become session leader of a new session (so we can make
290          * our device its controlling terminal and thus get SIGHUPs).
291          */
292         if (!nodetach) {
293             /* fork so we're not a process group leader */
294             if (pid = fork()) {
295                 exit(0);        /* parent is finished */
296             }
297             if (pid < 0) {
298                 syslog(LOG_ERR, "fork: %m");
299                 die(1);
300             }
301             pid = getpid();     /* otherwise pid is 0 in child */
302         } else {
303             /*
304              * try to put ourself into our parent's process group,
305              * so we're not a process group leader
306              */
307             if (setpgrp(pid, getppid()) < 0)
308                 syslog(LOG_WARNING, "setpgrp: %m");
309         }
310
311         /* create new session */
312         if ((pgrpid = setsid()) < 0) {
313             syslog(LOG_ERR, "setsid(): %m");
314             die(1);
315         }
316     }
317 #endif
318
319     if (lockflag && !default_device)
320         if (lock(devname) < 0)
321             die(1);
322
323     /* Get an internet socket for doing socket ioctl's on. */
324     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
325         syslog(LOG_ERR, "socket : %m");
326         die(1);
327     }
328   
329     /*
330      * Compute mask of all interesting signals and install signal handlers
331      * for each.  Only one signal handler may be active at a time.  Therefore,
332      * all other signals should be masked when any handler is executing.
333      */
334     sigemptyset(&mask);
335     sigaddset(&mask, SIGHUP);
336     sigaddset(&mask, SIGINT);
337     sigaddset(&mask, SIGALRM);
338     sigaddset(&mask, SIGIO);
339     sigaddset(&mask, SIGCHLD);
340 #ifdef  STREAMS
341     sigaddset(&mask, SIGPOLL);
342 #endif
343
344 #define SIGNAL(s, handler)      { \
345         sa.sa_handler = handler; \
346         if (sigaction(s, &sa, NULL) < 0) { \
347             syslog(LOG_ERR, "sigaction(%d): %m", s); \
348             die(1); \
349         } \
350     }
351
352     sa.sa_mask = mask;
353     sa.sa_flags = 0;
354     SIGNAL(SIGHUP, hup);                /* Hangup */
355     SIGNAL(SIGINT, intr);               /* Interrupt */
356     SIGNAL(SIGTERM, term);              /* Terminate */
357     SIGNAL(SIGALRM, alrm);              /* Timeout */
358     SIGNAL(SIGIO, io);                  /* Input available */
359     SIGNAL(SIGCHLD, chld);              /* Death of child process */
360 #ifdef  STREAMS
361     SIGNAL(SIGPOLL, io);                /* Input available */
362 #endif
363
364     signal(SIGUSR1, incdebug);          /* Increment debug flag */
365     signal(SIGUSR2, nodebug);           /* Reset debug flag */
366
367     /*
368      * Block SIGIOs and SIGPOLLs for now
369      */
370     sigemptyset(&mask);
371     sigaddset(&mask, SIGIO);
372 #ifdef  STREAMS
373     sigaddset(&mask, SIGPOLL);
374 #endif
375     sigprocmask(SIG_BLOCK, &mask, NULL);
376
377     /*
378      * Open the serial device and set it up to be the ppp interface.
379      */
380     if ((fd = open(devname, O_RDWR /*| O_NDELAY*/)) < 0) {
381         syslog(LOG_ERR, "open(%s): %m", devname);
382         die(1);
383     }
384     hungup = 0;
385
386 #ifdef TIOCSCTTY
387     /* set device to be controlling tty */
388     if (!default_device && ioctl(fd, TIOCSCTTY) < 0) {
389         syslog(LOG_ERR, "ioctl(TIOCSCTTY): %m");
390         die(1);
391     }
392 #endif /* TIOCSCTTY */
393
394     /* run connection script */
395     if (connector) {
396         MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
397
398         /* set line speed, flow control, etc.; set CLOCAL for now */
399         set_up_tty(fd, 1);
400
401         /* drop dtr to hang up in case modem is off hook */
402         if (!default_device && modem) {
403             setdtr(fd, FALSE);
404             sleep(1);
405             setdtr(fd, TRUE);
406         }
407
408         if (device_script(connector, fd, fd) < 0) {
409             syslog(LOG_ERR, "could not set up connection");
410             setdtr(fd, FALSE);
411             die(1);
412         }
413
414         syslog(LOG_INFO, "Connected...");
415         sleep(1);               /* give it time to set up its terminal */
416     }
417   
418     /* set line speed, flow control, etc.; clear CLOCAL if modem option */
419     set_up_tty(fd, 0);
420
421     /* set up the serial device as a ppp interface */
422     establish_ppp();
423
424     syslog(LOG_INFO, "Using interface ppp%d", ifunit);
425     (void) sprintf(ifname, "ppp%d", ifunit);
426
427     /* write pid to file */
428     (void) sprintf(pidfilename, "%s/%s.pid", pidpath, ifname);
429     if ((pidfile = fopen(pidfilename, "w")) != NULL) {
430         fprintf(pidfile, "%d\n", pid);
431         (void) fclose(pidfile);
432     } else {
433         syslog(LOG_ERR, "unable to create pid file: %m");
434         pidfilename[0] = 0;
435     }
436
437     /*
438      * Set process group of device to our process group so we can get
439      * SIGIOs and SIGHUPs.
440      */
441 #ifdef SETSID
442     if (default_device) {
443         int id = tcgetpgrp(fd);
444         if (id != pgrpid) {
445             syslog(LOG_WARNING, "warning: not in tty's process group");
446         }
447     } else {
448         if (tcsetpgrp(fd, pgrpid) < 0) {
449             syslog(LOG_ERR, "tcsetpgrp(): %m");
450             die(1);
451         }
452     }
453 #else
454     /* set process group on tty so we get SIGIO's */
455     if (ioctl(fd, TIOCSPGRP, &pgrpid) < 0) {
456         syslog(LOG_ERR, "ioctl(TIOCSPGRP): %m");
457         die(1);
458     }
459 #endif
460
461     /*
462      * Record initial device flags, then set device to cause SIGIO
463      * signals to be generated.
464      */
465     if ((initfdflags = fcntl(fd, F_GETFL)) == -1) {
466         syslog(LOG_ERR, "fcntl(F_GETFL): %m");
467         die(1);
468     }
469
470 #ifdef _linux_ /* This is a kludge for Linux. FIXME !!! -- later. */
471 #undef  FASYNC
472 #define FASYNC  0
473     {
474         int sig = SIGIO;
475         if (ioctl(fd, PPPIOCSINPSIG, &sig) == -1) {
476             syslog(LOG_ERR, "ioctl(PPPIOCSINPSIG): %m");
477             die(1);
478         }
479     }
480 #endif
481
482     if (fcntl(fd, F_SETFL, FNDELAY | FASYNC) == -1) {
483         syslog(LOG_ERR, "fcntl(F_SETFL, FNDELAY | FASYNC): %m");
484         die(1);
485     }
486   
487     /*
488      * Block all signals, start opening the connection, and  wait for
489      * incoming signals (reply, timeout, etc.).
490      */
491     syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devname);
492     sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */
493     lcp_lowerup(0);             /* XXX Well, sort of... */
494     lcp_open(0);                /* Start protocol */
495     for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; )
496         sigpause(0);            /* Wait for next signal */
497
498     /*
499      * Run disconnector script, if requested
500      */
501     if (disconnector) {
502         if (device_script(disconnector, fd, fd) < 0) {
503             syslog(LOG_WARNING, "disconnect script failed");
504             die(1);
505         }
506
507         syslog(LOG_INFO, "Disconnected...");
508     }
509
510     quit();
511 }
512
513 #if B9600 == 9600
514 /*
515  * XXX assume speed_t values numerically equal bits per second
516  * (so we can ask for any speed).
517  */
518 #define translate_speed(bps)    (bps)
519 #define baud_rate_of(speed)     (speed)
520
521 #else
522 /*
523  * List of valid speeds.
524  */
525 struct speed {
526     int speed_int, speed_val;
527 } speeds[] = {
528 #ifdef B50
529     { 50, B50 },
530 #endif
531 #ifdef B75
532     { 75, B75 },
533 #endif
534 #ifdef B110
535     { 110, B110 },
536 #endif
537 #ifdef B134
538     { 134, B134 },
539 #endif
540 #ifdef B150
541     { 150, B150 },
542 #endif
543 #ifdef B200
544     { 200, B200 },
545 #endif
546 #ifdef B300
547     { 300, B300 },
548 #endif
549 #ifdef B600
550     { 600, B600 },
551 #endif
552 #ifdef B1200
553     { 1200, B1200 },
554 #endif
555 #ifdef B1800
556     { 1800, B1800 },
557 #endif
558 #ifdef B2000
559     { 2000, B2000 },
560 #endif
561 #ifdef B2400
562     { 2400, B2400 },
563 #endif
564 #ifdef B3600
565     { 3600, B3600 },
566 #endif
567 #ifdef B4800
568     { 4800, B4800 },
569 #endif
570 #ifdef B7200
571     { 7200, B7200 },
572 #endif
573 #ifdef B9600
574     { 9600, B9600 },
575 #endif
576 #ifdef B19200
577     { 19200, B19200 },
578 #endif
579 #ifdef B38400
580     { 38400, B38400 },
581 #endif
582 #ifdef EXTA
583     { 19200, EXTA },
584 #endif
585 #ifdef EXTB
586     { 38400, EXTB },
587 #endif
588 #ifdef B57600
589     { 57600, B57600 },
590 #endif
591 #ifdef B115200
592     { 115200, B115200 },
593 #endif
594     { 0, 0 }
595 };
596
597 /*
598  * Translate from bits/second to a speed_t.
599  */
600 int
601 translate_speed(bps)
602     int bps;
603 {
604     struct speed *speedp;
605
606     if (bps == 0)
607         return 0;
608     for (speedp = speeds; speedp->speed_int; speedp++)
609         if (bps == speedp->speed_int)
610             return speedp->speed_val;
611     syslog(LOG_WARNING, "speed %d not supported", bps);
612     return 0;
613 }
614
615 /*
616  * Translate from a speed_t to bits/second.
617  */
618 int
619 baud_rate_of(speed)
620     int speed;
621 {
622     struct speed *speedp;
623
624     if (speed == 0)
625         return 0;
626     for (speedp = speeds; speedp->speed_int; speedp++)
627         if (speed == speedp->speed_val)
628             return speedp->speed_int;
629     return 0;
630 }
631 #endif
632
633 /*
634  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
635  * at the requested speed, etc.  If `local' is true, set CLOCAL
636  * regardless of whether the modem option was specified.
637  */
638 set_up_tty(fd, local)
639     int fd, local;
640 {
641 #ifndef SGTTY
642     int speed, x;
643     struct termios tios;
644
645     if (tcgetattr(fd, &tios) < 0) {
646         syslog(LOG_ERR, "tcgetattr: %m");
647         die(1);
648     }
649
650     if (!restore_term)
651         inittermios = tios;
652
653 #ifdef CRTSCTS
654     tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS);
655     if (crtscts == 1)
656         tios.c_cflag |= CRTSCTS;
657 #else
658     tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
659 #endif  /* CRTSCTS */
660
661     tios.c_cflag |= CS8 | CREAD | HUPCL;
662     if (local || !modem)
663         tios.c_cflag |= CLOCAL;
664     tios.c_iflag = IGNBRK | IGNPAR;
665     tios.c_oflag = 0;
666     tios.c_lflag = 0;
667     tios.c_cc[VMIN] = 1;
668     tios.c_cc[VTIME] = 0;
669
670     if (crtscts == 2) {
671         tios.c_iflag |= IXOFF;
672         tios.c_cc[VSTOP] = 0x13;        /* DC3 = XOFF = ^S */
673         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
674     }
675
676     speed = translate_speed(inspeed);
677     if (speed) {
678         cfsetospeed(&tios, speed);
679         cfsetispeed(&tios, speed);
680     } else {
681         speed = cfgetospeed(&tios);
682     }
683
684     if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
685         syslog(LOG_ERR, "tcsetattr: %m");
686         die(1);
687     }
688
689 #ifdef ultrix
690     x = 0;
691     if (ioctl(fd, (crtscts || modem)? TIOCMODEM: TIOCNMODEM, &x) < 0)
692         syslog(LOG_WARNING, "TIOC(N)MODEM: %m");
693     if (ioctl(fd, (local || !modem)? TIOCNCAR: TIOCCAR) < 0)
694         syslog(LOG_WARNING, "TIOC(N)CAR: %m");
695 #endif
696
697 #else   /* SGTTY */
698     int speed;
699     struct sgttyb sgttyb;
700
701     /*
702      * Put the tty in raw mode.
703      */
704     if (ioctl(fd, TIOCGETP, &sgttyb) < 0) {
705         syslog(LOG_ERR, "ioctl(TIOCGETP): %m");
706         die(1);
707     }
708
709     if (!restore_term)
710         initsgttyb = sgttyb;
711
712     sgttyb.sg_flags = RAW | ANYP;
713     speed = translate_speed(inspeed);
714     if (speed)
715         sgttyb.sg_ispeed = speed;
716     else
717         speed = sgttyb.sg_ispeed;
718
719     if (ioctl(fd, TIOCSETP, &sgttyb) < 0) {
720         syslog(LOG_ERR, "ioctl(TIOCSETP): %m");
721         die(1);
722     }
723 #endif
724
725     baud_rate = baud_rate_of(speed);
726     restore_term = TRUE;
727 }
728
729 /*
730  * setdtr - control the DTR line on the serial port.
731  * This is called from die(), so it shouldn't call die().
732  */
733 setdtr(fd, on)
734 int fd, on;
735 {
736     int modembits = TIOCM_DTR;
737
738     ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
739 }
740
741
742 /*
743  * quit - Clean up state and exit.
744  */
745 void 
746 quit()
747 {
748     die(0);
749 }
750
751 /*
752  * die - like quit, except we can specify an exit status.
753  */
754 void
755 die(status)
756     int status;
757 {
758     cleanup(0, NULL);
759     syslog(LOG_INFO, "Exit.");
760     exit(status);
761 }
762
763 /*
764  * cleanup - restore anything which needs to be restored before we exit
765  */
766 /* ARGSUSED */
767 void
768 cleanup(status, arg)
769     int status;
770     caddr_t arg;
771 {
772     if (fd >= 0) {
773         /* drop dtr to hang up */
774         if (modem)
775             setdtr(fd, FALSE);
776
777         if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
778             syslog(LOG_WARNING, "fcntl(F_SETFL, fdflags): %m");
779         initfdflags = -1;
780
781         disestablish_ppp();
782
783         if (restore_term) {
784 #ifndef SGTTY
785             if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
786                 syslog(LOG_WARNING, "tcsetattr: %m");
787 #else
788             if (ioctl(fd, TIOCSETP, &initsgttyb) < 0)
789                 syslog(LOG_WARNING, "ioctl(TIOCSETP): %m");
790 #endif
791         }
792
793         close(fd);
794         fd = -1;
795     }
796
797     if (pidfilename[0] != 0 && unlink(pidfilename) < 0) 
798         syslog(LOG_WARNING, "unable to unlink pid file: %m");
799     pidfilename[0] = 0;
800
801     if (lockflag && !default_device)
802         unlock();
803 }
804
805
806 static struct callout *callout = NULL;          /* Callout list */
807 static struct timeval schedtime;                /* Time last timeout was set */
808
809 /*
810  * timeout - Schedule a timeout.
811  *
812  * Note that this timeout takes the number of seconds, NOT hz (as in
813  * the kernel).
814  */
815 void
816 timeout(func, arg, time)
817     void (*func)();
818     caddr_t arg;
819     int time;
820 {
821     struct itimerval itv;
822     struct callout *newp, **oldpp;
823   
824     MAINDEBUG((LOG_DEBUG, "Timeout %x:%x in %d seconds.",
825                (int) func, (int) arg, time));
826   
827     /*
828      * Allocate timeout.
829      */
830     if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
831         syslog(LOG_ERR, "Out of memory in timeout()!");
832         die(1);
833     }
834     newp->c_arg = arg;
835     newp->c_func = func;
836   
837     /*
838      * Find correct place to link it in and decrement its time by the
839      * amount of time used by preceding timeouts.
840      */
841     for (oldpp = &callout;
842          *oldpp && (*oldpp)->c_time <= time;
843          oldpp = &(*oldpp)->c_next)
844         time -= (*oldpp)->c_time;
845     newp->c_time = time;
846     newp->c_next = *oldpp;
847     if (*oldpp)
848         (*oldpp)->c_time -= time;
849     *oldpp = newp;
850   
851     /*
852      * If this is now the first callout then we have to set a new
853      * itimer.
854      */
855     if (callout == newp) {
856         itv.it_interval.tv_sec = itv.it_interval.tv_usec =
857             itv.it_value.tv_usec = 0;
858         itv.it_value.tv_sec = callout->c_time;
859         MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in timeout.",
860                    itv.it_value.tv_sec));
861         if (setitimer(ITIMER_REAL, &itv, NULL)) {
862             syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
863             die(1);
864         }
865         if (gettimeofday(&schedtime, NULL)) {
866             syslog(LOG_ERR, "gettimeofday: %m");
867             die(1);
868         }
869     }
870 }
871
872
873 /*
874  * untimeout - Unschedule a timeout.
875  */
876 void
877 untimeout(func, arg)
878     void (*func)();
879     caddr_t arg;
880 {
881     struct itimerval itv;
882     struct callout **copp, *freep;
883     int reschedule = 0;
884   
885     MAINDEBUG((LOG_DEBUG, "Untimeout %x:%x.", (int) func, (int) arg));
886   
887     /*
888      * If the first callout is unscheduled then we have to set a new
889      * itimer.
890      */
891     if (callout &&
892         callout->c_func == func &&
893         callout->c_arg == arg)
894         reschedule = 1;
895   
896     /*
897      * Find first matching timeout.  Add its time to the next timeouts
898      * time.
899      */
900     for (copp = &callout; *copp; copp = &(*copp)->c_next)
901         if ((*copp)->c_func == func &&
902             (*copp)->c_arg == arg) {
903             freep = *copp;
904             *copp = freep->c_next;
905             if (*copp)
906                 (*copp)->c_time += freep->c_time;
907             (void) free((char *) freep);
908             break;
909         }
910   
911     if (reschedule) {
912         itv.it_interval.tv_sec = itv.it_interval.tv_usec =
913             itv.it_value.tv_usec = 0;
914         itv.it_value.tv_sec = callout ? callout->c_time : 0;
915         MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in untimeout.",
916                    itv.it_value.tv_sec));
917         if (setitimer(ITIMER_REAL, &itv, NULL)) {
918             syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
919             die(1);
920         }
921         if (gettimeofday(&schedtime, NULL)) {
922             syslog(LOG_ERR, "gettimeofday: %m");
923             die(1);
924         }
925     }
926 }
927
928
929 /*
930  * adjtimeout - Decrement the first timeout by the amount of time since
931  * it was scheduled.
932  */
933 void
934 adjtimeout()
935 {
936     struct timeval tv;
937     int timediff;
938   
939     if (callout == NULL)
940         return;
941     /*
942      * Make sure that the clock hasn't been warped dramatically.
943      * Account for recently expired, but blocked timer by adding
944      * small fudge factor.
945      */
946     if (gettimeofday(&tv, NULL)) {
947         syslog(LOG_ERR, "gettimeofday: %m");
948         die(1);
949     }
950     timediff = tv.tv_sec - schedtime.tv_sec;
951     if (timediff < 0 ||
952         timediff > callout->c_time + 1)
953         return;
954   
955     callout->c_time -= timediff;        /* OK, Adjust time */
956 }
957
958
959 /*
960  * hup - Catch SIGHUP signal.
961  *
962  * Indicates that the physical layer has been disconnected.
963  */
964 static void
965 hup(sig)
966     int sig;
967 {
968     syslog(LOG_INFO, "Hangup (SIGHUP)");
969
970     hungup = 1;                 /* they hung up on us! */
971     persist = 0;                /* don't try to restart */
972     adjtimeout();               /* Adjust timeouts */
973     lcp_lowerdown(0);           /* Reset connection */
974     quit();                     /* and die */
975 }
976
977
978 /*
979  * term - Catch SIGTERM signal.
980  *
981  * Indicates that we should initiate a graceful disconnect and exit.
982  */
983 static void
984 term(sig)
985     int sig;
986 {
987     syslog(LOG_INFO, "Terminating link.");
988     persist = 0;                /* don't try to restart */
989     adjtimeout();               /* Adjust timeouts */
990     lcp_close(0);               /* Close connection */
991 }
992
993
994 /*
995  * intr - Catch SIGINT signal (DEL/^C).
996  *
997  * Indicates that we should initiate a graceful disconnect and exit.
998  */
999 static void
1000 intr(sig)
1001     int sig;
1002 {
1003     syslog(LOG_INFO, "Interrupt received: terminating link");
1004     persist = 0;                /* don't try to restart */
1005     adjtimeout();               /* Adjust timeouts */
1006     lcp_close(0);               /* Close connection */
1007 }
1008
1009
1010 /*
1011  * alrm - Catch SIGALRM signal.
1012  *
1013  * Indicates a timeout.
1014  */
1015 static void
1016 alrm(sig)
1017     int sig;
1018 {
1019     struct itimerval itv;
1020     struct callout *freep, *list, *last;
1021
1022     MAINDEBUG((LOG_DEBUG, "Alarm"));
1023
1024     if (callout == NULL)
1025         return;
1026     /*
1027      * Get the first scheduled timeout and any that were scheduled
1028      * for the same time as a list, and remove them all from callout
1029      * list.
1030      */
1031     list = last = callout;
1032     while (last->c_next != NULL && last->c_next->c_time == 0)
1033         last = last->c_next;
1034     callout = last->c_next;
1035     last->c_next = NULL;
1036
1037     /*
1038      * Set a new itimer if there are more timeouts scheduled.
1039      */
1040     if (callout) {
1041         itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
1042         itv.it_value.tv_usec = 0;
1043         itv.it_value.tv_sec = callout->c_time;
1044         MAINDEBUG((LOG_DEBUG, "Setting itimer for %d seconds in alrm.",
1045                    itv.it_value.tv_sec));
1046         if (setitimer(ITIMER_REAL, &itv, NULL)) {
1047             syslog(LOG_ERR, "setitimer(ITIMER_REAL): %m");
1048             die(1);
1049         }
1050         if (gettimeofday(&schedtime, NULL)) {
1051             syslog(LOG_ERR, "gettimeofday: %m");
1052             die(1);
1053         }
1054     }
1055
1056     /*
1057      * Now call all the timeout routines scheduled for this time.
1058      */
1059     while (list) {
1060         (*list->c_func)(list->c_arg);
1061         freep = list;
1062         list = list->c_next;
1063         (void) free((char *) freep);
1064     }
1065   
1066 }
1067
1068
1069 /*
1070  * chld - Catch SIGCHLD signal.
1071  * Calls reap_kids to get status for any dead kids.
1072  */
1073 static void
1074 chld(sig)
1075     int sig;
1076 {
1077     reap_kids();
1078 }
1079
1080
1081 /*
1082  * io - Catch SIGIO signal.
1083  *
1084  * Indicates that incoming data is available.
1085  */
1086 static void
1087 io(sig)
1088     int sig;
1089 {
1090     int len, i;
1091     u_char *p;
1092     u_short protocol;
1093     fd_set fdset;
1094     struct timeval notime;
1095     int ready;
1096
1097     MAINDEBUG((LOG_DEBUG, "IO signal received"));
1098     adjtimeout();               /* Adjust timeouts */
1099
1100     /* Yup, this is for real */
1101     for (;;) {                  /* Read all available packets */
1102         p = inpacket_buf;       /* point to beginning of packet buffer */
1103
1104         len = read_packet(inpacket_buf);
1105         if (len < 0)
1106             return;
1107
1108         if (len == 0) {
1109             MAINDEBUG((LOG_DEBUG, "End of file on fd!"));
1110             lcp_lowerdown(0);
1111             return;
1112         }
1113
1114         if (debug /*&& (debugflags & DBG_INPACKET)*/)
1115             log_packet(p, len, "rcvd ");
1116
1117         if (len < DLLHEADERLEN) {
1118             MAINDEBUG((LOG_INFO, "io(): Received short packet."));
1119             return;
1120         }
1121
1122         p += 2;                         /* Skip address and control */
1123         GETSHORT(protocol, p);
1124         len -= DLLHEADERLEN;
1125
1126         /*
1127          * Toss all non-LCP packets unless LCP is OPEN.
1128          */
1129         if (protocol != LCP && lcp_fsm[0].state != OPENED) {
1130             MAINDEBUG((LOG_INFO,
1131                        "io(): Received non-LCP packet when LCP not open."));
1132             return;
1133         }
1134
1135         /*
1136          * Upcall the proper protocol input routine.
1137          */
1138         for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
1139             if (prottbl[i].protocol == protocol) {
1140                 (*prottbl[i].input)(0, p, len);
1141                 break;
1142             }
1143
1144         if (i == sizeof (prottbl) / sizeof (struct protent)) {
1145             syslog(LOG_WARNING, "input: Unknown protocol (%x) received!",
1146                    protocol);
1147             lcp_sprotrej(0, p - DLLHEADERLEN, len + DLLHEADERLEN);
1148         }
1149     }
1150 }
1151
1152 /*
1153  * demuxprotrej - Demultiplex a Protocol-Reject.
1154  */
1155 void
1156 demuxprotrej(unit, protocol)
1157     int unit;
1158     u_short protocol;
1159 {
1160     int i;
1161
1162     /*
1163      * Upcall the proper Protocol-Reject routine.
1164      */
1165     for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
1166         if (prottbl[i].protocol == protocol) {
1167             (*prottbl[i].protrej)(unit);
1168             return;
1169         }
1170
1171     syslog(LOG_WARNING,
1172            "demuxprotrej: Unrecognized Protocol-Reject for protocol %d!",
1173            protocol);
1174 }
1175
1176
1177 /*
1178  * incdebug - Catch SIGUSR1 signal.
1179  *
1180  * Increment debug flag.
1181  */
1182 /*ARGSUSED*/
1183 static void
1184 incdebug(sig)
1185     int sig;
1186 {
1187     syslog(LOG_INFO, "Debug turned ON, Level %d", debug);
1188     setlogmask(LOG_UPTO(LOG_DEBUG));
1189     debug++;
1190 }
1191
1192
1193 /*
1194  * nodebug - Catch SIGUSR2 signal.
1195  *
1196  * Turn off debugging.
1197  */
1198 /*ARGSUSED*/
1199 static void
1200 nodebug(sig)
1201     int sig;
1202 {
1203     setlogmask(LOG_UPTO(LOG_WARNING));
1204     debug = 0;
1205 }
1206
1207
1208 /*
1209  * device_script - run a program to connect or disconnect the
1210  * serial device.
1211  */
1212 int
1213 device_script(program, in, out)
1214     char *program;
1215     int in, out;
1216 {
1217     int pid;
1218     int status;
1219     sigset_t mask;
1220
1221     sigemptyset(&mask);
1222     sigaddset(&mask, SIGINT);
1223     sigaddset(&mask, SIGHUP);
1224     sigprocmask(SIG_BLOCK, &mask, &mask);
1225
1226     pid = fork();
1227
1228     if (pid < 0) {
1229         syslog(LOG_ERR, "fork: %m");
1230         die(1);
1231     }
1232
1233     if (pid == 0) {
1234         setreuid(getuid(), getuid());
1235         setregid(getgid(), getgid());
1236         sigprocmask(SIG_SETMASK, &mask, NULL);
1237         dup2(in, 0);
1238         dup2(out, 1);
1239         execl("/bin/sh", "sh", "-c", program, (char *)0);
1240         syslog(LOG_ERR, "could not exec /bin/sh: %m");
1241         _exit(99);
1242         /* NOTREACHED */
1243     }
1244
1245     while (waitpid(pid, &status, 0) < 0) {
1246         if (errno == EINTR)
1247             continue;
1248         syslog(LOG_ERR, "waiting for (dis)connection process: %m");
1249         die(1);
1250     }
1251     sigprocmask(SIG_SETMASK, &mask, NULL);
1252
1253     return (status == 0 ? 0 : -1);
1254 }
1255
1256
1257 /*
1258  * run-program - execute a program with given arguments,
1259  * but don't wait for it.
1260  * If the program can't be executed, logs an error unless
1261  * must_exist is 0 and the program file doesn't exist.
1262  */
1263 int
1264 run_program(prog, args, must_exist)
1265     char *prog;
1266     char **args;
1267     int must_exist;
1268 {
1269     int pid;
1270
1271     pid = fork();
1272     if (pid == -1) {
1273         syslog(LOG_ERR, "can't fork to run %s: %m", prog);
1274         return -1;
1275     }
1276     if (pid == 0) {
1277         execv(prog, args);
1278         if (must_exist || errno != ENOENT)
1279             syslog(LOG_WARNING, "can't execute %s: %m", prog);
1280         _exit(-1);
1281     }
1282     MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid));
1283     ++n_children;
1284     return 0;
1285 }
1286
1287
1288 /*
1289  * reap_kids - get status from any dead child processes,
1290  * and log a message for abnormal terminations.
1291  */
1292 void
1293 reap_kids()
1294 {
1295     int pid, status;
1296
1297     if (n_children == 0)
1298         return;
1299     if ((pid = waitpid(-1, &status, WNOHANG)) == -1) {
1300         if (errno != ECHILD)
1301             syslog(LOG_ERR, "waitpid: %m");
1302         return;
1303     }
1304     if (pid > 0) {
1305         --n_children;
1306         if (WIFSIGNALED(status)) {
1307             syslog(LOG_WARNING, "child process %d terminated with signal %d",
1308                    pid, WTERMSIG(status));
1309         }
1310     }
1311 }
1312
1313
1314 /*
1315  * log_packet - format a packet and log it.
1316  */
1317
1318 char line[256];                 /* line to be logged accumulated here */
1319 char *linep;
1320
1321 void
1322 log_packet(p, len, prefix)
1323     u_char *p;
1324     int len;
1325     char *prefix;
1326 {
1327     strcpy(line, prefix);
1328     linep = line + strlen(line);
1329     format_packet(p, len, pr_log, NULL);
1330     if (linep != line)
1331         syslog(LOG_DEBUG, "%s", line);
1332 }
1333
1334 /*
1335  * format_packet - make a readable representation of a packet,
1336  * calling `printer(arg, format, ...)' to output it.
1337  */
1338 void
1339 format_packet(p, len, printer, arg)
1340     u_char *p;
1341     int len;
1342     void (*printer) __ARGS((void *, char *, ...));
1343     void *arg;
1344 {
1345     int i, n;
1346     u_short proto;
1347     u_char x;
1348
1349     if (len >= DLLHEADERLEN && p[0] == ALLSTATIONS && p[1] == UI) {
1350         p += 2;
1351         GETSHORT(proto, p);
1352         len -= DLLHEADERLEN;
1353         for (i = 0; i < N_PROTO; ++i)
1354             if (proto == prottbl[i].protocol)
1355                 break;
1356         if (i < N_PROTO) {
1357             printer(arg, "[%s", prottbl[i].name);
1358             n = (*prottbl[i].printpkt)(p, len, printer, arg);
1359             printer(arg, "]");
1360             p += n;
1361             len -= n;
1362         } else {
1363             printer(arg, "[proto=0x%x]", proto);
1364         }
1365     }
1366
1367     for (; len > 0; --len) {
1368         GETCHAR(x, p);
1369         printer(arg, " %.2x", x);
1370     }
1371 }
1372
1373 #ifdef __STDC__
1374 #include <stdarg.h>
1375
1376 void
1377 pr_log(void *arg, char *fmt, ...)
1378 {
1379     int n;
1380     va_list pvar;
1381     char buf[256];
1382
1383     va_start(pvar, fmt);
1384     vsprintf(buf, fmt, pvar);
1385     va_end(pvar);
1386
1387     n = strlen(buf);
1388     if (linep + n + 1 > line + sizeof(line)) {
1389         syslog(LOG_DEBUG, "%s", line);
1390         linep = line;
1391     }
1392     strcpy(linep, buf);
1393     linep += n;
1394 }
1395
1396 #else /* __STDC__ */
1397 #include <varargs.h>
1398
1399 void
1400 pr_log(arg, fmt, va_alist)
1401 void *arg;
1402 char *fmt;
1403 va_dcl
1404 {
1405     int n;
1406     va_list pvar;
1407     char buf[256];
1408
1409     va_start(pvar);
1410     vsprintf(buf, fmt, pvar);
1411     va_end(pvar);
1412
1413     n = strlen(buf);
1414     if (linep + n + 1 > line + sizeof(line)) {
1415         syslog(LOG_DEBUG, "%s", line);
1416         linep = line;
1417     }
1418     strcpy(linep, buf);
1419     linep += n;
1420 }
1421 #endif
1422
1423 /*
1424  * print_string - print a readable representation of a string using
1425  * printer.
1426  */
1427 void
1428 print_string(p, len, printer, arg)
1429     char *p;
1430     int len;
1431     void (*printer) __ARGS((void *, char *, ...));
1432     void *arg;
1433 {
1434     int c;
1435
1436     printer(arg, "\"");
1437     for (; len > 0; --len) {
1438         c = *p++;
1439         if (' ' <= c && c <= '~')
1440             printer(arg, "%c", c);
1441         else
1442             printer(arg, "\\%.3o", c);
1443     }
1444     printer(arg, "\"");
1445 }
1446
1447 /*
1448  * novm - log an error message saying we ran out of memory, and die.
1449  */
1450 void
1451 novm(msg)
1452     char *msg;
1453 {
1454     syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
1455     die(1);
1456 }