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