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