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