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