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