]> git.ozlabs.org Git - ppp.git/blob - pppd/main.c
remove bpf options, added info about new options and auth-up/down scripts
[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.34 1996/07/01 01:17:39 paulus Exp $";
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.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/param.h>
36 #include <sys/types.h>
37 #include <sys/wait.h>
38 #include <sys/time.h>
39 #include <sys/resource.h>
40 #include <sys/stat.h>
41 #include <sys/socket.h>
42 #include <net/if.h>
43
44 #include "pppd.h"
45 #include "magic.h"
46 #include "fsm.h"
47 #include "lcp.h"
48 #include "ipcp.h"
49 #include "upap.h"
50 #include "chap.h"
51 #include "ccp.h"
52 #include "pathnames.h"
53 #include "patchlevel.h"
54
55 #if defined(SUNOS4)
56 extern char *strerror();
57 #endif
58
59 #ifdef IPX_CHANGE
60 #include "ipxcp.h"
61 #endif /* IPX_CHANGE */
62
63 /*
64  * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless
65  * /etc/ppp/options exists.
66  */
67 #ifndef REQ_SYSOPTIONS
68 #define REQ_SYSOPTIONS  1
69 #endif
70
71 /* interface vars */
72 char ifname[IFNAMSIZ];          /* Interface name */
73 int ifunit;                     /* Interface unit number */
74
75 char *progname;                 /* Name of this program */
76 char hostname[MAXNAMELEN];      /* Our hostname */
77 static char pidfilename[MAXPATHLEN];    /* name of pid file */
78 static char default_devnam[MAXPATHLEN]; /* name of default device */
79 static pid_t pid;               /* Our pid */
80 static uid_t uid;               /* Our real user-id */
81
82 int ttyfd = -1;                 /* Serial port file descriptor */
83 mode_t tty_mode = -1;           /* Original access permissions to tty */
84 int baud_rate;                  /* Actual bits/second for serial device */
85 int hungup;                     /* terminal has been hung up */
86
87 int phase;                      /* where the link is at */
88 int kill_link;
89 int open_ccp_flag;
90 int redirect_stderr;            /* Connector's stderr should go to file */
91
92 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
93 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
94
95 static int n_children;          /* # child processes still running */
96
97 static int locked;              /* lock() has succeeded */
98
99 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
100
101 /* Prototypes for procedures local to this file. */
102
103 static void cleanup __P((void));
104 static void close_tty __P((void));
105 static void get_input __P((void));
106 static void connect_time_expired __P((caddr_t));
107 static void calltimeout __P((void));
108 static struct timeval *timeleft __P((struct timeval *));
109 static void hup __P((int));
110 static void term __P((int));
111 static void chld __P((int));
112 static void toggle_debug __P((int));
113 static void open_ccp __P((int));
114 static void bad_signal __P((int));
115 static void holdoff_end __P((void *));
116 static int device_script __P((char *, int, int));
117 static void reap_kids __P((void));
118 static void pr_log __P((void *, char *, ...));
119
120 extern  char    *ttyname __P((int));
121 extern  char    *getlogin __P((void));
122
123 #ifdef ultrix
124 #undef  O_NONBLOCK
125 #define O_NONBLOCK      O_NDELAY
126 #endif
127
128 #ifdef PRIMITIVE_SYSLOG
129 #define setlogmask(x)
130 #endif
131
132 /*
133  * PPP Data Link Layer "protocol" table.
134  * One entry per supported protocol.
135  * The last entry must be NULL.
136  */
137 struct protent *protocols[] = {
138     &lcp_protent,
139     &pap_protent,
140     &chap_protent,
141     &ipcp_protent,
142     &ccp_protent,
143 #ifdef IPX_CHANGE
144     &ipxcp_protent,
145 #endif
146     NULL
147 };
148
149 int
150 main(argc, argv)
151     int argc;
152     char *argv[];
153 {
154     int i, nonblock, fdflags;
155     struct sigaction sa;
156     FILE *pidfile;
157     char *p;
158     struct passwd *pw;
159     struct timeval timo;
160     sigset_t mask;
161     struct protent *protp;
162     struct stat statbuf;
163
164     phase = PHASE_INITIALIZE;
165     p = ttyname(0);
166     if (p)
167         strcpy(devnam, p);
168     strcpy(default_devnam, devnam);
169
170     /* Initialize syslog facilities */
171 #ifdef PRIMITIVE_SYSLOG
172     openlog("pppd", LOG_PID);
173 #else
174     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
175     setlogmask(LOG_UPTO(LOG_INFO));
176 #endif
177
178     if (gethostname(hostname, MAXNAMELEN) < 0 ) {
179         syslog(LOG_ERR, "couldn't get hostname: %m");
180         die(1);
181     }
182     hostname[MAXNAMELEN-1] = 0;
183
184     uid = getuid();
185
186     /*
187      * Initialize to the standard option set, then parse, in order,
188      * the system options file, the user's options file,
189      * the tty's options file, and the command line arguments.
190      */
191     for (i = 0; (protp = protocols[i]) != NULL; ++i)
192         (*protp->init)(0);
193   
194     progname = *argv;
195
196     if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0)
197         || !options_from_user())
198         exit(1);
199     scan_args(argc-1, argv+1);  /* look for tty name on command line */
200     if (!options_for_tty()
201         || !parse_args(argc-1, argv+1))
202         exit(1);
203
204     if (!ppp_available()) {
205         fprintf(stderr, no_ppp_msg);
206         exit(1);
207     }
208
209     /*
210      * Check that the options given are valid and consistent.
211      */
212     sys_check_options();
213     auth_check_options();
214     for (i = 0; (protp = protocols[i]) != NULL; ++i)
215         if (protp->check_options != NULL)
216             (*protp->check_options)();
217     if (demand && connector == 0) {
218         fprintf(stderr, "%s: connect script required for demand-dialling\n",
219                 progname);
220         exit(1);
221     }
222
223     /*
224      * If the user has specified the default device name explicitly,
225      * pretend they hadn't.
226      */
227     if (!default_device && strcmp(devnam, default_devnam) == 0)
228         default_device = 1;
229     redirect_stderr = !nodetach || default_device;
230
231     /*
232      * Initialize system-dependent stuff and magic number package.
233      */
234     sys_init();
235     magic_init();
236     if (debug)
237         setlogmask(LOG_UPTO(LOG_DEBUG));
238
239     /*
240      * Detach ourselves from the terminal, if required,
241      * and identify who is running us.
242      */
243     if (!default_device && !nodetach && daemon(0, 0) < 0) {
244         perror("Couldn't detach from controlling terminal");
245         exit(1);
246     }
247     pid = getpid();
248     p = getlogin();
249     if (p == NULL) {
250         pw = getpwuid(uid);
251         if (pw != NULL && pw->pw_name != NULL)
252             p = pw->pw_name;
253         else
254             p = "(unknown)";
255     }
256     syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d",
257            VERSION, PATCHLEVEL, p, uid);
258   
259     /*
260      * Compute mask of all interesting signals and install signal handlers
261      * for each.  Only one signal handler may be active at a time.  Therefore,
262      * all other signals should be masked when any handler is executing.
263      */
264     sigemptyset(&mask);
265     sigaddset(&mask, SIGHUP);
266     sigaddset(&mask, SIGINT);
267     sigaddset(&mask, SIGTERM);
268     sigaddset(&mask, SIGCHLD);
269
270 #define SIGNAL(s, handler)      { \
271         sa.sa_handler = handler; \
272         if (sigaction(s, &sa, NULL) < 0) { \
273             syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \
274             die(1); \
275         } \
276     }
277
278     sa.sa_mask = mask;
279     sa.sa_flags = 0;
280     SIGNAL(SIGHUP, hup);                /* Hangup */
281     SIGNAL(SIGINT, term);               /* Interrupt */
282     SIGNAL(SIGTERM, term);              /* Terminate */
283     SIGNAL(SIGCHLD, chld);
284
285     SIGNAL(SIGUSR1, toggle_debug);      /* Toggle debug flag */
286     SIGNAL(SIGUSR2, open_ccp);          /* Reopen CCP */
287
288     /*
289      * Install a handler for other signals which would otherwise
290      * cause pppd to exit without cleaning up.
291      */
292     SIGNAL(SIGABRT, bad_signal);
293     SIGNAL(SIGALRM, bad_signal);
294     SIGNAL(SIGFPE, bad_signal);
295     SIGNAL(SIGILL, bad_signal);
296     SIGNAL(SIGPIPE, bad_signal);
297     SIGNAL(SIGQUIT, bad_signal);
298     SIGNAL(SIGSEGV, bad_signal);
299 #ifdef SIGBUS
300     SIGNAL(SIGBUS, bad_signal);
301 #endif
302 #ifdef SIGEMT
303     SIGNAL(SIGEMT, bad_signal);
304 #endif
305 #ifdef SIGPOLL
306     SIGNAL(SIGPOLL, bad_signal);
307 #endif
308 #ifdef SIGPROF
309     SIGNAL(SIGPROF, bad_signal);
310 #endif
311 #ifdef SIGSYS
312     SIGNAL(SIGSYS, bad_signal);
313 #endif
314 #ifdef SIGTRAP
315     SIGNAL(SIGTRAP, bad_signal);
316 #endif
317 #ifdef SIGVTALRM
318     SIGNAL(SIGVTALRM, bad_signal);
319 #endif
320 #ifdef SIGXCPU
321     SIGNAL(SIGXCPU, bad_signal);
322 #endif
323 #ifdef SIGXFSZ
324     SIGNAL(SIGXFSZ, bad_signal);
325 #endif
326
327     /*
328      * Apparently we can get a SIGPIPE when we call syslog, if
329      * syslogd has died and been restarted.  Ignoring it seems
330      * be sufficient.
331      */
332     signal(SIGPIPE, SIG_IGN);
333
334     /*
335      * If we're doing dial-on-demand, set up the interface now.
336      */
337     if (demand) {
338         /*
339          * Open the loopback channel and set it up to be the ppp interface.
340          */
341         open_ppp_loopback();
342
343         syslog(LOG_INFO, "Using interface ppp%d", ifunit);
344         (void) sprintf(ifname, "ppp%d", ifunit);
345
346         /* write pid to file */
347         (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
348         if ((pidfile = fopen(pidfilename, "w")) != NULL) {
349             fprintf(pidfile, "%d\n", pid);
350             (void) fclose(pidfile);
351         } else {
352             syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename);
353             pidfilename[0] = 0;
354         }
355
356         /*
357          * Configure the interface and mark it up, etc.
358          */
359         demand_conf();
360     }
361
362     for (;;) {
363
364         if (demand) {
365             /*
366              * Don't do anything until we see some activity.
367              */
368             phase = PHASE_DORMANT;
369             kill_link = 0;
370             demand_unblock();
371             for (;;) {
372                 wait_loop_output(timeleft(&timo));
373                 calltimeout();
374                 if (kill_link) {
375                     if (!persist)
376                         die(0);
377                     kill_link = 0;
378                 }
379                 if (get_loop_output())
380                     break;
381                 reap_kids();
382             }
383
384             /*
385              * Now we want to bring up the link.
386              */
387             demand_block();
388             syslog(LOG_INFO, "Starting link");
389         }
390
391         /*
392          * Lock the device if we've been asked to.
393          */
394         if (lockflag && !default_device) {
395             if (lock(devnam) < 0)
396                 goto fail;
397             locked = 1;
398         }
399
400         /*
401          * Open the serial device and set it up to be the ppp interface.
402          * If we're dialling out, or we don't want to use the modem lines,
403          * we open it in non-blocking mode, but then we need to clear
404          * the non-blocking I/O bit.
405          */
406         nonblock = (connector || !modem)? O_NONBLOCK: 0;
407         if ((ttyfd = open(devnam, nonblock | O_RDWR, 0)) < 0) {
408             syslog(LOG_ERR, "Failed to open %s: %m", devnam);
409             goto fail;
410         }
411         if (nonblock) {
412             if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
413                 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
414                 syslog(LOG_WARNING,
415                        "Couldn't reset non-blocking mode on device: %m");
416         }
417         hungup = 0;
418         kill_link = 0;
419
420         /*
421          * Do the equivalent of `mesg n' to stop broadcast messages.
422          */
423         if (fstat(ttyfd, &statbuf) < 0
424             || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
425             syslog(LOG_WARNING,
426                    "Couldn't restrict write permissions to %s: %m", devnam);
427         } else
428             tty_mode = statbuf.st_mode;
429
430         /* run connection script */
431         if (connector && connector[0]) {
432             MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
433
434             /* set line speed, flow control, etc.; set CLOCAL for now */
435             set_up_tty(ttyfd, 1);
436
437             /* drop dtr to hang up in case modem is off hook */
438             if (!default_device && modem) {
439                 setdtr(ttyfd, FALSE);
440                 sleep(1);
441                 setdtr(ttyfd, TRUE);
442             }
443
444             if (device_script(connector, ttyfd, ttyfd) < 0) {
445                 syslog(LOG_ERR, "Connect script failed");
446                 setdtr(ttyfd, FALSE);
447                 goto fail;
448             }
449
450             syslog(LOG_INFO, "Serial connection established.");
451             sleep(1);           /* give it time to set up its terminal */
452         }
453
454         /* set line speed, flow control, etc.; clear CLOCAL if modem option */
455         set_up_tty(ttyfd, 0);
456
457         /* run welcome script, if any */
458         if (welcomer && welcomer[0]) {
459             if (device_script(welcomer, ttyfd, ttyfd) < 0)
460                 syslog(LOG_WARNING, "Welcome script failed");
461         }
462
463         /* set up the serial device as a ppp interface */
464         establish_ppp(ttyfd);
465
466         if (!demand) {
467             
468             syslog(LOG_INFO, "Using interface ppp%d", ifunit);
469             (void) sprintf(ifname, "ppp%d", ifunit);
470             
471             /* write pid to file */
472             (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
473             if ((pidfile = fopen(pidfilename, "w")) != NULL) {
474                 fprintf(pidfile, "%d\n", pid);
475                 (void) fclose(pidfile);
476             } else {
477                 syslog(LOG_ERR, "Failed to create pid file %s: %m",
478                        pidfilename);
479                 pidfilename[0] = 0;
480             }
481         }
482
483         /*
484          * Set a timeout to close the connection once the maximum
485          * connect time has expired.
486          */
487         if (maxconnect > 0)
488             TIMEOUT(connect_time_expired, 0, maxconnect);
489
490         /*
491          * Start opening the connection and wait for
492          * incoming events (reply, timeout, etc.).
493          */
494         syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam);
495         lcp_lowerup(0);
496         lcp_open(0);            /* Start protocol */
497         for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
498             wait_input(timeleft(&timo));
499             calltimeout();
500             get_input();
501             if (kill_link) {
502                 lcp_close(0, "User request");
503                 kill_link = 0;
504             }
505             if (open_ccp_flag) {
506                 if (phase == PHASE_NETWORK) {
507                     ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
508                     (*ccp_protent.open)(0);
509                 }
510                 open_ccp_flag = 0;
511             }
512             reap_kids();        /* Don't leave dead kids lying around */
513         }
514
515         /*
516          * If we may want to bring the link up again, transfer
517          * the ppp unit back to the loopback.  Set the
518          * real serial device back to its normal mode of operation.
519          */
520         clean_check();
521 #ifdef _linux_
522         disestablish_ppp(ttyfd);
523 #endif
524         if (demand)
525             restore_loop();
526 #ifndef _linux_
527         disestablish_ppp(ttyfd);
528 #endif
529
530         /*
531          * Run disconnector script, if requested.
532          * XXX we may not be able to do this if the line has hung up!
533          */
534         if (disconnector && !hungup) {
535             set_up_tty(ttyfd, 1);
536             if (device_script(disconnector, ttyfd, ttyfd) < 0) {
537                 syslog(LOG_WARNING, "disconnect script failed");
538             } else {
539                 syslog(LOG_INFO, "Serial link disconnected.");
540             }
541         }
542
543     fail:
544         close_tty();
545         if (locked) {
546             unlock();
547             locked = 0;
548         }
549
550         if (!demand) {
551             if (pidfilename[0] != 0
552                 && unlink(pidfilename) < 0 && errno != ENOENT) 
553                 syslog(LOG_WARNING, "unable to delete pid file: %m");
554             pidfilename[0] = 0;
555         }
556
557         if (!persist)
558             break;
559
560         if (demand)
561             demand_discard();
562         if (holdoff > 0) {
563             phase = PHASE_HOLDOFF;
564             TIMEOUT(holdoff_end, NULL, holdoff);
565             do {
566                 wait_time(timeleft(&timo));
567                 calltimeout();
568                 if (kill_link) {
569                     if (!persist)
570                         die(0);
571                     kill_link = 0;
572                     phase = PHASE_DORMANT; /* allow signal to end holdoff */
573                 }
574                 reap_kids();
575             } while (phase == PHASE_HOLDOFF);
576         }
577     }
578
579     die(0);
580 }
581
582 /*
583  * holdoff_end - called via a timeout when the holdoff period ends.
584  */
585 static void
586 holdoff_end(arg)
587     void *arg;
588 {
589     phase = PHASE_DORMANT;
590 }
591
592 /*
593  * get_input - called when incoming data is available.
594  */
595 static void
596 get_input()
597 {
598     int len, i;
599     u_char *p;
600     u_short protocol;
601     struct protent *protp;
602
603     p = inpacket_buf;   /* point to beginning of packet buffer */
604
605     len = read_packet(inpacket_buf);
606     if (len < 0)
607         return;
608
609     if (len == 0) {
610         syslog(LOG_NOTICE, "Modem hangup");
611         hungup = 1;
612         lcp_lowerdown(0);       /* serial link is no longer available */
613         link_terminated(0);
614         return;
615     }
616
617     if (debug /*&& (debugflags & DBG_INPACKET)*/)
618         log_packet(p, len, "rcvd ");
619
620     if (len < PPP_HDRLEN) {
621         MAINDEBUG((LOG_INFO, "io(): Received short packet."));
622         return;
623     }
624
625     p += 2;                             /* Skip address and control */
626     GETSHORT(protocol, p);
627     len -= PPP_HDRLEN;
628
629     /*
630      * Toss all non-LCP packets unless LCP is OPEN.
631      */
632     if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
633         MAINDEBUG((LOG_INFO,
634                    "io(): Received non-LCP packet when LCP not open."));
635         return;
636     }
637
638     /*
639      * Upcall the proper protocol input routine.
640      */
641     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
642         if (protp->protocol == protocol && protp->enabled_flag) {
643             (*protp->input)(0, p, len);
644             return;
645         }
646         if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
647             && protp->datainput != NULL) {
648             (*protp->datainput)(0, p, len);
649             return;
650         }
651     }
652
653     if (debug)
654         syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol);
655     lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
656 }
657
658
659 /*
660  * quit - Clean up state and exit (with an error indication).
661  */
662 void 
663 quit()
664 {
665     die(1);
666 }
667
668 /*
669  * die - like quit, except we can specify an exit status.
670  */
671 void
672 die(status)
673     int status;
674 {
675     cleanup();
676     syslog(LOG_INFO, "Exit.");
677     exit(status);
678 }
679
680 /*
681  * connect_time_expired - log a message and close the connection.
682  */
683 static void
684 connect_time_expired(arg)
685     caddr_t arg;
686 {
687     syslog(LOG_INFO, "Connect time expired");
688     lcp_close(0, "Connect time expired");       /* Close connection */
689 }
690
691 /*
692  * cleanup - restore anything which needs to be restored before we exit
693  */
694 /* ARGSUSED */
695 static void
696 cleanup()
697 {
698     sys_cleanup();
699
700     if (ttyfd >= 0)
701         close_tty();
702
703     if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) 
704         syslog(LOG_WARNING, "unable to delete pid file: %m");
705     pidfilename[0] = 0;
706
707     if (locked)
708         unlock();
709 }
710
711 /*
712  * close_tty - restore the terminal device and close it.
713  */
714 static void
715 close_tty()
716 {
717     disestablish_ppp(ttyfd);
718
719     /* drop dtr to hang up */
720     if (modem) {
721         setdtr(ttyfd, FALSE);
722         /*
723          * This sleep is in case the serial port has CLOCAL set by default,
724          * and consequently will reassert DTR when we close the device.
725          */
726         sleep(1);
727     }
728
729     restore_tty(ttyfd);
730
731     if (tty_mode != (mode_t) -1)
732         chmod(devnam, tty_mode);
733
734     close(ttyfd);
735     ttyfd = -1;
736 }
737
738
739 struct  callout {
740     struct timeval      c_time;         /* time at which to call routine */
741     caddr_t             c_arg;          /* argument to routine */
742     void                (*c_func)();    /* routine */
743     struct              callout *c_next;
744 };
745
746 static struct callout *callout = NULL;  /* Callout list */
747 static struct timeval timenow;          /* Current time */
748
749 /*
750  * timeout - Schedule a timeout.
751  *
752  * Note that this timeout takes the number of seconds, NOT hz (as in
753  * the kernel).
754  */
755 void
756 timeout(func, arg, time)
757     void (*func)();
758     caddr_t arg;
759     int time;
760 {
761     struct callout *newp, *p, **pp;
762   
763     MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.",
764                (long) func, (long) arg, time));
765   
766     /*
767      * Allocate timeout.
768      */
769     if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
770         syslog(LOG_ERR, "Out of memory in timeout()!");
771         die(1);
772     }
773     newp->c_arg = arg;
774     newp->c_func = func;
775     gettimeofday(&timenow, NULL);
776     newp->c_time.tv_sec = timenow.tv_sec + time;
777     newp->c_time.tv_usec = timenow.tv_usec;
778   
779     /*
780      * Find correct place and link it in.
781      */
782     for (pp = &callout; (p = *pp); pp = &p->c_next)
783         if (newp->c_time.tv_sec < p->c_time.tv_sec
784             || (newp->c_time.tv_sec == p->c_time.tv_sec
785                 && newp->c_time.tv_usec < p->c_time.tv_sec))
786             break;
787     newp->c_next = p;
788     *pp = newp;
789 }
790
791
792 /*
793  * untimeout - Unschedule a timeout.
794  */
795 void
796 untimeout(func, arg)
797     void (*func)();
798     caddr_t arg;
799 {
800     struct callout **copp, *freep;
801   
802     MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg));
803   
804     /*
805      * Find first matching timeout and remove it from the list.
806      */
807     for (copp = &callout; (freep = *copp); copp = &freep->c_next)
808         if (freep->c_func == func && freep->c_arg == arg) {
809             *copp = freep->c_next;
810             (void) free((char *) freep);
811             break;
812         }
813 }
814
815
816 /*
817  * calltimeout - Call any timeout routines which are now due.
818  */
819 static void
820 calltimeout()
821 {
822     struct callout *p;
823
824     while (callout != NULL) {
825         p = callout;
826
827         if (gettimeofday(&timenow, NULL) < 0) {
828             syslog(LOG_ERR, "Failed to get time of day: %m");
829             die(1);
830         }
831         if (!(p->c_time.tv_sec < timenow.tv_sec
832               || (p->c_time.tv_sec == timenow.tv_sec
833                   && p->c_time.tv_usec <= timenow.tv_usec)))
834             break;              /* no, it's not time yet */
835
836         callout = p->c_next;
837         (*p->c_func)(p->c_arg);
838
839         free((char *) p);
840     }
841 }
842
843
844 /*
845  * timeleft - return the length of time until the next timeout is due.
846  */
847 static struct timeval *
848 timeleft(tvp)
849     struct timeval *tvp;
850 {
851     if (callout == NULL)
852         return NULL;
853
854     gettimeofday(&timenow, NULL);
855     tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
856     tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
857     if (tvp->tv_usec < 0) {
858         tvp->tv_usec += 1000000;
859         tvp->tv_sec -= 1;
860     }
861     if (tvp->tv_sec < 0)
862         tvp->tv_sec = tvp->tv_usec = 0;
863
864     return tvp;
865 }
866     
867
868 /*
869  * hup - Catch SIGHUP signal.
870  *
871  * Indicates that the physical layer has been disconnected.
872  * We don't rely on this indication; if the user has sent this
873  * signal, we just take the link down.
874  */
875 static void
876 hup(sig)
877     int sig;
878 {
879     syslog(LOG_INFO, "Hangup (SIGHUP)");
880     kill_link = 1;
881 }
882
883
884 /*
885  * term - Catch SIGTERM signal and SIGINT signal (^C/del).
886  *
887  * Indicates that we should initiate a graceful disconnect and exit.
888  */
889 /*ARGSUSED*/
890 static void
891 term(sig)
892     int sig;
893 {
894     syslog(LOG_INFO, "Terminating on signal %d.", sig);
895     persist = 0;                /* don't try to restart */
896     kill_link = 1;
897 }
898
899
900 /*
901  * chld - Catch SIGCHLD signal.
902  * Calls reap_kids to get status for any dead kids.
903  */
904 static void
905 chld(sig)
906     int sig;
907 {
908     reap_kids();
909 }
910
911
912 /*
913  * toggle_debug - Catch SIGUSR1 signal.
914  *
915  * Toggle debug flag.
916  */
917 /*ARGSUSED*/
918 static void
919 toggle_debug(sig)
920     int sig;
921 {
922     debug = !debug;
923     if (debug) {
924         setlogmask(LOG_UPTO(LOG_DEBUG));
925     } else {
926         setlogmask(LOG_UPTO(LOG_WARNING));
927     }
928 }
929
930
931 /*
932  * open_ccp - Catch SIGUSR2 signal.
933  *
934  * Try to (re)negotiate compression.
935  */
936 /*ARGSUSED*/
937 static void
938 open_ccp(sig)
939     int sig;
940 {
941     open_ccp_flag = 1;
942 }
943
944
945 /*
946  * bad_signal - We've caught a fatal signal.  Clean up state and exit.
947  */
948 static void
949 bad_signal(sig)
950     int sig;
951 {
952     syslog(LOG_ERR, "Fatal signal %d", sig);
953     die(1);
954 }
955
956
957 /*
958  * device_script - run a program to connect or disconnect the
959  * serial device.
960  */
961 static int
962 device_script(program, in, out)
963     char *program;
964     int in, out;
965 {
966     int pid;
967     int status;
968     int errfd;
969
970     pid = fork();
971
972     if (pid < 0) {
973         syslog(LOG_ERR, "Failed to create child process: %m");
974         die(1);
975     }
976
977     if (pid == 0) {
978         sys_close();
979         closelog();
980         if (in == out) {
981             if (in != 0) {
982                 dup2(in, 0);
983                 close(in);
984             }
985             dup2(0, 1);
986         } else {
987             if (out == 0)
988                 out = dup(out);
989             if (in != 0) {
990                 dup2(in, 0);
991                 close(in);
992             }
993             if (out != 1) {
994                 dup2(out, 1);
995                 close(out);
996             }
997         }
998         if (redirect_stderr) {
999             close(2);
1000             errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644);
1001             if (errfd >= 0 && errfd != 2) {
1002                 dup2(errfd, 2);
1003                 close(errfd);
1004             }
1005         }
1006         setuid(getuid());
1007         setgid(getgid());
1008         execl("/bin/sh", "sh", "-c", program, (char *)0);
1009         syslog(LOG_ERR, "could not exec /bin/sh: %m");
1010         _exit(99);
1011         /* NOTREACHED */
1012     }
1013
1014     while (waitpid(pid, &status, 0) < 0) {
1015         if (errno == EINTR)
1016             continue;
1017         syslog(LOG_ERR, "error waiting for (dis)connection process: %m");
1018         die(1);
1019     }
1020
1021     return (status == 0 ? 0 : -1);
1022 }
1023
1024
1025 /*
1026  * run-program - execute a program with given arguments,
1027  * but don't wait for it.
1028  * If the program can't be executed, logs an error unless
1029  * must_exist is 0 and the program file doesn't exist.
1030  */
1031 int
1032 run_program(prog, args, must_exist)
1033     char *prog;
1034     char **args;
1035     int must_exist;
1036 {
1037     int pid;
1038     char *nullenv[1];
1039
1040     pid = fork();
1041     if (pid == -1) {
1042         syslog(LOG_ERR, "Failed to create child process for %s: %m", prog);
1043         return -1;
1044     }
1045     if (pid == 0) {
1046         int new_fd;
1047
1048         /* Leave the current location */
1049         (void) setsid();    /* No controlling tty. */
1050         (void) umask (S_IRWXG|S_IRWXO);
1051         (void) chdir ("/"); /* no current directory. */
1052         setuid(geteuid());
1053         setgid(getegid());
1054
1055         /* Ensure that nothing of our device environment is inherited. */
1056         sys_close();
1057         closelog();
1058         close (0);
1059         close (1);
1060         close (2);
1061         close (ttyfd);  /* tty interface to the ppp device */
1062
1063         /* Don't pass handles to the PPP device, even by accident. */
1064         new_fd = open (_PATH_DEVNULL, O_RDWR);
1065         if (new_fd >= 0) {
1066             if (new_fd != 0) {
1067                 dup2  (new_fd, 0); /* stdin <- /dev/null */
1068                 close (new_fd);
1069             }
1070             dup2 (0, 1); /* stdout -> /dev/null */
1071             dup2 (0, 2); /* stderr -> /dev/null */
1072         }
1073
1074 #ifdef BSD
1075         /* Force the priority back to zero if pppd is running higher. */
1076         if (setpriority (PRIO_PROCESS, 0, 0) < 0)
1077             syslog (LOG_WARNING, "can't reset priority to 0: %m"); 
1078 #endif
1079
1080         /* SysV recommends a second fork at this point. */
1081
1082         /* run the program; give it a null environment */
1083         nullenv[0] = NULL;
1084         execve(prog, args, nullenv);
1085         if (must_exist || errno != ENOENT)
1086             syslog(LOG_WARNING, "Can't execute %s: %m", prog);
1087         _exit(-1);
1088     }
1089     MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid));
1090     ++n_children;
1091     return 0;
1092 }
1093
1094
1095 /*
1096  * reap_kids - get status from any dead child processes,
1097  * and log a message for abnormal terminations.
1098  */
1099 static void
1100 reap_kids()
1101 {
1102     int pid, status;
1103
1104     if (n_children == 0)
1105         return;
1106     if ((pid = waitpid(-1, &status, WNOHANG)) == -1) {
1107         if (errno != ECHILD)
1108             syslog(LOG_ERR, "Error waiting for child process: %m");
1109         return;
1110     }
1111     if (pid > 0) {
1112         --n_children;
1113         if (WIFSIGNALED(status)) {
1114             syslog(LOG_WARNING, "Child process %d terminated with signal %d",
1115                    pid, WTERMSIG(status));
1116         }
1117     }
1118 }
1119
1120
1121 /*
1122  * log_packet - format a packet and log it.
1123  */
1124
1125 char line[256];                 /* line to be logged accumulated here */
1126 char *linep;
1127
1128 void
1129 log_packet(p, len, prefix)
1130     u_char *p;
1131     int len;
1132     char *prefix;
1133 {
1134     strcpy(line, prefix);
1135     linep = line + strlen(line);
1136     format_packet(p, len, pr_log, NULL);
1137     if (linep != line)
1138         syslog(LOG_DEBUG, "%s", line);
1139 }
1140
1141 /*
1142  * format_packet - make a readable representation of a packet,
1143  * calling `printer(arg, format, ...)' to output it.
1144  */
1145 void
1146 format_packet(p, len, printer, arg)
1147     u_char *p;
1148     int len;
1149     void (*printer) __P((void *, char *, ...));
1150     void *arg;
1151 {
1152     int i, n;
1153     u_short proto;
1154     u_char x;
1155     struct protent *protp;
1156
1157     if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
1158         p += 2;
1159         GETSHORT(proto, p);
1160         len -= PPP_HDRLEN;
1161         for (i = 0; (protp = protocols[i]) != NULL; ++i)
1162             if (proto == protp->protocol)
1163                 break;
1164         if (protp != NULL) {
1165             printer(arg, "[%s", protp->name);
1166             n = (*protp->printpkt)(p, len, printer, arg);
1167             printer(arg, "]");
1168             p += n;
1169             len -= n;
1170         } else {
1171             printer(arg, "[proto=0x%x]", proto);
1172         }
1173     }
1174
1175     for (; len > 0; --len) {
1176         GETCHAR(x, p);
1177         printer(arg, " %.2x", x);
1178     }
1179 }
1180
1181 static void
1182 pr_log __V((void *arg, char *fmt, ...))
1183 {
1184     int n;
1185     va_list pvar;
1186     char buf[256];
1187
1188 #if __STDC__
1189     va_start(pvar, fmt);
1190 #else
1191     void *arg;
1192     char *fmt;
1193     va_start(pvar);
1194     arg = va_arg(pvar, void *);
1195     fmt = va_arg(pvar, char *);
1196 #endif
1197
1198     vsprintf(buf, fmt, pvar);
1199     va_end(pvar);
1200
1201     n = strlen(buf);
1202     if (linep + n + 1 > line + sizeof(line)) {
1203         syslog(LOG_DEBUG, "%s", line);
1204         linep = line;
1205     }
1206     strcpy(linep, buf);
1207     linep += n;
1208 }
1209
1210 /*
1211  * print_string - print a readable representation of a string using
1212  * printer.
1213  */
1214 void
1215 print_string(p, len, printer, arg)
1216     char *p;
1217     int len;
1218     void (*printer) __P((void *, char *, ...));
1219     void *arg;
1220 {
1221     int c;
1222
1223     printer(arg, "\"");
1224     for (; len > 0; --len) {
1225         c = *p++;
1226         if (' ' <= c && c <= '~') {
1227             if (c == '\\' || c == '"')
1228                 printer(arg, "\\");
1229             printer(arg, "%c", c);
1230         } else {
1231             switch (c) {
1232             case '\n':
1233                 printer(arg, "\\n");
1234                 break;
1235             case '\r':
1236                 printer(arg, "\\r");
1237                 break;
1238             case '\t':
1239                 printer(arg, "\\t");
1240                 break;
1241             default:
1242                 printer(arg, "\\%.3o", c);
1243             }
1244         }
1245     }
1246     printer(arg, "\"");
1247 }
1248
1249 /*
1250  * novm - log an error message saying we ran out of memory, and die.
1251  */
1252 void
1253 novm(msg)
1254     char *msg;
1255 {
1256     syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
1257     die(1);
1258 }
1259
1260 /*
1261  * fmtmsg - format a message into a buffer.  Like sprintf except we
1262  * also specify the length of the output buffer, and we handle
1263  * %r (recursive format), %m (error message) and %I (IP address) formats.
1264  * Doesn't do floating-point formats.
1265  * Returns the number of chars put into buf.
1266  */
1267 int
1268 fmtmsg __V((char *buf, int buflen, char *fmt, ...))
1269 {
1270     va_list args;
1271     int n;
1272
1273 #if __STDC__
1274     va_start(args, fmt);
1275 #else
1276     char *buf;
1277     int buflen;
1278     char *fmt;
1279     va_start(args);
1280     buf = va_arg(args, char *);
1281     buflen = va_arg(args, int);
1282     fmt = va_arg(args, char *);
1283 #endif
1284     n = vfmtmsg(buf, buflen, fmt, args);
1285     va_end(args);
1286     return n;
1287 }
1288
1289 /*
1290  * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
1291  */
1292 #define OUTCHAR(c)      (buflen > 0? (--buflen, *buf++ = (c)): 0)
1293
1294 int
1295 vfmtmsg(char *buf, int buflen, char *fmt, va_list args)
1296 {
1297     int c, i, n;
1298     int width, prec, fillch;
1299     int base, len, neg, quoted;
1300     unsigned long val;
1301     char *str, *f, *buf0;
1302     unsigned char *p;
1303     va_list a;
1304     char num[32];
1305     time_t t;
1306     static char hexchars[16] = "0123456789abcdef";
1307
1308     buf0 = buf;
1309     --buflen;
1310     while (buflen > 0) {
1311         for (f = fmt; *f != '%' && *f != 0; ++f)
1312             ;
1313         if (f > fmt) {
1314             len = f - fmt;
1315             if (len > buflen)
1316                 len = buflen;
1317             memcpy(buf, fmt, len);
1318             buf += len;
1319             buflen -= len;
1320             fmt = f;
1321         }
1322         if (*fmt == 0)
1323             break;
1324         c = *++fmt;
1325         width = prec = 0;
1326         fillch = ' ';
1327         if (c == '0') {
1328             fillch = '0';
1329             c = *++fmt;
1330         }
1331         if (c == '*') {
1332             width = va_arg(args, int);
1333             c = *++fmt;
1334         } else {
1335             while (isdigit(c)) {
1336                 width = width * 10 + c - '0';
1337                 c = *++fmt;
1338             }
1339         }
1340         if (c == '.') {
1341             c = *++fmt;
1342             if (c == '*') {
1343                 prec = va_arg(args, int);
1344                 c = *++fmt;
1345             } else {
1346                 while (isdigit(c)) {
1347                     prec = prec * 10 + c - '0';
1348                     c = *++fmt;
1349                 }
1350             }
1351         }
1352         str = 0;
1353         base = 0;
1354         neg = 0;
1355         ++fmt;
1356         switch (c) {
1357         case 'd':
1358             i = va_arg(args, int);
1359             if (i < 0) {
1360                 neg = 1;
1361                 val = -i;
1362             } else
1363                 val = i;
1364             base = 10;
1365             break;
1366         case 'o':
1367             val = va_arg(args, unsigned int);
1368             base = 8;
1369             break;
1370         case 'x':
1371             val = va_arg(args, unsigned int);
1372             base = 16;
1373             break;
1374         case 'p':
1375             val = (unsigned long) va_arg(args, void *);
1376             base = 16;
1377             neg = 2;
1378             break;
1379         case 's':
1380             str = va_arg(args, char *);
1381             break;
1382         case 'c':
1383             num[0] = va_arg(args, int);
1384             num[1] = 0;
1385             str = num;
1386             break;
1387         case 'm':
1388             str = strerror(errno);
1389             break;
1390         case 'I':
1391             str = ip_ntoa(va_arg(args, u_int32_t));
1392             break;
1393         case 'r':
1394             f = va_arg(args, char *);
1395             a = va_arg(args, va_list);
1396             n = vfmtmsg(buf, buflen + 1, f, a);
1397             buf += n;
1398             buflen -= n;
1399             continue;
1400         case 't':
1401             time(&t);
1402             str = ctime(&t);
1403             str += 4;           /* chop off the day name */
1404             str[15] = 0;        /* chop off year and newline */
1405             break;
1406         case 'v':               /* "visible" string */
1407         case 'q':               /* quoted string */
1408             quoted = c == 'q';
1409             p = va_arg(args, unsigned char *);
1410             if (fillch == '0' && prec > 0) {
1411                 n = prec;
1412             } else {
1413                 n = strlen((char *)p);
1414                 if (prec > 0 && prec < n)
1415                     n = prec;
1416             }
1417             while (n > 0 && buflen > 0) {
1418                 c = *p++;
1419                 --n;
1420                 if (!quoted && c >= 0x80) {
1421                     OUTCHAR('M');
1422                     OUTCHAR('-');
1423                     c -= 0x80;
1424                 }
1425                 if (quoted && (c == '"' || c == '\\'))
1426                     OUTCHAR('\\');
1427                 if (c < 0x20 || 0x7f <= c && c < 0xa0) {
1428                     if (quoted) {
1429                         OUTCHAR('\\');
1430                         switch (c) {
1431                         case '\t':      OUTCHAR('t');   break;
1432                         case '\n':      OUTCHAR('n');   break;
1433                         case '\b':      OUTCHAR('b');   break;
1434                         case '\f':      OUTCHAR('f');   break;
1435                         default:
1436                             OUTCHAR('x');
1437                             OUTCHAR(hexchars[c >> 4]);
1438                             OUTCHAR(hexchars[c & 0xf]);
1439                         }
1440                     } else {
1441                         if (c == '\t')
1442                             OUTCHAR(c);
1443                         else {
1444                             OUTCHAR('^');
1445                             OUTCHAR(c ^ 0x40);
1446                         }
1447                     }
1448                 } else
1449                     OUTCHAR(c);
1450             }
1451             continue;
1452         default:
1453             *buf++ = '%';
1454             if (c != '%')
1455                 --fmt;          /* so %z outputs %z etc. */
1456             --buflen;
1457             continue;
1458         }
1459         if (base != 0) {
1460             str = num + sizeof(num);
1461             *--str = 0;
1462             while (str > num + neg) {
1463                 *--str = hexchars[val % base];
1464                 val = val / base;
1465                 if (--prec <= 0 && val == 0)
1466                     break;
1467             }
1468             switch (neg) {
1469             case 1:
1470                 *--str = '-';
1471                 break;
1472             case 2:
1473                 *--str = 'x';
1474                 *--str = '0';
1475                 break;
1476             }
1477             len = num + sizeof(num) - 1 - str;
1478         } else {
1479             len = strlen(str);
1480             if (prec > 0 && len > prec)
1481                 len = prec;
1482         }
1483         if (width > 0) {
1484             if (width > buflen)
1485                 width = buflen;
1486             if ((n = width - len) > 0) {
1487                 buflen -= n;
1488                 for (; n > 0; --n)
1489                     *buf++ = fillch;
1490             }
1491         }
1492         if (len > buflen)
1493             len = buflen;
1494         memcpy(buf, str, len);
1495         buf += len;
1496         buflen -= len;
1497     }
1498     *buf = 0;
1499     return buf - buf0;
1500 }