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