summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
c4aa99c)
having with leaking fds and with fatal errors occurring when the link
goes down.
Updated patchlevel.h to 2.4.2b2.
Moved open of /dev/ppp to generic_establish_ppp; we now close the
ppp_dev_fd in generic_disestablish_ppp rather than trying to use
PPPIOCDETACH.
*_send_config and *_recv_config now return 0 for success or -1 for
error, rather than calling fatal() when an error occurs.
Added a notifier for when we fork so plugins can close their fds in
the child.
Added a safe_fork() which does a fork and then closes stuff in the
child; the parent waits until the child has done that.
On detach, the parent rewrites the pid files rather than the child,
and the child waits for the parent to die.
Fixed some potential FILE * leaks.
Also moved auth_number() check into auth_check_options.
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: auth.c,v 1.92 2003/02/16 22:29:50 paulus Exp $"
+#define RCSID "$Id: auth.c,v 1.93 2003/03/03 05:11:45 paulus Exp $"
#include <stdio.h>
#include <stddef.h>
#include <stdio.h>
#include <stddef.h>
/* get username */
if (fgets(u, MAXNAMELEN - 1, ufile) == NULL
/* get username */
if (fgets(u, MAXNAMELEN - 1, ufile) == NULL
- || fgets(p, MAXSECRETLEN - 1, ufile) == NULL){
+ || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) {
+ fclose(ufile);
option_error("unable to read user login data file %s", fname);
return 0;
}
option_error("unable to read user login data file %s", fname);
return 0;
}
+
+ /*
+ * Early check for remote number authorization.
+ */
+ if (!auth_number()) {
+ warn("calling number %q is not authorized", remote_number);
+ exit(EXIT_CNID_AUTH_FAILED);
+ }
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: demand.c,v 1.16 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID "$Id: demand.c,v 1.17 2003/03/03 05:11:45 paulus Exp $"
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
fcs = PPP_INITFCS;
netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
fcs = PPP_INITFCS;
netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
- ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
- ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+ if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0
+ || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0)
+ fatal("Couldn't set up demand-dialled PPP interface: %m");
#ifdef PPP_FILTER
set_filters(&pass_filter, &active_filter);
#ifdef PPP_FILTER
set_filters(&pass_filter, &active_filter);
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: lcp.c,v 1.64 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID "$Id: lcp.c,v 1.65 2003/03/03 05:11:46 paulus Exp $"
* but accept A/C and protocol compressed packets
* if we are going to ask for A/C and protocol compression.
*/
* but accept A/C and protocol compressed packets
* if we are going to ask for A/C and protocol compression.
*/
- ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
- ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
- wo->neg_pcompression, wo->neg_accompression);
+ if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
+ || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
+ wo->neg_pcompression, wo->neg_accompression) < 0)
+ return;
peer_mru[unit] = PPP_MRU;
if (listen_time != 0) {
peer_mru[unit] = PPP_MRU;
if (listen_time != 0) {
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: main.c,v 1.122 2003/02/24 12:46:37 fcusack Exp $"
+#define RCSID "$Id: main.c,v 1.123 2003/03/03 05:11:46 paulus Exp $"
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#include <ctype.h>
struct notifier *phasechange = NULL;
struct notifier *exitnotify = NULL;
struct notifier *sigreceived = NULL;
struct notifier *phasechange = NULL;
struct notifier *exitnotify = NULL;
struct notifier *sigreceived = NULL;
+struct notifier *fork_notifier = NULL;
int hungup; /* terminal has been hung up */
int privileged; /* we're running as real uid root */
int hungup; /* terminal has been hung up */
int privileged; /* we're running as real uid root */
static int devfd; /* fd of underlying device */
static int fd_ppp = -1; /* fd for talking PPP */
static int fd_loop; /* fd for getting demand-dial packets */
static int devfd; /* fd of underlying device */
static int fd_ppp = -1; /* fd for talking PPP */
static int fd_loop; /* fd for getting demand-dial packets */
+static int fd_devnull; /* fd for /dev/null */
int phase; /* where the link is at */
int kill_link;
int phase; /* where the link is at */
int kill_link;
/* Prototypes for procedures local to this file. */
static void setup_signals __P((void));
/* Prototypes for procedures local to this file. */
static void setup_signals __P((void));
-static void create_pidfile __P((void));
-static void create_linkpidfile __P((void));
+static void create_pidfile __P((int pid));
+static void create_linkpidfile __P((int pid));
static void cleanup __P((void));
static void get_input __P((void));
static void calltimeout __P((void));
static void cleanup __P((void));
static void get_input __P((void));
static void calltimeout __P((void));
link_stats_valid = 0;
new_phase(PHASE_INITIALIZE);
link_stats_valid = 0;
new_phase(PHASE_INITIALIZE);
- /*
- * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
- * This way we can close 0, 1, 2 in detach() without clobbering
- * a fd that we are using.
- */
- if ((i = open("/dev/null", O_RDWR)) >= 0) {
- while (0 <= i && i <= 2)
- i = dup(i);
- if (i >= 0)
- close(i);
- }
-
script_env = NULL;
/* Initialize syslog facilities */
script_env = NULL;
/* Initialize syslog facilities */
- /*
- * Early check for remote number authorization.
- */
- if (!auth_number()) {
- warn("calling number %q is not authorized", remote_number);
- exit(EXIT_CNID_AUTH_FAILED);
- }
-
+ /* Make sure fds 0, 1, 2 are open to somewhere. */
+ fd_devnull = open(_PATH_DEVNULL, O_RDWR);
+ if (fd_devnull < 0)
+ fatal("Couldn't open %s: %m", _PATH_DEVNULL);
+ while (fd_devnull <= 2) {
+ i = dup(fd_devnull);
+ if (i < 0)
+ fatal("Critical shortage of file descriptors: dup failed: %m");
+ fd_devnull = i;
+ }
+
#ifdef USE_TDB
pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
if (pppdb != NULL) {
#ifdef USE_TDB
pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
if (pppdb != NULL) {
+ create_linkpidfile(getpid());
/*
* If we're doing dial-on-demand, set up the interface now.
/*
* If we're doing dial-on-demand, set up the interface now.
slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
script_setenv("IFNAME", ifname, iskey);
if (iskey) {
slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
script_setenv("IFNAME", ifname, iskey);
if (iskey) {
- create_pidfile(); /* write pid to file */
- create_linkpidfile();
+ create_pidfile(getpid()); /* write pid to file */
+ create_linkpidfile(getpid());
{
int pid;
char numbuf[16];
{
int pid;
char numbuf[16];
+ if (pipe(pipefd) == -1)
+ pipefd[0] = pipefd[1] = -1;
if ((pid = fork()) < 0) {
error("Couldn't detach (fork failed: %m)");
die(1); /* or just return? */
if ((pid = fork()) < 0) {
error("Couldn't detach (fork failed: %m)");
die(1); /* or just return? */
if (pid != 0) {
/* parent */
notify(pidchange, pid);
if (pid != 0) {
/* parent */
notify(pidchange, pid);
+ /* update pid files if they have been written already */
+ if (pidfilename[0])
+ create_pidfile(pid);
+ if (linkpidfile[0])
+ create_linkpidfile(pid);
exit(0); /* parent dies */
}
setsid();
chdir("/");
exit(0); /* parent dies */
}
setsid();
chdir("/");
- close(0);
- close(1);
- close(2);
+ dup2(fd_devnull, 0);
+ dup2(fd_devnull, 1);
+ dup2(fd_devnull, 2);
detached = 1;
if (log_default)
log_to_fd = -1;
detached = 1;
if (log_default)
log_to_fd = -1;
- /* update pid files if they have been written already */
- if (pidfilename[0])
- create_pidfile();
- if (linkpidfile[0])
- create_linkpidfile();
slprintf(numbuf, sizeof(numbuf), "%d", getpid());
script_setenv("PPPD_PID", numbuf, 1);
slprintf(numbuf, sizeof(numbuf), "%d", getpid());
script_setenv("PPPD_PID", numbuf, 1);
+
+ /* wait for parent to finish updating pid & lock files and die */
+ close(pipefd[1]);
+ read(pipefd[0], numbuf, 1);
+ close(pipefd[0]);
* Create a file containing our process ID.
*/
static void
* Create a file containing our process ID.
*/
static void
+create_pidfile(pid)
+ int pid;
+create_linkpidfile(pid)
+ int pid;
+/*
+ * safe_fork - Create a child process. The child closes all the
+ * file descriptors that we don't want to leak to a script.
+ * The parent waits for the child to do this before returning.
+ */
+pid_t
+safe_fork()
+{
+ pid_t pid;
+ int pipefd[2];
+ char buf[1];
+
+ if (pipe(pipefd) == -1)
+ pipefd[0] = pipefd[1] = -1;
+ pid = fork();
+ if (pid < 0)
+ return -1;
+ if (pid > 0) {
+ close(pipefd[1]);
+ /* this read() blocks until the close(pipefd[1]) below */
+ read(pipefd[0], buf, 1);
+ close(pipefd[0]);
+ return pid;
+ }
+ sys_close();
+#ifdef USE_TDB
+ tdb_close(pppdb);
+#endif
+ notify(fork_notifier, 0);
+ close(pipefd[0]);
+ /* this close unblocks the read() call above in the parent */
+ close(pipefd[1]);
+ return 0;
+}
/*
* device_script - run a program to talk to the specified fds
/*
* device_script - run a program to talk to the specified fds
int in, out;
int dont_wait;
{
int in, out;
int dont_wait;
{
int status = -1;
int errfd;
++conn_running;
int status = -1;
int errfd;
++conn_running;
if (pid < 0) {
--conn_running;
if (pid < 0) {
--conn_running;
}
/* here we are executing in the child */
}
/* here we are executing in the child */
- /* make sure fds 0, 1, 2 are occupied */
- while ((fd = dup(in)) >= 0) {
- if (fd > 2) {
- close(fd);
- break;
- }
- }
/* dup in and out to fds > 2 */
{
/* dup in and out to fds > 2 */
{
close(0);
close(1);
close(2);
close(0);
close(1);
close(2);
if (the_channel->close)
(*the_channel->close)();
closelog();
if (the_channel->close)
(*the_channel->close)();
closelog();
/* dup the in, out, err fds to 0, 1, 2 */
dup2(in, 0);
/* dup the in, out, err fds to 0, 1, 2 */
dup2(in, 0);
if (pid == -1) {
error("Failed to create child process for %s: %m", prog);
return -1;
}
if (pid == -1) {
error("Failed to create child process for %s: %m", prog);
return -1;
}
- if (pid == 0) {
- int new_fd;
+ if (pid != 0) {
+ if (debug)
+ dbglog("Script %s started (pid %d)", prog, pid);
+ record_child(pid, prog, done, arg);
+ return pid;
+ }
- /* Leave the current location */
- (void) setsid(); /* No controlling tty. */
- (void) umask (S_IRWXG|S_IRWXO);
- (void) chdir ("/"); /* no current directory. */
- setuid(0); /* set real UID = root */
- setgid(getegid());
+ /* Leave the current location */
+ (void) setsid(); /* No controlling tty. */
+ (void) umask (S_IRWXG|S_IRWXO);
+ (void) chdir ("/"); /* no current directory. */
+ setuid(0); /* set real UID = root */
+ setgid(getegid());
- /* Ensure that nothing of our device environment is inherited. */
- sys_close();
- closelog();
- close (0);
- close (1);
- close (2);
- if (the_channel->close)
- (*the_channel->close)();
-
- /* Don't pass handles to the PPP device, even by accident. */
- new_fd = open (_PATH_DEVNULL, O_RDWR);
- if (new_fd >= 0) {
- if (new_fd != 0) {
- dup2 (new_fd, 0); /* stdin <- /dev/null */
- close (new_fd);
- }
- dup2 (0, 1); /* stdout -> /dev/null */
- dup2 (0, 2); /* stderr -> /dev/null */
- }
+ /* Ensure that nothing of our device environment is inherited. */
+ closelog();
+ if (the_channel->close)
+ (*the_channel->close)();
+
+ /* Don't pass handles to the PPP device, even by accident. */
+ dup2(fd_devnull, 0);
+ dup2(fd_devnull, 1);
+ dup2(fd_devnull, 2);
+ close(fd_devnull);
- /* Force the priority back to zero if pppd is running higher. */
- if (setpriority (PRIO_PROCESS, 0, 0) < 0)
- warn("can't reset priority to 0: %m");
+ /* Force the priority back to zero if pppd is running higher. */
+ if (setpriority (PRIO_PROCESS, 0, 0) < 0)
+ warn("can't reset priority to 0: %m");
- /* SysV recommends a second fork at this point. */
+ /* SysV recommends a second fork at this point. */
- /* run the program */
- execve(prog, args, script_env);
- if (must_exist || errno != ENOENT) {
- /* have to reopen the log, there's nowhere else
- for the message to go. */
- reopen_log();
- syslog(LOG_ERR, "Can't execute %s: %m", prog);
- closelog();
- }
- _exit(-1);
+ /* run the program */
+ execve(prog, args, script_env);
+ if (must_exist || errno != ENOENT) {
+ /* have to reopen the log, there's nowhere else
+ for the message to go. */
+ reopen_log();
+ syslog(LOG_ERR, "Can't execute %s: %m", prog);
+ closelog();
-
- if (debug)
- dbglog("Script %s started (pid %d)", prog, pid);
- record_child(pid, prog, done, arg);
-
- return pid;
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: options.c,v 1.90 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID "$Id: options.c,v 1.91 2003/03/03 05:11:46 paulus Exp $"
#include <ctype.h>
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
static int
setlogfile(argv)
char **argv;
static int
setlogfile(argv)
char **argv;
log_default = 0;
return 1;
}
log_default = 0;
return 1;
}
#ifdef MAXOCTETS
static int
setmodir(argv)
#ifdef MAXOCTETS
static int
setmodir(argv)
-/* $Id: patchlevel.h,v 1.55 2003/02/16 22:31:41 paulus Exp $ */
+/* $Id: patchlevel.h,v 1.56 2003/03/03 05:11:46 paulus Exp $ */
-#define VERSION "2.4.2b1"
-#define DATE "17 February 2003"
+#define VERSION "2.4.2b2"
+#define DATE "3 March 2003"
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: pppd.h,v 1.79 2003/02/16 22:26:27 paulus Exp $
+ * $Id: pppd.h,v 1.80 2003/03/03 05:11:46 paulus Exp $
extern struct notifier *ip_down_notifier; /* IPCP has gone down */
extern struct notifier *auth_up_notifier; /* peer has authenticated */
extern struct notifier *link_down_notifier; /* link has gone down */
extern struct notifier *ip_down_notifier; /* IPCP has gone down */
extern struct notifier *auth_up_notifier; /* peer has authenticated */
extern struct notifier *link_down_notifier; /* link has gone down */
+extern struct notifier *fork_notifier; /* we are a new child process */
/* Values for do_callback and doing_callback */
#define CALLBACK_DIALIN 1 /* we are expecting the call back */
/* Values for do_callback and doing_callback */
#define CALLBACK_DIALIN 1 /* we are expecting the call back */
/* take the channel out of PPP `mode', restore loopback if demand */
void (*disestablish_ppp) __P((int));
/* set the transmit-side PPP parameters of the channel */
/* take the channel out of PPP `mode', restore loopback if demand */
void (*disestablish_ppp) __P((int));
/* set the transmit-side PPP parameters of the channel */
- void (*send_config) __P((int, u_int32_t, int, int));
+ int (*send_config) __P((int, u_int32_t, int, int));
/* set the receive-side PPP parameters of the channel */
/* set the receive-side PPP parameters of the channel */
- void (*recv_config) __P((int, u_int32_t, int, int));
+ int (*recv_config) __P((int, u_int32_t, int, int));
/* cleanup on error or normal exit */
void (*cleanup) __P((void));
/* close the device, called in children after fork */
/* cleanup on error or normal exit */
void (*cleanup) __P((void));
/* close the device, called in children after fork */
extern struct channel *the_channel;
#define ppp_send_config(unit, mtu, accm, pc, acc) \
extern struct channel *the_channel;
#define ppp_send_config(unit, mtu, accm, pc, acc) \
-do { \
- if (the_channel->send_config) \
- (*the_channel->send_config)((mtu), (accm), (pc), (acc)); \
-} while (0)
+ (the_channel->send_config? \
+ (*the_channel->send_config)((mtu), (accm), (pc), (acc)): 0)
#define ppp_recv_config(unit, mtu, accm, pc, acc) \
#define ppp_recv_config(unit, mtu, accm, pc, acc) \
-do { \
- if (the_channel->send_config) \
- (*the_channel->recv_config)((mtu), (accm), (pc), (acc)); \
-} while (0)
+ (the_channel->recv_config? \
+ (*the_channel->recv_config)((mtu), (accm), (pc), (acc)): 0)
void untimeout __P((void (*func)(void *), void *arg));
/* Cancel call to func(arg) */
void record_child __P((int, char *, void (*) (void *), void *));
void untimeout __P((void (*func)(void *), void *arg));
/* Cancel call to func(arg) */
void record_child __P((int, char *, void (*) (void *), void *));
+pid_t safe_fork __P((void)); /* Fork & close stuff in child */
int device_script __P((char *cmd, int in, int out, int dont_wait));
/* Run `cmd' with given stdin and stdout */
pid_t run_program __P((char *prog, char **args, int must_exist,
int device_script __P((char *cmd, int in, int out, int dont_wait));
/* Run `cmd' with given stdin and stdout */
pid_t run_program __P((char *prog, char **args, int must_exist,
void remove_fd __P((int)); /* Remove fd from set to wait for */
int read_packet __P((u_char *)); /* Read PPP packet */
int get_loop_output __P((void)); /* Read pkts from loopback */
void remove_fd __P((int)); /* Remove fd from set to wait for */
int read_packet __P((u_char *)); /* Read PPP packet */
int get_loop_output __P((void)); /* Read pkts from loopback */
-void tty_send_config __P((int, u_int32_t, int, int));
+int tty_send_config __P((int, u_int32_t, int, int));
/* Configure i/f transmit parameters */
void tty_set_xaccm __P((ext_accm));
/* Set extended transmit ACCM */
/* Configure i/f transmit parameters */
void tty_set_xaccm __P((ext_accm));
/* Set extended transmit ACCM */
-void tty_recv_config __P((int, u_int32_t, int, int));
+int tty_recv_config __P((int, u_int32_t, int, int));
/* Configure i/f receive parameters */
int ccp_test __P((int, u_char *, int, int));
/* Test support for compression scheme */
/* Configure i/f receive parameters */
int ccp_test __P((int, u_char *, int, int));
/* Test support for compression scheme */
#ifdef INET6
static int sock6_fd = -1;
#endif /* INET6 */
#ifdef INET6
static int sock6_fd = -1;
#endif /* INET6 */
-int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
+int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
static int chindex; /* channel index (new style driver) */
static fd_set in_fds; /* set of fds that wait_input waits for */
static int chindex; /* channel index (new style driver) */
static fd_set in_fds; /* set of fds that wait_input waits for */
/* Prototypes for procedures local to this file. */
static int get_flags (int fd);
/* Prototypes for procedures local to this file. */
static int get_flags (int fd);
-static void set_flags (int fd, int flags);
+static int set_flags (int fd, int flags);
static int translate_speed (int bps);
static int baud_rate_of (int speed);
static void close_route_table (void);
static int translate_speed (int bps);
static int baud_rate_of (int speed);
static void close_route_table (void);
/********************************************************************/
/********************************************************************/
-static void set_flags (int fd, int flags)
+static int set_flags (int fd, int flags)
{
SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
if (! ok_error (errno) )
{
SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
if (! ok_error (errno) )
- fatal("ioctl(PPPIOCSFLAGS, %x): %m (line %d)", flags, errno, __LINE__);
+ error("Failed to set PPP kernel option flags: %m", flags);
+ return -1;
}
/********************************************************************
}
/********************************************************************
- int flags;
-
- if (new_style_driver) {
- ppp_dev_fd = open("/dev/ppp", O_RDWR);
- if (ppp_dev_fd < 0)
- fatal("Couldn't open /dev/ppp: %m");
- flags = fcntl(ppp_dev_fd, F_GETFL);
- if (flags == -1
- || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
- warn("Couldn't set /dev/ppp to nonblock: %m");
- }
-
/* Get an internet socket for doing socket ioctls. */
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0)
/* Get an internet socket for doing socket ioctls. */
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0)
close(ppp_dev_fd);
if (sock_fd >= 0)
close(sock_fd);
close(ppp_dev_fd);
if (sock_fd >= 0)
close(sock_fd);
+#ifdef INET6
+ if (sock6_fd >= 0)
+ close(sock6_fd);
+#endif
if (slave_fd >= 0)
close(slave_fd);
if (master_fd >= 0)
close(master_fd);
if (slave_fd >= 0)
close(slave_fd);
if (master_fd >= 0)
close(master_fd);
}
/********************************************************************
}
/********************************************************************
int x;
if (new_style_driver) {
int x;
if (new_style_driver) {
- /* Open another instance of /dev/ppp and connect the channel to it */
+ /* Open an instance of /dev/ppp and connect the channel to it */
if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
error("Couldn't get channel number: %m");
goto err;
if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
error("Couldn't get channel number: %m");
goto err;
if (demand) {
set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
looped = 1;
if (demand) {
set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
looped = 1;
- } else if (ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
- error("Couldn't release PPP unit: %m");
- if (!multilink)
+ } else if (ifunit >= 0) {
+ close(ppp_dev_fd);
} else {
/* old-style driver */
if (demand)
} else {
/* old-style driver */
if (demand)
*/
static int make_ppp_unit()
{
*/
static int make_ppp_unit()
{
+ int x, flags;
+
+ if (ppp_dev_fd >= 0) {
+ dbglog("in make_ppp_unit, already had /dev/ppp open?");
+ close(ppp_dev_fd);
+ }
+ ppp_dev_fd = open("/dev/ppp", O_RDWR);
+ if (ppp_dev_fd < 0)
+ fatal("Couldn't open /dev/ppp: %m");
+ flags = fcntl(ppp_dev_fd, F_GETFL);
+ if (flags == -1
+ || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
+ warn("Couldn't set /dev/ppp to nonblock: %m");
ifunit = req_unit;
x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
ifunit = req_unit;
x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
*/
int bundle_attach(int ifnum)
{
*/
int bundle_attach(int ifnum)
{
if (!new_style_driver)
return -1;
if (!new_style_driver)
return -1;
- if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
- if (errno == ENXIO)
+ master_fd = open("/dev/ppp", O_RDWR);
+ if (master_fd < 0)
+ fatal("Couldn't open /dev/ppp: %m");
+ if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
+ if (errno == ENXIO) {
+ close(master_fd);
return 0; /* doesn't still exist */
return 0; /* doesn't still exist */
fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
}
if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
fatal("Couldn't connect to interface unit %d: %m", ifnum);
fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
}
if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
fatal("Couldn't connect to interface unit %d: %m", ifnum);
- set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
+ set_flags(master_fd, get_flags(master_fd) | SC_MULTILINK);
+ close(master_fd);
ifunit = ifnum;
return 1;
ifunit = ifnum;
return 1;
-void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
+int tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
* Set the asyncmap and other parameters for the ppp device
*/
if (!still_ppp())
* Set the asyncmap and other parameters for the ppp device
*/
if (!still_ppp())
link_mtu = mtu;
SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
link_mtu = mtu;
SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
- if (!ok_error(errno))
- fatal("ioctl(PPPIOCSASYNCMAP): %m (line %d)", __LINE__);
- return;
+ if (errno != EIO && errno != ENOTTY)
+ error("Couldn't set transmit async character map: %m");
+ else if (debug)
+ dbglog("PPPIOCSASYNCMAP: %m");
+ return -1;
}
x = get_flags(ppp_fd);
x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
}
x = get_flags(ppp_fd);
x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
+ return set_flags(ppp_fd, x);
}
/********************************************************************
}
/********************************************************************
-void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
+int tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
/*
* If we were called because the link has gone down then there is nothing
* which may be done. Just return without incident.
*/
if (!still_ppp())
SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
/*
* If we were called because the link has gone down then there is nothing
* which may be done. Just return without incident.
*/
if (!still_ppp())
/*
* Set the receiver parameters
*/
if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
/*
* Set the receiver parameters
*/
if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
- if ( ! ok_error (errno))
- error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__);
+ if (errno != EIO && errno != ENOTTY)
+ error("Couldn't set channel receive MRU: %m");
+ else if (debug)
+ dbglog("PPPIOCSMRU: %m");
+ ret = -1;
}
if (new_style_driver && ifunit >= 0
}
if (new_style_driver && ifunit >= 0
- && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
+ && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
error("Couldn't set MRU in generic PPP layer: %m");
error("Couldn't set MRU in generic PPP layer: %m");
SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
- if (!ok_error(errno))
- error("ioctl(PPPIOCSRASYNCMAP): %m (line %d)", __LINE__);
+ if (errno != EIO && errno != ENOTTY)
+ error("Couldn't set channel receive asyncmap: %m");
+ else if (debug)
+ dbglog("PPPIOCSRASYNCMAP: %m");
+ ret = -1;
}
/********************************************************************
}
/********************************************************************
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: sys-solaris.c,v 1.9 2002/12/04 23:03:33 paulus Exp $"
+#define RCSID "$Id: sys-solaris.c,v 1.10 2003/03/03 05:11:46 paulus Exp $"
#include <limits.h>
#include <stdio.h>
#include <limits.h>
#include <stdio.h>
* tty_send_config - configure the transmit characteristics of
* the ppp interface.
*/
* tty_send_config - configure the transmit characteristics of
* the ppp interface.
*/
tty_send_config(mtu, asyncmap, pcomp, accomp)
int mtu;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
tty_send_config(mtu, asyncmap, pcomp, accomp)
int mtu;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
link_mtu = mtu;
if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
if (hungup && errno == ENXIO)
link_mtu = mtu;
if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
if (hungup && errno == ENXIO)
error("Couldn't set MTU: %m");
error("Couldn't set MTU: %m");
}
if (fdmuxid >= 0) {
if (!sync_serial) {
if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set transmit ACCM: %m");
}
if (fdmuxid >= 0) {
if (!sync_serial) {
if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set transmit ACCM: %m");
}
}
cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
}
}
cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
if (any_compressions() &&
strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC compression: %m");
if (any_compressions() &&
strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC compression: %m");
* tty_recv_config - configure the receive-side characteristics of
* the ppp interface.
*/
* tty_recv_config - configure the receive-side characteristics of
* the ppp interface.
*/
tty_recv_config(mru, asyncmap, pcomp, accomp)
int mru;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
tty_recv_config(mru, asyncmap, pcomp, accomp)
int mru;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
link_mru = mru;
if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
if (hungup && errno == ENXIO)
link_mru = mru;
if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
if (hungup && errno == ENXIO)
error("Couldn't set MRU: %m");
error("Couldn't set MRU: %m");
}
if (fdmuxid >= 0) {
if (!sync_serial) {
if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set receive ACCM: %m");
}
if (fdmuxid >= 0) {
if (!sync_serial) {
if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set receive ACCM: %m");
}
}
cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
}
}
cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
if (any_compressions() &&
strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC decompression: %m");
if (any_compressions() &&
strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC decompression: %m");
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: sys-sunos4.c,v 1.30 2002/12/04 23:03:33 paulus Exp $"
+#define RCSID "$Id: sys-sunos4.c,v 1.31 2003/03/03 05:11:46 paulus Exp $"
#include <stdio.h>
#include <stddef.h>
#include <stdio.h>
#include <stddef.h>
* tty_send_config - configure the transmit characteristics of
* the ppp interface.
*/
* tty_send_config - configure the transmit characteristics of
* the ppp interface.
*/
tty_send_config(mtu, asyncmap, pcomp, accomp)
int mtu;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
tty_send_config(mtu, asyncmap, pcomp, accomp)
int mtu;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
link_mtu = mtu;
if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
if (hungup && errno == ENXIO)
link_mtu = mtu;
if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
if (hungup && errno == ENXIO)
error("Couldn't set MTU: %m");
error("Couldn't set MTU: %m");
}
if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set transmit ACCM: %m");
}
if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set transmit ACCM: %m");
}
cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
cf[1] = COMP_PROT | COMP_AC;
if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC compression: %m");
}
cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
cf[1] = COMP_PROT | COMP_AC;
if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC compression: %m");
* tty_recv_config - configure the receive-side characteristics of
* the ppp interface.
*/
* tty_recv_config - configure the receive-side characteristics of
* the ppp interface.
*/
tty_recv_config(mru, asyncmap, pcomp, accomp)
int mru;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
tty_recv_config(mru, asyncmap, pcomp, accomp)
int mru;
u_int32_t asyncmap;
int pcomp, accomp;
{
int cf[2];
link_mru = mru;
if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
if (hungup && errno == ENXIO)
link_mru = mru;
if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
if (hungup && errno == ENXIO)
error("Couldn't set MRU: %m");
error("Couldn't set MRU: %m");
}
if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set receive ACCM: %m");
}
if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
error("Couldn't set receive ACCM: %m");
}
cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
cf[1] = DECOMP_PROT | DECOMP_AC;
if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC decompression: %m");
}
cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
cf[1] = DECOMP_PROT | DECOMP_AC;
if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
error("Couldn't set prot/AC decompression: %m");
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: tty.c,v 1.10 2003/02/24 11:29:53 fcusack Exp $"
+#define RCSID "$Id: tty.c,v 1.11 2003/03/03 05:11:46 paulus Exp $"
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#include <ctype.h>
void disconnect_tty __P((void));
void tty_close_fds __P((void));
void cleanup_tty __P((void));
void disconnect_tty __P((void));
void tty_close_fds __P((void));
void cleanup_tty __P((void));
-void tty_do_send_config __P((int, u_int32_t, int, int));
+int tty_do_send_config __P((int, u_int32_t, int, int));
static int setdevname __P((char *, char **, int));
static int setspeed __P((char *, char **, int));
static int setdevname __P((char *, char **, int));
static int setspeed __P((char *, char **, int));
* tty_do_send_config - set transmit-side PPP configuration.
* We set the extended transmit ACCM here as well.
*/
* tty_do_send_config - set transmit-side PPP configuration.
* We set the extended transmit ACCM here as well.
*/
tty_do_send_config(mtu, accm, pcomp, accomp)
int mtu;
u_int32_t accm;
int pcomp, accomp;
{
tty_set_xaccm(xmit_accm);
tty_do_send_config(mtu, accm, pcomp, accomp)
int mtu;
u_int32_t accm;
int pcomp, accomp;
{
tty_set_xaccm(xmit_accm);
- tty_send_config(mtu, accm, pcomp, accomp);
+ return tty_send_config(mtu, accm, pcomp, accomp);
if (cpid == -1) {
error("Can't fork process for character shunt: %m");
return 0;
if (cpid == -1) {
error("Can't fork process for character shunt: %m");
return 0;
if (getuid() != uid)
fatal("setuid failed");
setgid(getgid());
if (getuid() != uid)
fatal("setuid failed");
setgid(getgid());
if (!nodetach)
log_to_fd = -1;
charshunt(ifd, ofd, record_file);
if (!nodetach)
log_to_fd = -1;
charshunt(ifd, ofd, record_file);