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