]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-svr4.c
Add IF_UNITSEL ioctl to set ppa since driver is DLPI style 2. Solaris 8 is
[ppp.git] / pppd / sys-svr4.c
index e6d3d67f117824e080cd17eb293b36f3278be18d..5f0ffa573689c80a0ddff1aaa2299998cc67e0dd 100644 (file)
@@ -25,9 +25,7 @@
  * OR MODIFICATIONS.
  */
 
-#ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.26 1999/03/16 22:53:48 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>
@@ -60,13 +58,17 @@ static char rcsid[] = "$Id: sys-svr4.c,v 1.26 1999/03/16 22:53:48 paulus Exp $";
 #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;
@@ -92,6 +94,7 @@ static int    link_mtu, link_mru;
 #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 */
@@ -108,6 +111,37 @@ static int dlpi_info_req __P((int));
 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.
@@ -128,7 +162,7 @@ sys_init()
     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);
@@ -160,6 +194,18 @@ sys_init()
        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) {
@@ -221,7 +267,7 @@ sys_check_options()
     return 1;
 }
 
-
+#if 0
 /*
  * daemon - Detach us from controlling terminal session.
  */
@@ -245,6 +291,7 @@ daemon(nochdir, noclose)
     }
     return 0;
 }
+#endif
 
 /*
  * ppp_available - check whether the system has any ppp interfaces
@@ -269,27 +316,39 @@ establish_ppp(fd)
     /* 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;
 }
@@ -322,8 +381,8 @@ disestablish_ppp(fd)
        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",
@@ -443,6 +502,9 @@ struct speed {
 #ifdef B57600
     { 57600, B57600 },
 #endif
+#ifdef B76800
+    { 76800, B76800 },
+#endif
 #ifdef B115200
     { 115200, B115200 },
 #endif
@@ -499,7 +561,7 @@ set_up_tty(fd, local)
     struct termiox tiox;
 #endif
 
-    if (tcgetattr(fd, &tios) < 0)
+    if (!sync_serial && tcgetattr(fd, &tios) < 0)
        fatal("tcgetattr: %m");
 
 #ifndef CRTSCTS
@@ -564,7 +626,7 @@ set_up_tty(fd, local)
            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
@@ -683,7 +745,8 @@ wait_input(timo)
 /*
  * 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;
 
@@ -701,7 +764,8 @@ void add_fd(int fd)
 /*
  * 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;
 
@@ -834,7 +898,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
 
     /* set the MTU for IP as well */
     memset(&ifr, 0, sizeof(ifr));
-    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     ifr.ifr_metric = link_mtu;
     if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) {
        error("Couldn't set IP MTU: %m");
@@ -930,6 +994,25 @@ get_idle_time(u, ip)
     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.
@@ -1016,7 +1099,7 @@ sifup(u)
 {
     struct ifreq ifr;
 
-    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
        error("Couldn't mark interface up (get): %m");
        return 0;
@@ -1041,7 +1124,7 @@ sifdown(u)
 
     if (ipmuxid < 0)
        return 1;
-    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
        error("Couldn't mark interface down (get): %m");
        return 0;
@@ -1089,7 +1172,7 @@ sifaddr(u, o, h, m)
     int ret = 1;
 
     memset(&ifr, 0, sizeof(ifr));
-    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     ifr.ifr_addr.sa_family = AF_INET;
     INET_ADDR(ifr.ifr_addr) = m;
     if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) {
@@ -1301,7 +1384,7 @@ get_ether_addr(ipaddr, hwaddr)
        /*
         * Check that the interface is up, and not point-to-point or loopback.
         */
-       strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
+       strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
        if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
            continue;
        if ((ifreq.ifr_flags &
@@ -1550,7 +1633,7 @@ GetMask(addr)
        /*
         * Check that the interface is up, and not point-to-point or loopback.
         */
-       strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
+       strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
        if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
            continue;
        if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
@@ -1579,9 +1662,9 @@ logwtmp(line, name, host)
 
     if (name[0] != 0) {
        /* logging in */
-       strlcpy(utmpx.ut_user, sizeof(utmpx.ut_user), name);
-       strlcpy(utmpx.ut_id, sizeof(utmpx.ut_id), ifname);
-       strlcpy(utmpx.ut_line, sizeof(utmpx.ut_line), 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 {
@@ -1625,6 +1708,7 @@ strioctl(fd, cmd, ptr, ilen, olen)
     return 0;
 }
 
+#if 0
 /*
  * lock - create a lock file for the named lock device
  */
@@ -1702,7 +1786,7 @@ unlock()
        lock_file[0] = 0;
     }
 }
-
+#endif
 
 /*
  * cifroute - delete a route through the addresses given.
@@ -1744,6 +1828,7 @@ int
 have_route_to(addr)
     u_int32_t addr;
 {
+#ifdef SOL2
     int fd, r, flags, i;
     struct {
        struct T_optmgmt_req req;
@@ -1834,4 +1919,58 @@ have_route_to(addr)
     }
     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;
 }