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