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 $
34 #include <sys/param.h>
35 #include <sys/types.h>
38 #include <sys/resource.h>
40 #include <sys/socket.h>
50 #include "pathnames.h"
51 #include "patchlevel.h"
58 extern char *strerror();
63 #endif /* IPX_CHANGE */
69 char ifname
[32]; /* Interface name */
70 int ifunit
; /* Interface unit number */
72 char *progname
; /* Name of this program */
73 char hostname
[MAXNAMELEN
]; /* Our hostname */
74 static char pidfilename
[MAXPATHLEN
]; /* name of pid file */
75 static char iffilename
[MAXPATHLEN
]; /* name of if file */
76 static char default_devnam
[MAXPATHLEN
]; /* name of default device */
77 static pid_t pid
; /* Our pid */
78 static uid_t uid
; /* Our real user-id */
79 time_t etime
,stime
; /* End and Start time */
80 int minutes
; /* connection duration */
81 static int conn_running
; /* we have a [dis]connector running */
83 int ttyfd
= -1; /* Serial port file descriptor */
84 mode_t tty_mode
= -1; /* Original access permissions to tty */
85 int baud_rate
; /* Actual bits/second for serial device */
86 int hungup
; /* terminal has been hung up */
87 int privileged
; /* we're running as real uid root */
88 int need_holdoff
; /* need holdoff period before restarting */
89 int detached
; /* have detached from terminal */
91 int phase
; /* where the link is at */
95 char **script_env
; /* Env. variable values for scripts */
96 int s_env_nalloc
; /* # words avail at script_env */
98 u_char outpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for outgoing packet */
99 u_char inpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for incoming packet */
101 static int n_children
; /* # child processes still running */
103 static int locked
; /* lock() has succeeded */
105 char *no_ppp_msg
= "Sorry - this system lacks PPP kernel support\n";
107 /* Prototypes for procedures local to this file. */
109 static void create_pidfile(void);
110 static void cleanup(void);
111 static void close_tty(void);
112 static void get_input(void);
113 static void calltimeout(void);
114 static struct timeval
*timeleft(struct timeval
*);
115 static void kill_my_pg(int);
116 static void hup(int);
117 static void term(int);
118 static void chld(int);
119 static void toggle_debug(int);
120 static void open_ccp(int);
121 static void bad_signal(int);
122 static void holdoff_end(void *);
123 static int device_script(char *, int, int);
124 static void reap_kids(void);
125 static void pr_log(void *, char *, ...);
127 extern char *ttyname(int);
128 extern char *getlogin(void);
132 #define O_NONBLOCK O_NDELAY
136 #define setlogmask(x)
140 * PPP Data Link Layer "protocol" table.
141 * One entry per supported protocol.
142 * The last entry must be NULL.
144 struct protent
*protocols
[] = {
163 main(int argc
, char *argv
[])
172 struct protent
*protp
;
174 int connect_attempts
= 0;
177 phase
= PHASE_INITIALIZE
;
181 strcpy(default_devnam
, devnam
);
185 /* Initialize syslog facilities */
187 openlog("pppd", LOG_PID
);
189 openlog("pppd", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
190 setlogmask(LOG_UPTO(LOG_INFO
));
193 if (gethostname(hostname
, MAXNAMELEN
) < 0 ) {
194 option_error("Couldn't get hostname: %m");
197 hostname
[MAXNAMELEN
-1] = 0;
200 privileged
= uid
== 0;
201 sprintf(numbuf
, "%d", uid
);
202 script_setenv("UID", numbuf
);
205 * Initialize to the standard option set, then parse, in order,
206 * the system options file, the user's options file,
207 * the tty's options file, and the command line arguments.
209 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
214 if (!options_from_file(_PATH_SYSOPTIONS
, !privileged
, 0, 1)
215 || !options_from_user())
217 scan_args(argc
-1, argv
+1); /* look for tty name on command line */
218 if (!options_for_tty()
219 || !parse_args(argc
-1, argv
+1))
223 * Check that we are running as root.
225 if (geteuid() != 0) {
226 option_error("must be root to run %s, since it is not setuid-root",
231 if (!ppp_available()) {
232 option_error(no_ppp_msg
);
237 * Check that the options given are valid and consistent.
240 auth_check_options();
241 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
242 if (protp
->check_options
!= NULL
)
243 (*protp
->check_options
)();
244 if (demand
&& connector
== 0) {
245 option_error("connect script required for demand-dialling\n");
249 script_setenv("DEVICE", devnam
);
250 sprintf(numbuf
, "%d", baud_rate
);
251 script_setenv("SPEED", numbuf
);
254 * If the user has specified the default device name explicitly,
255 * pretend they hadn't.
257 if (!default_device
&& strcmp(devnam
, default_devnam
) == 0)
263 * Initialize system-dependent stuff and magic number package.
268 setlogmask(LOG_UPTO(LOG_DEBUG
));
271 * Detach ourselves from the terminal, if required,
272 * and identify who is running us.
281 if (pw
!= NULL
&& pw
->pw_name
!= NULL
)
286 syslog(LOG_NOTICE
, "pppd %s.%d%s started by %s, uid %d",
287 VERSION
, PATCHLEVEL
, IMPLEMENTATION
, p
, uid
);
290 * Compute mask of all interesting signals and install signal handlers
291 * for each. Only one signal handler may be active at a time. Therefore,
292 * all other signals should be masked when any handler is executing.
295 sigaddset(&mask
, SIGHUP
);
296 sigaddset(&mask
, SIGINT
);
297 sigaddset(&mask
, SIGTERM
);
298 sigaddset(&mask
, SIGCHLD
);
300 #define SIGNAL(s, handler) { \
301 sa.sa_handler = handler; \
302 if (sigaction(s, &sa, NULL) < 0) { \
303 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \
310 SIGNAL(SIGHUP
, hup
); /* Hangup */
311 SIGNAL(SIGINT
, term
); /* Interrupt */
312 SIGNAL(SIGTERM
, term
); /* Terminate */
313 SIGNAL(SIGCHLD
, chld
);
315 SIGNAL(SIGUSR1
, toggle_debug
); /* Toggle debug flag */
316 SIGNAL(SIGUSR2
, open_ccp
); /* Reopen CCP */
319 * Install a handler for other signals which would otherwise
320 * cause pppd to exit without cleaning up.
322 SIGNAL(SIGABRT
, bad_signal
);
323 SIGNAL(SIGALRM
, bad_signal
);
324 SIGNAL(SIGFPE
, bad_signal
);
325 SIGNAL(SIGILL
, bad_signal
);
326 SIGNAL(SIGPIPE
, bad_signal
);
327 SIGNAL(SIGQUIT
, bad_signal
);
328 SIGNAL(SIGSEGV
, bad_signal
);
330 SIGNAL(SIGBUS
, bad_signal
);
333 SIGNAL(SIGEMT
, bad_signal
);
336 SIGNAL(SIGPOLL
, bad_signal
);
339 SIGNAL(SIGPROF
, bad_signal
);
342 SIGNAL(SIGSYS
, bad_signal
);
345 SIGNAL(SIGTRAP
, bad_signal
);
348 SIGNAL(SIGVTALRM
, bad_signal
);
351 SIGNAL(SIGXCPU
, bad_signal
);
354 SIGNAL(SIGXFSZ
, bad_signal
);
358 * Apparently we can get a SIGPIPE when we call syslog, if
359 * syslogd has died and been restarted. Ignoring it seems
362 signal(SIGPIPE
, SIG_IGN
);
365 * If we're doing dial-on-demand, set up the interface now.
369 * Open the loopback channel and set it up to be the ppp interface.
373 syslog(LOG_INFO
, "Using interface ppp%d", ifunit
);
374 sprintf(ifname
, "ppp%d", ifunit
);
375 script_setenv("IFNAME", ifname
);
377 create_pidfile(); /* write pid to file */
380 * Configure the interface and mark it up, etc.
391 * Don't do anything until we see some activity.
393 phase
= PHASE_DORMANT
;
397 wait_loop_output(timeleft(&timo
));
404 if (get_loop_output())
410 * Now we want to bring up the link.
413 syslog(LOG_INFO
, "Starting link");
417 * Lock the device if we've been asked to.
419 if (lockflag
&& !default_device
) {
420 if (lock(devnam
) < 0)
426 * Open the serial device and set it up to be the ppp interface.
427 * First we open it in non-blocking mode so we can set the
428 * various termios flags appropriately. If we aren't dialling
429 * out and we want to use the modem lines, we reopen it later
430 * in order to wait for the carrier detect signal from the modem.
432 while ((ttyfd
= open(devnam
, O_NONBLOCK
| O_RDWR
, 0)) < 0) {
434 syslog(LOG_ERR
, "Failed to open %s: %m", devnam
);
435 if (!persist
|| errno
!= EINTR
)
438 if ((fdflags
= fcntl(ttyfd
, F_GETFL
)) == -1
439 || fcntl(ttyfd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
441 "Couldn't reset non-blocking mode on device: %m");
447 * Do the equivalent of `mesg n' to stop broadcast messages.
449 if (fstat(ttyfd
, &statbuf
) < 0
450 || fchmod(ttyfd
, statbuf
.st_mode
& ~(S_IWGRP
| S_IWOTH
)) < 0) {
452 "Couldn't restrict write permissions to %s: %m", devnam
);
454 tty_mode
= statbuf
.st_mode
;
456 /* run connection script */
457 if (connector
&& connector
[0]) {
458 MAINDEBUG((LOG_INFO
, "Connecting with <%s>", connector
));
461 * Set line speed, flow control, etc.
462 * On most systems we set CLOCAL for now so that we can talk
463 * to the modem before carrier comes up. But this has the
464 * side effect that we might miss it if CD drops before we
465 * get to clear CLOCAL below. On systems where we can talk
466 * successfully to the modem with CLOCAL clear and CD down,
467 * we can clear CLOCAL at this point.
469 set_up_tty(ttyfd
, 1);
471 /* drop dtr to hang up in case modem is off hook */
472 if (!default_device
&& modem
) {
473 setdtr(ttyfd
, FALSE
);
478 if (device_script(connector
, ttyfd
, ttyfd
) < 0) {
479 syslog(LOG_ERR
, "Connect script failed");
480 setdtr(ttyfd
, FALSE
);
486 syslog(LOG_INFO
, "Serial connection established.");
487 sleep(1); /* give it time to set up its terminal */
490 connect_attempts
= 0; /* we made it through ok */
492 /* set line speed, flow control, etc.; clear CLOCAL if modem option */
493 set_up_tty(ttyfd
, 0);
495 /* reopen tty if necessary to wait for carrier */
496 if (connector
== NULL
&& modem
) {
497 while ((i
= open(devnam
, O_RDWR
)) < 0) {
499 syslog(LOG_ERR
, "Failed to reopen %s: %m", devnam
);
500 if (!persist
|| errno
!= EINTR
||
507 /* run welcome script, if any */
508 if (welcomer
&& welcomer
[0]) {
509 if (device_script(welcomer
, ttyfd
, ttyfd
) < 0)
510 syslog(LOG_WARNING
, "Welcome script failed");
513 /* set up the serial device as a ppp interface */
514 establish_ppp(ttyfd
);
518 syslog(LOG_INFO
, "Using interface ppp%d", ifunit
);
519 sprintf(ifname
, "ppp%d", ifunit
);
521 create_pidfile(); /* write pid to file */
523 /* write interface unit number to file */
524 for (n
= strlen(devnam
); n
> 0 ; n
--)
525 if (devnam
[n
] == '/') {
529 sprintf(iffilename
, "%s%s.if", _PATH_VARRUN
, &devnam
[n
]);
530 if ((iffile
= fopen(iffilename
, "w")) != NULL
) {
531 fprintf(iffile
, "ppp%d\n", ifunit
);
534 syslog(LOG_ERR
, "Failed to create if file %s: %m", iffilename
);
538 script_setenv("IFNAME", ifname
);
542 * Start opening the connection and wait for
543 * incoming events (reply, timeout, etc.).
545 syslog(LOG_NOTICE
, "Connect: %s <--> %s", ifname
, devnam
);
548 lcp_open(0); /* Start protocol */
549 for (phase
= PHASE_ESTABLISH
; phase
!= PHASE_DEAD
; ) {
550 wait_input(timeleft(&timo
));
554 lcp_close(0, "User request");
558 if (phase
== PHASE_NETWORK
) {
559 ccp_fsm
[0].flags
= OPT_RESTART
; /* clears OPT_SILENT */
560 (*ccp_protent
.open
)(0);
564 reap_kids(); /* Don't leave dead kids lying around */
568 * If we may want to bring the link up again, transfer
569 * the ppp unit back to the loopback. Set the
570 * real serial device back to its normal mode of operation.
575 disestablish_ppp(ttyfd
);
578 * Run disconnector script, if requested.
579 * XXX we may not be able to do this if the line has hung up!
581 if (disconnector
&& !hungup
) {
582 set_up_tty(ttyfd
, 1);
583 if (device_script(disconnector
, ttyfd
, ttyfd
) < 0) {
584 syslog(LOG_WARNING
, "disconnect script failed");
586 syslog(LOG_INFO
, "Serial link disconnected.");
599 if (pidfilename
[0] != 0
600 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
601 syslog(LOG_WARNING
, "unable to delete pid file: %m");
605 if (unlink(iffilename
) < 0 && errno
!= ENOENT
)
606 syslog(LOG_WARNING
, "unable to delete if file: %m");
610 /* limit to retries? */
611 if (max_con_attempts
)
612 if (connect_attempts
>= max_con_attempts
)
620 if (holdoff
> 0 && need_holdoff
) {
621 phase
= PHASE_HOLDOFF
;
622 TIMEOUT(holdoff_end
, NULL
, holdoff
);
624 wait_time(timeleft(&timo
));
630 phase
= PHASE_DORMANT
; /* allow signal to end holdoff */
633 } while (phase
== PHASE_HOLDOFF
);
642 * detach - detach us from the controlling terminal.
649 if (daemon(0, 0) < 0) {
650 perror("Couldn't detach from controlling terminal");
655 /* update pid file if it has been written already */
661 * Create a file containing our process ID.
668 sprintf(pidfilename
, "%s%s.pid", _PATH_VARRUN
, ifname
);
669 if ((pidfile
= fopen(pidfilename
, "w")) != NULL
) {
670 fprintf(pidfile
, "%d\n", pid
);
673 syslog(LOG_ERR
, "Failed to create pid file %s: %m", pidfilename
);
679 * holdoff_end - called via a timeout when the holdoff period ends.
682 holdoff_end(void *arg
)
684 phase
= PHASE_DORMANT
;
688 * get_input - called when incoming data is available.
696 struct protent
*protp
;
698 p
= inpacket_buf
; /* point to beginning of packet buffer */
700 len
= read_packet(inpacket_buf
);
706 minutes
= (etime
-stime
)/60;
707 syslog(LOG_NOTICE
, "Modem hangup, connected for %d minutes", (minutes
>1) ? minutes
: 1);
709 lcp_lowerdown(0); /* serial link is no longer available */
714 if (debug
/*&& (debugflags & DBG_INPACKET)*/)
715 log_packet(p
, len
, "rcvd ", LOG_DEBUG
);
717 if (len
< PPP_HDRLEN
) {
718 MAINDEBUG((LOG_INFO
, "io(): Received short packet."));
722 p
+= 2; /* Skip address and control */
723 GETSHORT(protocol
, p
);
727 * Toss all non-LCP packets unless LCP is OPEN.
729 if (protocol
!= PPP_LCP
&& lcp_fsm
[0].state
!= OPENED
) {
731 "get_input: Received non-LCP packet when LCP not open."));
736 * Until we get past the authentication phase, toss all packets
737 * except LCP, LQR and authentication packets.
739 if (phase
<= PHASE_AUTHENTICATE
740 && !(protocol
== PPP_LCP
|| protocol
== PPP_LQR
741 || protocol
== PPP_PAP
|| protocol
== PPP_CHAP
)) {
742 MAINDEBUG((LOG_INFO
, "get_input: discarding proto 0x%x in phase %d",
748 * Upcall the proper protocol input routine.
750 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
) {
751 if (protp
->protocol
== protocol
&& protp
->enabled_flag
) {
752 (*protp
->input
)(0, p
, len
);
755 if (protocol
== (protp
->protocol
& ~0x8000) && protp
->enabled_flag
756 && protp
->datainput
!= NULL
) {
757 (*protp
->datainput
)(0, p
, len
);
763 syslog(LOG_WARNING
, "Unsupported protocol (0x%x) received", protocol
);
764 lcp_sprotrej(0, p
- PPP_HDRLEN
, len
+ PPP_HDRLEN
);
769 * quit - Clean up state and exit (with an error indication).
778 * die - like quit, except we can specify an exit status.
784 syslog(LOG_INFO
, "Exit.");
789 * cleanup - restore anything which needs to be restored before we exit
800 if (pidfilename
[0] != 0 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
801 syslog(LOG_WARNING
, "unable to delete pid file: %m");
809 * close_tty - restore the terminal device and close it.
814 disestablish_ppp(ttyfd
);
816 /* drop dtr to hang up */
818 setdtr(ttyfd
, FALSE
);
820 * This sleep is in case the serial port has CLOCAL set by default,
821 * and consequently will reassert DTR when we close the device.
828 if (tty_mode
!= (mode_t
) -1)
829 fchmod(ttyfd
, tty_mode
);
837 struct timeval c_time
; /* time at which to call routine */
838 void *c_arg
; /* argument to routine */
839 void (*c_func
)(void *); /* routine */
840 struct callout
*c_next
;
843 static struct callout
*callout
= NULL
; /* Callout list */
844 static struct timeval timenow
; /* Current time */
847 * timeout - Schedule a timeout.
849 * Note that this timeout takes the number of seconds, NOT hz (as in
853 timeout(void (*func
)(void *), void *arg
, int time
)
855 struct callout
*newp
, *p
, **pp
;
857 MAINDEBUG((LOG_DEBUG
, "Timeout %lx:%lx in %d seconds.",
858 (long) func
, (long) arg
, time
));
863 if ((newp
= (struct callout
*) malloc(sizeof(struct callout
))) == NULL
) {
864 syslog(LOG_ERR
, "Out of memory in timeout()!");
869 gettimeofday(&timenow
, NULL
);
870 newp
->c_time
.tv_sec
= timenow
.tv_sec
+ time
;
871 newp
->c_time
.tv_usec
= timenow
.tv_usec
;
874 * Find correct place and link it in.
876 for (pp
= &callout
; (p
= *pp
); pp
= &p
->c_next
)
877 if (newp
->c_time
.tv_sec
< p
->c_time
.tv_sec
878 || (newp
->c_time
.tv_sec
== p
->c_time
.tv_sec
879 && newp
->c_time
.tv_usec
< p
->c_time
.tv_sec
))
887 * untimeout - Unschedule a timeout.
890 untimeout(void (*func
)(void *), void *arg
)
892 struct callout
**copp
, *freep
;
894 MAINDEBUG((LOG_DEBUG
, "Untimeout %lx:%lx.", (long) func
, (long) arg
));
897 * Find first matching timeout and remove it from the list.
899 for (copp
= &callout
; (freep
= *copp
); copp
= &freep
->c_next
)
900 if (freep
->c_func
== func
&& freep
->c_arg
== arg
) {
901 *copp
= freep
->c_next
;
902 free((char *) freep
);
909 * calltimeout - Call any timeout routines which are now due.
916 while (callout
!= NULL
) {
919 if (gettimeofday(&timenow
, NULL
) < 0) {
920 syslog(LOG_ERR
, "Failed to get time of day: %m");
923 if (!(p
->c_time
.tv_sec
< timenow
.tv_sec
924 || (p
->c_time
.tv_sec
== timenow
.tv_sec
925 && p
->c_time
.tv_usec
<= timenow
.tv_usec
)))
926 break; /* no, it's not time yet */
929 (*p
->c_func
)(p
->c_arg
);
937 * timeleft - return the length of time until the next timeout is due.
939 static struct timeval
*
940 timeleft(struct timeval
*tvp
)
945 gettimeofday(&timenow
, NULL
);
946 tvp
->tv_sec
= callout
->c_time
.tv_sec
- timenow
.tv_sec
;
947 tvp
->tv_usec
= callout
->c_time
.tv_usec
- timenow
.tv_usec
;
948 if (tvp
->tv_usec
< 0) {
949 tvp
->tv_usec
+= 1000000;
953 tvp
->tv_sec
= tvp
->tv_usec
= 0;
960 * kill_my_pg - send a signal to our process group, and ignore it ourselves.
965 struct sigaction act
, oldact
;
967 act
.sa_handler
= SIG_IGN
;
970 sigaction(sig
, &act
, &oldact
);
971 sigaction(sig
, &oldact
, NULL
);
976 * hup - Catch SIGHUP signal.
978 * Indicates that the physical layer has been disconnected.
979 * We don't rely on this indication; if the user has sent this
980 * signal, we just take the link down.
985 syslog(LOG_INFO
, "Hangup (SIGHUP)");
988 /* Send the signal to the [dis]connector process(es) also */
994 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
996 * Indicates that we should initiate a graceful disconnect and exit.
1002 syslog(LOG_INFO
, "Terminating on signal %d.", sig
);
1003 persist
= 0; /* don't try to restart */
1006 /* Send the signal to the [dis]connector process(es) also */
1012 * chld - Catch SIGCHLD signal.
1013 * Calls reap_kids to get status for any dead kids.
1023 * toggle_debug - Catch SIGUSR1 signal.
1025 * Toggle debug flag.
1029 toggle_debug(int sig
)
1033 setlogmask(LOG_UPTO(LOG_DEBUG
));
1035 setlogmask(LOG_UPTO(LOG_WARNING
));
1041 * open_ccp - Catch SIGUSR2 signal.
1043 * Try to (re)negotiate compression.
1054 * bad_signal - We've caught a fatal signal. Clean up state and exit.
1059 static int crashed
= 0;
1064 syslog(LOG_ERR
, "Fatal signal %d", sig
);
1066 kill_my_pg(SIGTERM
);
1072 * device_script - run a program to connect or disconnect the
1076 device_script(char *program
, int in
, int out
)
1087 syslog(LOG_ERR
, "Failed to create child process: %m");
1112 if (nodetach
== 0) {
1114 errfd
= open(_PATH_CONNERRS
, O_WRONLY
| O_APPEND
| O_CREAT
, 0600);
1115 if (errfd
>= 0 && errfd
!= 2) {
1122 execl("/bin/sh", "sh", "-c", program
, NULL
);
1123 syslog(LOG_ERR
, "could not exec /bin/sh: %m");
1128 while (waitpid(pid
, &status
, 0) < 0) {
1131 syslog(LOG_ERR
, "error waiting for (dis)connection process: %m");
1136 return (status
== 0 ? 0 : -1);
1141 * run-program - execute a program with given arguments,
1142 * but don't wait for it.
1143 * If the program can't be executed, logs an error unless
1144 * must_exist is 0 and the program file doesn't exist.
1147 run_program(char *prog
, char **args
, int must_exist
)
1153 syslog(LOG_ERR
, "Failed to create child process for %s: %m", prog
);
1159 /* Leave the current location */
1160 setsid(); /* No controlling tty. */
1161 umask (S_IRWXG
|S_IRWXO
);
1162 chdir ("/"); /* no current directory. */
1166 /* Ensure that nothing of our device environment is inherited. */
1172 close (ttyfd
); /* tty interface to the ppp device */
1174 /* Don't pass handles to the PPP device, even by accident. */
1175 new_fd
= open (_PATH_DEVNULL
, O_RDWR
);
1178 dup2 (new_fd
, 0); /* stdin <- /dev/null */
1181 dup2 (0, 1); /* stdout -> /dev/null */
1182 dup2 (0, 2); /* stderr -> /dev/null */
1186 /* Force the priority back to zero if pppd is running higher. */
1187 if (setpriority (PRIO_PROCESS
, 0, 0) < 0)
1188 syslog (LOG_WARNING
, "can't reset priority to 0: %m");
1191 /* SysV recommends a second fork at this point. */
1193 /* run the program; give it a null environment */
1194 execve(prog
, args
, script_env
);
1195 if (must_exist
|| errno
!= ENOENT
)
1196 syslog(LOG_WARNING
, "Can't execute %s: %m", prog
);
1199 MAINDEBUG((LOG_DEBUG
, "Script %s started; pid = %d", prog
, pid
));
1206 * reap_kids - get status from any dead child processes,
1207 * and log a message for abnormal terminations.
1214 if (n_children
== 0)
1216 if ((pid
= waitpid(-1, &status
, WNOHANG
)) == -1) {
1217 if (errno
!= ECHILD
)
1218 syslog(LOG_ERR
, "Error waiting for child process: %m");
1223 if (WIFSIGNALED(status
)) {
1224 syslog(LOG_WARNING
, "Child process %d terminated with signal %d",
1225 pid
, WTERMSIG(status
));
1232 * log_packet - format a packet and log it.
1235 char line
[256]; /* line to be logged accumulated here */
1239 log_packet(u_char
*p
, int len
, char *prefix
, int level
)
1241 strcpy(line
, prefix
);
1242 linep
= line
+ strlen(line
);
1243 format_packet(p
, len
, pr_log
, NULL
);
1245 syslog(level
, "%s", line
);
1249 * format_packet - make a readable representation of a packet,
1250 * calling `printer(arg, format, ...)' to output it.
1253 format_packet(u_char
*p
, int len
, void (*printer
)(void *, char *, ...),
1259 struct protent
*protp
;
1261 if (len
>= PPP_HDRLEN
&& p
[0] == PPP_ALLSTATIONS
&& p
[1] == PPP_UI
) {
1265 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
1266 if (proto
== protp
->protocol
)
1268 if (protp
!= NULL
) {
1269 printer(arg
, "[%s", protp
->name
);
1270 n
= (*protp
->printpkt
)(p
, len
, printer
, arg
);
1275 printer(arg
, "[proto=0x%x]", proto
);
1279 for (; len
> 0; --len
) {
1281 printer(arg
, " %.2x", x
);
1286 pr_log
__V((void *arg
, char *fmt
, ...))
1293 va_start(pvar
, fmt
);
1298 arg
= va_arg(pvar
, void *);
1299 fmt
= va_arg(pvar
, char *);
1302 n
= vfmtmsg(buf
, sizeof(buf
), fmt
, pvar
);
1305 if (linep
+ n
+ 1 > line
+ sizeof(line
)) {
1306 syslog(LOG_DEBUG
, "%s", line
);
1314 * print_string - print a readable representation of a string using
1318 print_string(char *p
, int len
, void (*printer
)(void *, char *, ...),
1324 for (; len
> 0; --len
) {
1326 if (' ' <= c
&& c
<= '~') {
1327 if (c
== '\\' || c
== '"')
1329 printer(arg
, "%c", c
);
1333 printer(arg
, "\\n");
1336 printer(arg
, "\\r");
1339 printer(arg
, "\\t");
1342 printer(arg
, "\\%.3o", c
);
1350 * novm - log an error message saying we ran out of memory, and die.
1355 syslog(LOG_ERR
, "Virtual memory exhausted allocating %s\n", msg
);
1360 * fmtmsg - format a message into a buffer. Like sprintf except we
1361 * also specify the length of the output buffer, and we handle
1362 * %r (recursive format), %m (error message) and %I (IP address) formats.
1363 * Doesn't do floating-point formats.
1364 * Returns the number of chars put into buf.
1367 fmtmsg
__V((char *buf
, int buflen
, char *fmt
, ...))
1373 va_start(args
, fmt
);
1379 buf
= va_arg(args
, char *);
1380 buflen
= va_arg(args
, int);
1381 fmt
= va_arg(args
, char *);
1383 n
= vfmtmsg(buf
, buflen
, fmt
, args
);
1389 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
1391 #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
1394 vfmtmsg(char *buf
, int buflen
, char *fmt
, va_list args
)
1397 int width
, prec
, fillch
;
1398 int base
, len
, neg
, quoted
;
1399 unsigned long val
= 0;
1400 char *str
, *f
, *buf0
;
1404 static char hexchars
[] = "0123456789abcdef";
1408 while (buflen
> 0) {
1409 for (f
= fmt
; *f
!= '%' && *f
!= 0; ++f
)
1415 memcpy(buf
, fmt
, len
);
1430 width
= va_arg(args
, int);
1433 while (isdigit(c
)) {
1434 width
= width
* 10 + c
- '0';
1441 prec
= va_arg(args
, int);
1444 while (isdigit(c
)) {
1445 prec
= prec
* 10 + c
- '0';
1456 i
= va_arg(args
, int);
1465 val
= va_arg(args
, unsigned int);
1469 val
= va_arg(args
, unsigned int);
1473 val
= (unsigned long) va_arg(args
, void *);
1478 str
= va_arg(args
, char *);
1481 num
[0] = va_arg(args
, int);
1486 str
= strerror(errno
);
1489 str
= ip_ntoa(va_arg(args
, u_int32_t
));
1492 f
= va_arg(args
, char *);
1493 #if !defined(__powerpc__) && !defined(__x86_64__)
1494 n
= vfmtmsg(buf
, buflen
+ 1, f
, va_arg(args
, va_list));
1496 /* On the powerpc, a va_list is an array of 1 structure */
1497 n
= vfmtmsg(buf
, buflen
+ 1, f
, va_arg(args
, void *));
1505 str
+= 4; /* chop off the day name */
1506 str
[15] = 0; /* chop off year and newline */
1508 case 'v': /* "visible" string */
1509 case 'q': /* quoted string */
1511 p
= va_arg(args
, unsigned char *);
1512 if (fillch
== '0' && prec
> 0) {
1515 n
= strlen((char *)p
);
1516 if (prec
> 0 && prec
< n
)
1519 while (n
> 0 && buflen
> 0) {
1522 if (!quoted
&& c
>= 0x80) {
1527 if (quoted
&& (c
== '"' || c
== '\\'))
1529 if (c
< 0x20 || (0x7f <= c
&& c
< 0xa0)) {
1533 case '\t': OUTCHAR('t'); break;
1534 case '\n': OUTCHAR('n'); break;
1535 case '\b': OUTCHAR('b'); break;
1536 case '\f': OUTCHAR('f'); break;
1539 OUTCHAR(hexchars
[c
>> 4]);
1540 OUTCHAR(hexchars
[c
& 0xf]);
1557 --fmt
; /* so %z outputs %z etc. */
1562 str
= num
+ sizeof(num
);
1564 while (str
> num
+ neg
) {
1565 *--str
= hexchars
[val
% base
];
1567 if (--prec
<= 0 && val
== 0)
1579 len
= num
+ sizeof(num
) - 1 - str
;
1582 if (prec
> 0 && len
> prec
)
1588 if ((n
= width
- len
) > 0) {
1596 memcpy(buf
, str
, len
);
1605 * script_setenv - set an environment variable value to be used
1606 * for scripts that we run (e.g. ip-up, auth-up, etc.)
1609 script_setenv(char *var
, char *value
)
1611 int vl
= strlen(var
);
1613 char *p
, *newstring
;
1615 newstring
= (char *) malloc(vl
+ strlen(value
) + 2);
1616 if (newstring
== NULL
)
1618 strcpy(newstring
, var
);
1619 newstring
[vl
] = '=';
1620 strcpy(newstring
+vl
+1, value
);
1622 /* check if this variable is already set */
1623 if (script_env
!= NULL
) {
1624 for (i
= 0; (p
= script_env
[i
]) != NULL
; ++i
) {
1625 if (strncmp(p
, var
, vl
) == 0 && p
[vl
] == '=') {
1627 script_env
[i
] = newstring
;
1633 script_env
= (char **) malloc(16 * sizeof(char *));
1634 if (script_env
== NULL
)
1639 /* reallocate script_env with more space if needed */
1640 if (i
+ 1 >= s_env_nalloc
) {
1642 char **newenv
= (char **) realloc((void *)script_env
,
1643 new_n
* sizeof(char *));
1646 script_env
= newenv
;
1647 s_env_nalloc
= new_n
;
1650 script_env
[i
] = newstring
;
1651 script_env
[i
+1] = NULL
;
1655 * script_unsetenv - remove a variable from the environment
1659 script_unsetenv(char *var
)
1661 int vl
= strlen(var
);
1665 if (script_env
== NULL
)
1667 for (i
= 0; (p
= script_env
[i
]) != NULL
; ++i
) {
1668 if (strncmp(p
, var
, vl
) == 0 && p
[vl
] == '=') {
1670 while ((script_env
[i
] = script_env
[i
+1]) != NULL
)