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