2 * main.c - Point-to-Point Protocol main module
4 * Copyright (c) 1989 Carnegie Mellon University.
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.
19 * $FreeBSD: src/usr.sbin/pppd/main.c,v 1.19.2.1 2002/07/30 03:50:40 peter Exp $
20 * $DragonFly: src/usr.sbin/pppd/main.c,v 1.6 2006/07/27 00:40:55 corecode Exp $
35 #include <sys/param.h>
36 #include <sys/types.h>
39 #include <sys/resource.h>
41 #include <sys/socket.h>
51 #include "pathnames.h"
52 #include "patchlevel.h"
59 extern char *strerror();
64 #endif /* IPX_CHANGE */
70 char ifname
[32]; /* Interface name */
71 int ifunit
; /* Interface unit number */
73 char *progname
; /* Name of this program */
74 char hostname
[MAXNAMELEN
]; /* Our hostname */
75 static char pidfilename
[MAXPATHLEN
]; /* name of pid file */
76 static char iffilename
[MAXPATHLEN
]; /* name of if file */
77 static char default_devnam
[MAXPATHLEN
]; /* name of default device */
78 static pid_t pid
; /* Our pid */
79 static uid_t uid
; /* Our real user-id */
80 time_t etime
,stime
; /* End and Start time */
81 int minutes
; /* connection duration */
82 static int conn_running
; /* we have a [dis]connector running */
84 int ttyfd
= -1; /* Serial port file descriptor */
85 mode_t tty_mode
= -1; /* Original access permissions to tty */
86 int baud_rate
; /* Actual bits/second for serial device */
87 int hungup
; /* terminal has been hung up */
88 int privileged
; /* we're running as real uid root */
89 int need_holdoff
; /* need holdoff period before restarting */
90 int detached
; /* have detached from terminal */
92 int phase
; /* where the link is at */
96 char **script_env
; /* Env. variable values for scripts */
97 int s_env_nalloc
; /* # words avail at script_env */
99 u_char outpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for outgoing packet */
100 u_char inpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for incoming packet */
102 static int n_children
; /* # child processes still running */
104 static int locked
; /* lock() has succeeded */
106 char *no_ppp_msg
= "Sorry - this system lacks PPP kernel support\n";
108 /* Prototypes for procedures local to this file. */
110 static void create_pidfile(void);
111 static void cleanup(void);
112 static void close_tty(void);
113 static void get_input(void);
114 static void calltimeout(void);
115 static struct timeval
*timeleft(struct timeval
*);
116 static void kill_my_pg(int);
117 static void hup(int);
118 static void term(int);
119 static void chld(int);
120 static void toggle_debug(int);
121 static void open_ccp(int);
122 static void bad_signal(int);
123 static void holdoff_end(void *);
124 static int device_script(char *, int, int);
125 static void reap_kids(void);
126 static void pr_log(void *, char *, ...);
128 extern char *ttyname(int);
129 extern char *getlogin(void);
130 int main(int, char *[]);
134 #define O_NONBLOCK O_NDELAY
138 #define setlogmask(x)
142 * PPP Data Link Layer "protocol" table.
143 * One entry per supported protocol.
144 * The last entry must be NULL.
146 struct protent
*protocols
[] = {
165 main(int argc
, char *argv
[])
174 struct protent
*protp
;
176 int connect_attempts
= 0;
179 phase
= PHASE_INITIALIZE
;
183 strcpy(default_devnam
, devnam
);
187 /* Initialize syslog facilities */
189 openlog("pppd", LOG_PID
);
191 openlog("pppd", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
192 setlogmask(LOG_UPTO(LOG_INFO
));
195 if (gethostname(hostname
, MAXNAMELEN
) < 0 ) {
196 option_error("Couldn't get hostname: %m");
199 hostname
[MAXNAMELEN
-1] = 0;
202 privileged
= uid
== 0;
203 sprintf(numbuf
, "%d", uid
);
204 script_setenv("UID", numbuf
);
207 * Initialize to the standard option set, then parse, in order,
208 * the system options file, the user's options file,
209 * the tty's options file, and the command line arguments.
211 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
216 if (!options_from_file(_PATH_SYSOPTIONS
, !privileged
, 0, 1)
217 || !options_from_user())
219 scan_args(argc
-1, argv
+1); /* look for tty name on command line */
220 if (!options_for_tty()
221 || !parse_args(argc
-1, argv
+1))
225 * Check that we are running as root.
227 if (geteuid() != 0) {
228 option_error("must be root to run %s, since it is not setuid-root",
233 if (!ppp_available()) {
234 option_error(no_ppp_msg
);
239 * Check that the options given are valid and consistent.
242 auth_check_options();
243 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
244 if (protp
->check_options
!= NULL
)
245 (*protp
->check_options
)();
246 if (demand
&& connector
== 0) {
247 option_error("connect script required for demand-dialling\n");
251 script_setenv("DEVICE", devnam
);
252 sprintf(numbuf
, "%d", baud_rate
);
253 script_setenv("SPEED", numbuf
);
256 * If the user has specified the default device name explicitly,
257 * pretend they hadn't.
259 if (!default_device
&& strcmp(devnam
, default_devnam
) == 0)
265 * Initialize system-dependent stuff and magic number package.
270 setlogmask(LOG_UPTO(LOG_DEBUG
));
273 * Detach ourselves from the terminal, if required,
274 * and identify who is running us.
283 if (pw
!= NULL
&& pw
->pw_name
!= NULL
)
288 syslog(LOG_NOTICE
, "pppd %s.%d%s started by %s, uid %d",
289 VERSION
, PATCHLEVEL
, IMPLEMENTATION
, p
, uid
);
292 * Compute mask of all interesting signals and install signal handlers
293 * for each. Only one signal handler may be active at a time. Therefore,
294 * all other signals should be masked when any handler is executing.
297 sigaddset(&mask
, SIGHUP
);
298 sigaddset(&mask
, SIGINT
);
299 sigaddset(&mask
, SIGTERM
);
300 sigaddset(&mask
, SIGCHLD
);
302 #define SIGNAL(s, handler) { \
303 sa.sa_handler = handler; \
304 if (sigaction(s, &sa, NULL) < 0) { \
305 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \
312 SIGNAL(SIGHUP
, hup
); /* Hangup */
313 SIGNAL(SIGINT
, term
); /* Interrupt */
314 SIGNAL(SIGTERM
, term
); /* Terminate */
315 SIGNAL(SIGCHLD
, chld
);
317 SIGNAL(SIGUSR1
, toggle_debug
); /* Toggle debug flag */
318 SIGNAL(SIGUSR2
, open_ccp
); /* Reopen CCP */
321 * Install a handler for other signals which would otherwise
322 * cause pppd to exit without cleaning up.
324 SIGNAL(SIGABRT
, bad_signal
);
325 SIGNAL(SIGALRM
, bad_signal
);
326 SIGNAL(SIGFPE
, bad_signal
);
327 SIGNAL(SIGILL
, bad_signal
);
328 SIGNAL(SIGPIPE
, bad_signal
);
329 SIGNAL(SIGQUIT
, bad_signal
);
330 SIGNAL(SIGSEGV
, bad_signal
);
332 SIGNAL(SIGBUS
, bad_signal
);
335 SIGNAL(SIGEMT
, bad_signal
);
338 SIGNAL(SIGPOLL
, bad_signal
);
341 SIGNAL(SIGPROF
, bad_signal
);
344 SIGNAL(SIGSYS
, bad_signal
);
347 SIGNAL(SIGTRAP
, bad_signal
);
350 SIGNAL(SIGVTALRM
, bad_signal
);
353 SIGNAL(SIGXCPU
, bad_signal
);
356 SIGNAL(SIGXFSZ
, bad_signal
);
360 * Apparently we can get a SIGPIPE when we call syslog, if
361 * syslogd has died and been restarted. Ignoring it seems
364 signal(SIGPIPE
, SIG_IGN
);
367 * If we're doing dial-on-demand, set up the interface now.
371 * Open the loopback channel and set it up to be the ppp interface.
375 syslog(LOG_INFO
, "Using interface ppp%d", ifunit
);
376 sprintf(ifname
, "ppp%d", ifunit
);
377 script_setenv("IFNAME", ifname
);
379 create_pidfile(); /* write pid to file */
382 * Configure the interface and mark it up, etc.
393 * Don't do anything until we see some activity.
395 phase
= PHASE_DORMANT
;
399 wait_loop_output(timeleft(&timo
));
406 if (get_loop_output())
412 * Now we want to bring up the link.
415 syslog(LOG_INFO
, "Starting link");
419 * Lock the device if we've been asked to.
421 if (lockflag
&& !default_device
) {
422 if (lock(devnam
) < 0)
428 * Open the serial device and set it up to be the ppp interface.
429 * First we open it in non-blocking mode so we can set the
430 * various termios flags appropriately. If we aren't dialling
431 * out and we want to use the modem lines, we reopen it later
432 * in order to wait for the carrier detect signal from the modem.
434 while ((ttyfd
= open(devnam
, O_NONBLOCK
| O_RDWR
, 0)) < 0) {
436 syslog(LOG_ERR
, "Failed to open %s: %m", devnam
);
437 if (!persist
|| errno
!= EINTR
)
440 if ((fdflags
= fcntl(ttyfd
, F_GETFL
)) == -1
441 || fcntl(ttyfd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
443 "Couldn't reset non-blocking mode on device: %m");
449 * Do the equivalent of `mesg n' to stop broadcast messages.
451 if (fstat(ttyfd
, &statbuf
) < 0
452 || fchmod(ttyfd
, statbuf
.st_mode
& ~(S_IWGRP
| S_IWOTH
)) < 0) {
454 "Couldn't restrict write permissions to %s: %m", devnam
);
456 tty_mode
= statbuf
.st_mode
;
458 /* run connection script */
459 if (connector
&& connector
[0]) {
460 MAINDEBUG((LOG_INFO
, "Connecting with <%s>", connector
));
463 * Set line speed, flow control, etc.
464 * On most systems we set CLOCAL for now so that we can talk
465 * to the modem before carrier comes up. But this has the
466 * side effect that we might miss it if CD drops before we
467 * get to clear CLOCAL below. On systems where we can talk
468 * successfully to the modem with CLOCAL clear and CD down,
469 * we can clear CLOCAL at this point.
471 set_up_tty(ttyfd
, 1);
473 /* drop dtr to hang up in case modem is off hook */
474 if (!default_device
&& modem
) {
475 setdtr(ttyfd
, FALSE
);
480 if (device_script(connector
, ttyfd
, ttyfd
) < 0) {
481 syslog(LOG_ERR
, "Connect script failed");
482 setdtr(ttyfd
, FALSE
);
488 syslog(LOG_INFO
, "Serial connection established.");
489 sleep(1); /* give it time to set up its terminal */
492 connect_attempts
= 0; /* we made it through ok */
494 /* set line speed, flow control, etc.; clear CLOCAL if modem option */
495 set_up_tty(ttyfd
, 0);
497 /* reopen tty if necessary to wait for carrier */
498 if (connector
== NULL
&& modem
) {
499 while ((i
= open(devnam
, O_RDWR
)) < 0) {
501 syslog(LOG_ERR
, "Failed to reopen %s: %m", devnam
);
502 if (!persist
|| errno
!= EINTR
||
509 /* run welcome script, if any */
510 if (welcomer
&& welcomer
[0]) {
511 if (device_script(welcomer
, ttyfd
, ttyfd
) < 0)
512 syslog(LOG_WARNING
, "Welcome script failed");
515 /* set up the serial device as a ppp interface */
516 establish_ppp(ttyfd
);
520 syslog(LOG_INFO
, "Using interface ppp%d", ifunit
);
521 sprintf(ifname
, "ppp%d", ifunit
);
523 create_pidfile(); /* write pid to file */
525 /* write interface unit number to file */
526 for (n
= strlen(devnam
); n
> 0 ; n
--)
527 if (devnam
[n
] == '/') {
531 sprintf(iffilename
, "%s%s.if", _PATH_VARRUN
, &devnam
[n
]);
532 if ((iffile
= fopen(iffilename
, "w")) != NULL
) {
533 fprintf(iffile
, "ppp%d\n", ifunit
);
536 syslog(LOG_ERR
, "Failed to create if file %s: %m", iffilename
);
540 script_setenv("IFNAME", ifname
);
544 * Start opening the connection and wait for
545 * incoming events (reply, timeout, etc.).
547 syslog(LOG_NOTICE
, "Connect: %s <--> %s", ifname
, devnam
);
550 lcp_open(0); /* Start protocol */
551 for (phase
= PHASE_ESTABLISH
; phase
!= PHASE_DEAD
; ) {
552 wait_input(timeleft(&timo
));
556 lcp_close(0, "User request");
560 if (phase
== PHASE_NETWORK
) {
561 ccp_fsm
[0].flags
= OPT_RESTART
; /* clears OPT_SILENT */
562 (*ccp_protent
.open
)(0);
566 reap_kids(); /* Don't leave dead kids lying around */
570 * If we may want to bring the link up again, transfer
571 * the ppp unit back to the loopback. Set the
572 * real serial device back to its normal mode of operation.
577 disestablish_ppp(ttyfd
);
580 * Run disconnector script, if requested.
581 * XXX we may not be able to do this if the line has hung up!
583 if (disconnector
&& !hungup
) {
584 set_up_tty(ttyfd
, 1);
585 if (device_script(disconnector
, ttyfd
, ttyfd
) < 0) {
586 syslog(LOG_WARNING
, "disconnect script failed");
588 syslog(LOG_INFO
, "Serial link disconnected.");
601 if (pidfilename
[0] != 0
602 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
603 syslog(LOG_WARNING
, "unable to delete pid file: %m");
607 if (unlink(iffilename
) < 0 && errno
!= ENOENT
)
608 syslog(LOG_WARNING
, "unable to delete if file: %m");
612 /* limit to retries? */
613 if (max_con_attempts
)
614 if (connect_attempts
>= max_con_attempts
)
622 if (holdoff
> 0 && need_holdoff
) {
623 phase
= PHASE_HOLDOFF
;
624 TIMEOUT(holdoff_end
, NULL
, holdoff
);
626 wait_time(timeleft(&timo
));
632 phase
= PHASE_DORMANT
; /* allow signal to end holdoff */
635 } while (phase
== PHASE_HOLDOFF
);
644 * detach - detach us from the controlling terminal.
651 if (daemon(0, 0) < 0) {
652 perror("Couldn't detach from controlling terminal");
657 /* update pid file if it has been written already */
663 * Create a file containing our process ID.
670 sprintf(pidfilename
, "%s%s.pid", _PATH_VARRUN
, ifname
);
671 if ((pidfile
= fopen(pidfilename
, "w")) != NULL
) {
672 fprintf(pidfile
, "%d\n", pid
);
675 syslog(LOG_ERR
, "Failed to create pid file %s: %m", pidfilename
);
681 * holdoff_end - called via a timeout when the holdoff period ends.
684 holdoff_end(void *arg
)
686 phase
= PHASE_DORMANT
;
690 * get_input - called when incoming data is available.
698 struct protent
*protp
;
700 p
= inpacket_buf
; /* point to beginning of packet buffer */
702 len
= read_packet(inpacket_buf
);
708 minutes
= (etime
-stime
)/60;
709 syslog(LOG_NOTICE
, "Modem hangup, connected for %d minutes", (minutes
>1) ? minutes
: 1);
711 lcp_lowerdown(0); /* serial link is no longer available */
716 if (debug
/*&& (debugflags & DBG_INPACKET)*/)
717 log_packet(p
, len
, "rcvd ", LOG_DEBUG
);
719 if (len
< PPP_HDRLEN
) {
720 MAINDEBUG((LOG_INFO
, "io(): Received short packet."));
724 p
+= 2; /* Skip address and control */
725 GETSHORT(protocol
, p
);
729 * Toss all non-LCP packets unless LCP is OPEN.
731 if (protocol
!= PPP_LCP
&& lcp_fsm
[0].state
!= OPENED
) {
733 "get_input: Received non-LCP packet when LCP not open."));
738 * Until we get past the authentication phase, toss all packets
739 * except LCP, LQR and authentication packets.
741 if (phase
<= PHASE_AUTHENTICATE
742 && !(protocol
== PPP_LCP
|| protocol
== PPP_LQR
743 || protocol
== PPP_PAP
|| protocol
== PPP_CHAP
)) {
744 MAINDEBUG((LOG_INFO
, "get_input: discarding proto 0x%x in phase %d",
750 * Upcall the proper protocol input routine.
752 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
) {
753 if (protp
->protocol
== protocol
&& protp
->enabled_flag
) {
754 (*protp
->input
)(0, p
, len
);
757 if (protocol
== (protp
->protocol
& ~0x8000) && protp
->enabled_flag
758 && protp
->datainput
!= NULL
) {
759 (*protp
->datainput
)(0, p
, len
);
765 syslog(LOG_WARNING
, "Unsupported protocol (0x%x) received", protocol
);
766 lcp_sprotrej(0, p
- PPP_HDRLEN
, len
+ PPP_HDRLEN
);
771 * quit - Clean up state and exit (with an error indication).
780 * die - like quit, except we can specify an exit status.
786 syslog(LOG_INFO
, "Exit.");
791 * cleanup - restore anything which needs to be restored before we exit
802 if (pidfilename
[0] != 0 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
803 syslog(LOG_WARNING
, "unable to delete pid file: %m");
811 * close_tty - restore the terminal device and close it.
816 disestablish_ppp(ttyfd
);
818 /* drop dtr to hang up */
820 setdtr(ttyfd
, FALSE
);
822 * This sleep is in case the serial port has CLOCAL set by default,
823 * and consequently will reassert DTR when we close the device.
830 if (tty_mode
!= (mode_t
) -1)
831 fchmod(ttyfd
, tty_mode
);
839 struct timeval c_time
; /* time at which to call routine */
840 void *c_arg
; /* argument to routine */
841 void (*c_func
)(void *); /* routine */
842 struct callout
*c_next
;
845 static struct callout
*callout
= NULL
; /* Callout list */
846 static struct timeval timenow
; /* Current time */
849 * timeout - Schedule a timeout.
851 * Note that this timeout takes the number of seconds, NOT hz (as in
855 timeout(void (*func
)(void *), void *arg
, int time
)
857 struct callout
*newp
, *p
, **pp
;
859 MAINDEBUG((LOG_DEBUG
, "Timeout %lx:%lx in %d seconds.",
860 (long) func
, (long) arg
, time
));
865 if ((newp
= (struct callout
*) malloc(sizeof(struct callout
))) == NULL
) {
866 syslog(LOG_ERR
, "Out of memory in timeout()!");
871 gettimeofday(&timenow
, NULL
);
872 newp
->c_time
.tv_sec
= timenow
.tv_sec
+ time
;
873 newp
->c_time
.tv_usec
= timenow
.tv_usec
;
876 * Find correct place and link it in.
878 for (pp
= &callout
; (p
= *pp
); pp
= &p
->c_next
)
879 if (newp
->c_time
.tv_sec
< p
->c_time
.tv_sec
880 || (newp
->c_time
.tv_sec
== p
->c_time
.tv_sec
881 && newp
->c_time
.tv_usec
< p
->c_time
.tv_sec
))
889 * untimeout - Unschedule a timeout.
892 untimeout(void (*func
)(void *), void *arg
)
894 struct callout
**copp
, *freep
;
896 MAINDEBUG((LOG_DEBUG
, "Untimeout %lx:%lx.", (long) func
, (long) arg
));
899 * Find first matching timeout and remove it from the list.
901 for (copp
= &callout
; (freep
= *copp
); copp
= &freep
->c_next
)
902 if (freep
->c_func
== func
&& freep
->c_arg
== arg
) {
903 *copp
= freep
->c_next
;
904 free((char *) freep
);
911 * calltimeout - Call any timeout routines which are now due.
918 while (callout
!= NULL
) {
921 if (gettimeofday(&timenow
, NULL
) < 0) {
922 syslog(LOG_ERR
, "Failed to get time of day: %m");
925 if (!(p
->c_time
.tv_sec
< timenow
.tv_sec
926 || (p
->c_time
.tv_sec
== timenow
.tv_sec
927 && p
->c_time
.tv_usec
<= timenow
.tv_usec
)))
928 break; /* no, it's not time yet */
931 (*p
->c_func
)(p
->c_arg
);
939 * timeleft - return the length of time until the next timeout is due.
941 static struct timeval
*
942 timeleft(struct timeval
*tvp
)
947 gettimeofday(&timenow
, NULL
);
948 tvp
->tv_sec
= callout
->c_time
.tv_sec
- timenow
.tv_sec
;
949 tvp
->tv_usec
= callout
->c_time
.tv_usec
- timenow
.tv_usec
;
950 if (tvp
->tv_usec
< 0) {
951 tvp
->tv_usec
+= 1000000;
955 tvp
->tv_sec
= tvp
->tv_usec
= 0;
962 * kill_my_pg - send a signal to our process group, and ignore it ourselves.
967 struct sigaction act
, oldact
;
969 act
.sa_handler
= SIG_IGN
;
972 sigaction(sig
, &act
, &oldact
);
973 sigaction(sig
, &oldact
, NULL
);
978 * hup - Catch SIGHUP signal.
980 * Indicates that the physical layer has been disconnected.
981 * We don't rely on this indication; if the user has sent this
982 * signal, we just take the link down.
987 syslog(LOG_INFO
, "Hangup (SIGHUP)");
990 /* Send the signal to the [dis]connector process(es) also */
996 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
998 * Indicates that we should initiate a graceful disconnect and exit.
1004 syslog(LOG_INFO
, "Terminating on signal %d.", sig
);
1005 persist
= 0; /* don't try to restart */
1008 /* Send the signal to the [dis]connector process(es) also */
1014 * chld - Catch SIGCHLD signal.
1015 * Calls reap_kids to get status for any dead kids.
1025 * toggle_debug - Catch SIGUSR1 signal.
1027 * Toggle debug flag.
1031 toggle_debug(int sig
)
1035 setlogmask(LOG_UPTO(LOG_DEBUG
));
1037 setlogmask(LOG_UPTO(LOG_WARNING
));
1043 * open_ccp - Catch SIGUSR2 signal.
1045 * Try to (re)negotiate compression.
1056 * bad_signal - We've caught a fatal signal. Clean up state and exit.
1061 static int crashed
= 0;
1066 syslog(LOG_ERR
, "Fatal signal %d", sig
);
1068 kill_my_pg(SIGTERM
);
1074 * device_script - run a program to connect or disconnect the
1078 device_script(char *program
, int in
, int out
)
1089 syslog(LOG_ERR
, "Failed to create child process: %m");
1114 if (nodetach
== 0) {
1116 errfd
= open(_PATH_CONNERRS
, O_WRONLY
| O_APPEND
| O_CREAT
, 0600);
1117 if (errfd
>= 0 && errfd
!= 2) {
1124 execl("/bin/sh", "sh", "-c", program
, NULL
);
1125 syslog(LOG_ERR
, "could not exec /bin/sh: %m");
1130 while (waitpid(pid
, &status
, 0) < 0) {
1133 syslog(LOG_ERR
, "error waiting for (dis)connection process: %m");
1138 return (status
== 0 ? 0 : -1);
1143 * run-program - execute a program with given arguments,
1144 * but don't wait for it.
1145 * If the program can't be executed, logs an error unless
1146 * must_exist is 0 and the program file doesn't exist.
1149 run_program(char *prog
, char **args
, int must_exist
)
1155 syslog(LOG_ERR
, "Failed to create child process for %s: %m", prog
);
1161 /* Leave the current location */
1162 setsid(); /* No controlling tty. */
1163 umask (S_IRWXG
|S_IRWXO
);
1164 chdir ("/"); /* no current directory. */
1168 /* Ensure that nothing of our device environment is inherited. */
1174 close (ttyfd
); /* tty interface to the ppp device */
1176 /* Don't pass handles to the PPP device, even by accident. */
1177 new_fd
= open (_PATH_DEVNULL
, O_RDWR
);
1180 dup2 (new_fd
, 0); /* stdin <- /dev/null */
1183 dup2 (0, 1); /* stdout -> /dev/null */
1184 dup2 (0, 2); /* stderr -> /dev/null */
1188 /* Force the priority back to zero if pppd is running higher. */
1189 if (setpriority (PRIO_PROCESS
, 0, 0) < 0)
1190 syslog (LOG_WARNING
, "can't reset priority to 0: %m");
1193 /* SysV recommends a second fork at this point. */
1195 /* run the program; give it a null environment */
1196 execve(prog
, args
, script_env
);
1197 if (must_exist
|| errno
!= ENOENT
)
1198 syslog(LOG_WARNING
, "Can't execute %s: %m", prog
);
1201 MAINDEBUG((LOG_DEBUG
, "Script %s started; pid = %d", prog
, pid
));
1208 * reap_kids - get status from any dead child processes,
1209 * and log a message for abnormal terminations.
1216 if (n_children
== 0)
1218 if ((pid
= waitpid(-1, &status
, WNOHANG
)) == -1) {
1219 if (errno
!= ECHILD
)
1220 syslog(LOG_ERR
, "Error waiting for child process: %m");
1225 if (WIFSIGNALED(status
)) {
1226 syslog(LOG_WARNING
, "Child process %d terminated with signal %d",
1227 pid
, WTERMSIG(status
));
1234 * log_packet - format a packet and log it.
1237 char line
[256]; /* line to be logged accumulated here */
1241 log_packet(u_char
*p
, int len
, char *prefix
, int level
)
1243 strcpy(line
, prefix
);
1244 linep
= line
+ strlen(line
);
1245 format_packet(p
, len
, pr_log
, NULL
);
1247 syslog(level
, "%s", line
);
1251 * format_packet - make a readable representation of a packet,
1252 * calling `printer(arg, format, ...)' to output it.
1255 format_packet(u_char
*p
, int len
, void (*printer
)(void *, char *, ...),
1261 struct protent
*protp
;
1263 if (len
>= PPP_HDRLEN
&& p
[0] == PPP_ALLSTATIONS
&& p
[1] == PPP_UI
) {
1267 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
1268 if (proto
== protp
->protocol
)
1270 if (protp
!= NULL
) {
1271 printer(arg
, "[%s", protp
->name
);
1272 n
= (*protp
->printpkt
)(p
, len
, printer
, arg
);
1277 printer(arg
, "[proto=0x%x]", proto
);
1281 for (; len
> 0; --len
) {
1283 printer(arg
, " %.2x", x
);
1288 pr_log
__V((void *arg
, char *fmt
, ...))
1295 va_start(pvar
, fmt
);
1300 arg
= va_arg(pvar
, void *);
1301 fmt
= va_arg(pvar
, char *);
1304 n
= vfmtmsg(buf
, sizeof(buf
), fmt
, pvar
);
1307 if (linep
+ n
+ 1 > line
+ sizeof(line
)) {
1308 syslog(LOG_DEBUG
, "%s", line
);
1316 * print_string - print a readable representation of a string using
1320 print_string(char *p
, int len
, void (*printer
)(void *, char *, ...),
1326 for (; len
> 0; --len
) {
1328 if (' ' <= c
&& c
<= '~') {
1329 if (c
== '\\' || c
== '"')
1331 printer(arg
, "%c", c
);
1335 printer(arg
, "\\n");
1338 printer(arg
, "\\r");
1341 printer(arg
, "\\t");
1344 printer(arg
, "\\%.3o", c
);
1352 * novm - log an error message saying we ran out of memory, and die.
1357 syslog(LOG_ERR
, "Virtual memory exhausted allocating %s\n", msg
);
1362 * fmtmsg - format a message into a buffer. Like sprintf except we
1363 * also specify the length of the output buffer, and we handle
1364 * %r (recursive format), %m (error message) and %I (IP address) formats.
1365 * Doesn't do floating-point formats.
1366 * Returns the number of chars put into buf.
1369 fmtmsg
__V((char *buf
, int buflen
, char *fmt
, ...))
1375 va_start(args
, fmt
);
1381 buf
= va_arg(args
, char *);
1382 buflen
= va_arg(args
, int);
1383 fmt
= va_arg(args
, char *);
1385 n
= vfmtmsg(buf
, buflen
, fmt
, args
);
1391 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
1393 #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
1396 vfmtmsg(char *buf
, int buflen
, char *fmt
, va_list args
)
1399 int width
, prec
, fillch
;
1400 int base
, len
, neg
, quoted
;
1401 unsigned long val
= 0;
1402 char *str
, *f
, *buf0
;
1406 static char hexchars
[] = "0123456789abcdef";
1410 while (buflen
> 0) {
1411 for (f
= fmt
; *f
!= '%' && *f
!= 0; ++f
)
1417 memcpy(buf
, fmt
, len
);
1432 width
= va_arg(args
, int);
1435 while (isdigit(c
)) {
1436 width
= width
* 10 + c
- '0';
1443 prec
= va_arg(args
, int);
1446 while (isdigit(c
)) {
1447 prec
= prec
* 10 + c
- '0';
1458 i
= va_arg(args
, int);
1467 val
= va_arg(args
, unsigned int);
1471 val
= va_arg(args
, unsigned int);
1475 val
= (unsigned long) va_arg(args
, void *);
1480 str
= va_arg(args
, char *);
1483 num
[0] = va_arg(args
, int);
1488 str
= strerror(errno
);
1491 str
= ip_ntoa(va_arg(args
, u_int32_t
));
1494 f
= va_arg(args
, char *);
1495 #if !defined(__powerpc__) && !defined(__amd64__)
1496 n
= vfmtmsg(buf
, buflen
+ 1, f
, va_arg(args
, va_list));
1498 /* On the powerpc, a va_list is an array of 1 structure */
1499 n
= vfmtmsg(buf
, buflen
+ 1, f
, va_arg(args
, void *));
1507 str
+= 4; /* chop off the day name */
1508 str
[15] = 0; /* chop off year and newline */
1510 case 'v': /* "visible" string */
1511 case 'q': /* quoted string */
1513 p
= va_arg(args
, unsigned char *);
1514 if (fillch
== '0' && prec
> 0) {
1517 n
= strlen((char *)p
);
1518 if (prec
> 0 && prec
< n
)
1521 while (n
> 0 && buflen
> 0) {
1524 if (!quoted
&& c
>= 0x80) {
1529 if (quoted
&& (c
== '"' || c
== '\\'))
1531 if (c
< 0x20 || (0x7f <= c
&& c
< 0xa0)) {
1535 case '\t': OUTCHAR('t'); break;
1536 case '\n': OUTCHAR('n'); break;
1537 case '\b': OUTCHAR('b'); break;
1538 case '\f': OUTCHAR('f'); break;
1541 OUTCHAR(hexchars
[c
>> 4]);
1542 OUTCHAR(hexchars
[c
& 0xf]);
1559 --fmt
; /* so %z outputs %z etc. */
1564 str
= num
+ sizeof(num
);
1566 while (str
> num
+ neg
) {
1567 *--str
= hexchars
[val
% base
];
1569 if (--prec
<= 0 && val
== 0)
1581 len
= num
+ sizeof(num
) - 1 - str
;
1584 if (prec
> 0 && len
> prec
)
1590 if ((n
= width
- len
) > 0) {
1598 memcpy(buf
, str
, len
);
1607 * script_setenv - set an environment variable value to be used
1608 * for scripts that we run (e.g. ip-up, auth-up, etc.)
1611 script_setenv(char *var
, char *value
)
1613 int vl
= strlen(var
);
1615 char *p
, *newstring
;
1617 newstring
= (char *) malloc(vl
+ strlen(value
) + 2);
1620 strcpy(newstring
, var
);
1621 newstring
[vl
] = '=';
1622 strcpy(newstring
+vl
+1, value
);
1624 /* check if this variable is already set */
1625 if (script_env
!= 0) {
1626 for (i
= 0; (p
= script_env
[i
]) != 0; ++i
) {
1627 if (strncmp(p
, var
, vl
) == 0 && p
[vl
] == '=') {
1629 script_env
[i
] = newstring
;
1635 script_env
= (char **) malloc(16 * sizeof(char *));
1636 if (script_env
== 0)
1641 /* reallocate script_env with more space if needed */
1642 if (i
+ 1 >= s_env_nalloc
) {
1644 char **newenv
= (char **) realloc((void *)script_env
,
1645 new_n
* sizeof(char *));
1648 script_env
= newenv
;
1649 s_env_nalloc
= new_n
;
1652 script_env
[i
] = newstring
;
1653 script_env
[i
+1] = 0;
1657 * script_unsetenv - remove a variable from the environment
1661 script_unsetenv(char *var
)
1663 int vl
= strlen(var
);
1667 if (script_env
== 0)
1669 for (i
= 0; (p
= script_env
[i
]) != 0; ++i
) {
1670 if (strncmp(p
, var
, vl
) == 0 && p
[vl
] == '=') {
1672 while ((script_env
[i
] = script_env
[i
+1]) != 0)