* OR MODIFICATIONS.
*/
-#ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.27 1999/03/19 01:29:50 paulus Exp $";
-#endif
+#define RCSID "$Id: sys-svr4.c,v 1.34 1999/09/08 01:11:16 masputra Exp $"
#include <limits.h>
#include <stdio.h>
#include <net/ppp_defs.h>
#include <net/pppio.h>
#include <netinet/in.h>
+#ifdef SOL2
#include <sys/tihdr.h>
#include <sys/tiuser.h>
#include <inet/common.h>
#include <inet/mib2.h>
+#endif
#include "pppd.h"
+static const char rcsid[] = RCSID;
+
static int pppfd;
static int fdmuxid = -1;
static int ipfd;
#define NMODULES 32
static int tty_nmodules;
static char tty_modules[NMODULES][FMNAMESZ+1];
+static int tty_npushed;
static int if_is_up; /* Interface has been marked up */
static u_int32_t remote_addr; /* IP address of peer */
static int dlpi_get_reply __P((int, union DL_primitives *, int, int));
static int strioctl __P((int, int, void *, int, int));
+#ifdef SOL2
+/*
+ * sifppa - Sets interface ppa
+ *
+ * without setting the ppa, ip module will return EINVAL upon setting the
+ * interface UP (SIOCSxIFFLAGS). This is because ip module in 2.8 expects
+ * two DLPI_INFO_REQ to be sent down to the driver (below ip) before
+ * IFF_UP can be set. Plumbing the device causes one DLPI_INFO_REQ to
+ * be sent down, and the second DLPI_INFO_REQ is sent upon receiving
+ * IF_UNITSEL (old) or SIOCSLIFNAME (new) ioctls. Such setting of the ppa
+ * is required because the ppp DLPI provider advertises itself as
+ * a DLPI style 2 type, which requires a point of attachment to be
+ * specified. The only way the user can specify a point of attachment
+ * is via SIOCSLIFNAME or IF_UNITSEL.
+ *
+ * Such changes in the behavior of ip module was made to meet new or
+ * evolving standards requirements.
+ *
+ */
+static int
+sifppa(fd, ppa)
+ int fd;
+ int ppa;
+{
+ if (ioctl(fd, IF_UNITSEL, (char *)&ppa) < 0) {
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* SOL2 */
/*
* sys_init - System-dependent initialization.
if (ipfd < 0)
fatal("Couldn't open IP device: %m");
- if (default_device)
+ if (default_device && !notty)
tty_sid = getsid((pid_t)0);
pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0);
close(ifd);
fatal("Can't push IP module: %m");
}
+
+#ifdef SOL2
+ /*
+ * Assign ppa according to the unit number returned by ppp device
+ * after plumbing is completed above.
+ */
+ if (sifppa(ifd, ifunit) < 0) {
+ close (ifd);
+ fatal("Can't set ppa for unit %d: %m", ifunit);
+ }
+#endif /* SOL2 */
+
#else
if (dlpi_attach(ifd, ifunit) < 0 ||
dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) {
return 1;
}
-
+#if 0
/*
* daemon - Detach us from controlling terminal session.
*/
}
return 0;
}
+#endif
/*
* ppp_available - check whether the system has any ppp interfaces
/* Pop any existing modules off the tty stream. */
for (i = 0;; ++i)
if (ioctl(fd, I_LOOK, tty_modules[i]) < 0
+ || strcmp(tty_modules[i], "ptem") == 0
|| ioctl(fd, I_POP, 0) < 0)
break;
tty_nmodules = i;
/* Push the async hdlc module and the compressor module. */
- if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0)
- fatal("Couldn't push PPP Async HDLC module: %m");
+ tty_npushed = 0;
+
+ if(!sync_serial) {
+ if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0) {
+ error("Couldn't push PPP Async HDLC module: %m");
+ return -1;
+ }
+ ++tty_npushed;
+ }
if (kdebugflag & 4) {
i = PPPDBG_LOG + PPPDBG_AHDLC;
strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);
}
if (ioctl(fd, I_PUSH, "ppp_comp") < 0)
error("Couldn't push PPP compression module: %m");
+ else
+ ++tty_npushed;
if (kdebugflag & 2) {
i = PPPDBG_LOG + PPPDBG_COMP;
strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);
}
/* Link the serial port under the PPP multiplexor. */
- if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0)
- fatal("Can't link tty to PPP mux: %m");
+ if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) {
+ error("Can't link tty to PPP mux: %m");
+ return -1;
+ }
return pppfd;
}
fdmuxid = -1;
if (!hungup) {
- while (ioctl(fd, I_POP, 0) >= 0)
- ;
+ while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0)
+ --tty_npushed;
for (i = tty_nmodules - 1; i >= 0; --i)
if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)
error("Couldn't restore tty module %s: %m",
#ifdef B57600
{ 57600, B57600 },
#endif
+#ifdef B76800
+ { 76800, B76800 },
+#endif
#ifdef B115200
{ 115200, B115200 },
#endif
struct termiox tiox;
#endif
- if (tcgetattr(fd, &tios) < 0)
+ if (!sync_serial && tcgetattr(fd, &tios) < 0)
fatal("tcgetattr: %m");
#ifndef CRTSCTS
fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
}
- if (tcsetattr(fd, TCSAFLUSH, &tios) < 0)
+ if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0)
fatal("tcsetattr: %m");
#ifndef CRTSCTS
/*
* add_fd - add an fd to the set that wait_input waits for.
*/
-void add_fd(int fd)
+void add_fd(fd)
+ int fd;
{
int n;
/*
* remove_fd - remove an fd from the set that wait_input waits for.
*/
-void remove_fd(int fd)
+void remove_fd(fd)
+ int fd;
{
int n;
return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
}
+/*
+ * get_ppp_stats - return statistics for the link.
+ */
+int
+get_ppp_stats(u, stats)
+ int u;
+ struct pppd_stats *stats;
+{
+ struct ppp_stats s;
+
+ if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
+ error("Couldn't get link statistics: %m");
+ return 0;
+ }
+ stats->bytes_in = s.p.ppp_ibytes;
+ stats->bytes_out = s.p.ppp_obytes;
+ return 1;
+}
+
#if 0
/*
* set_filters - transfer the pass and active filters to the kernel.
if (name[0] != 0) {
/* logging in */
- strlcpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
- strlcpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
- strlcpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
+ strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
+ strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
+ strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
utmpx.ut_pid = getpid();
utmpx.ut_type = USER_PROCESS;
} else {
return 0;
}
+#if 0
/*
* lock - create a lock file for the named lock device
*/
lock_file[0] = 0;
}
}
-
+#endif
/*
* cifroute - delete a route through the addresses given.
have_route_to(addr)
u_int32_t addr;
{
+#ifdef SOL2
int fd, r, flags, i;
struct {
struct T_optmgmt_req req;
}
close(fd);
return 0;
+#else
+ return -1;
+#endif /* SOL2 */
+}
+
+/*
+ * get_pty - get a pty master/slave pair and chown the slave side to
+ * the uid given. Assumes slave_name points to MAXPATHLEN bytes of space.
+ */
+int
+get_pty(master_fdp, slave_fdp, slave_name, uid)
+ int *master_fdp;
+ int *slave_fdp;
+ char *slave_name;
+ int uid;
+{
+ int mfd, sfd;
+ char *pty_name;
+ struct termios tios;
+
+ mfd = open("/dev/ptmx", O_RDWR);
+ if (mfd < 0) {
+ error("Couldn't open pty master: %m");
+ return 0;
+ }
+
+ pty_name = ptsname(mfd);
+ if (pty_name == NULL) {
+ error("Couldn't get name of pty slave");
+ close(mfd);
+ return 0;
+ }
+ if (chown(pty_name, uid, -1) < 0)
+ warn("Couldn't change owner of pty slave: %m");
+ if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0)
+ warn("Couldn't change permissions on pty slave: %m");
+ if (unlockpt(mfd) < 0)
+ warn("Couldn't unlock pty slave: %m");
+
+ sfd = open(pty_name, O_RDWR);
+ if (sfd < 0) {
+ error("Couldn't open pty slave %s: %m", pty_name);
+ close(mfd);
+ return 0;
+ }
+ if (ioctl(sfd, I_PUSH, "ptem") < 0)
+ warn("Couldn't push ptem module on pty slave: %m");
+
+ dbglog("Using %s", pty_name);
+ strlcpy(slave_name, pty_name, MAXPATHLEN);
+ *master_fdp = mfd;
+ *slave_fdp = sfd;
+
+ return 1;
}