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