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