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