]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-solaris.c
Changing USE_SRP to PPP_WITH_SRP for consistency
[ppp.git] / pppd / sys-solaris.c
index 6e925f9fc4623edc295babf77054dc1f162587ef..080a3b653629e19b40f136e338b5d2c153e2f016 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <limits.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <sys/ethernet.h>
 #endif
 
+#ifdef PPP_WITH_FILTER
+#include <pcap.h>
+#endif
+
 #include "pppd.h"
 #include "fsm.h"
 #include "lcp.h"
@@ -182,7 +190,7 @@ static int  fdmuxid = -1;
 static int     ipfd;
 static int     ipmuxid = -1;
 
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
 static int     ip6fd;          /* IP file descriptor */
 static int     ip6muxid = -1;  /* Multiplexer file descriptor */
 static int     if6_is_up = 0;  /* IPv6 interface has been marked up */
@@ -216,14 +224,11 @@ static int        if6_is_up = 0;  /* IPv6 interface has been marked up */
 #define IN6A_LLADDR_FROM_EUI64(s, eui64)  \
     _IN6A_LLX_FROM_EUI64(s, eui64, 0xfe800000)
 
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
-#if defined(INET6) && defined(SOL2)
-static char    first_ether_name[LIFNAMSIZ];    /* Solaris 8 and above */
-#else
-static char    first_ether_name[IFNAMSIZ];     /* Before Solaris 8 */
+#if !defined(PPP_WITH_IPV6CP) || !defined(SOL2)
 #define MAXIFS         256                     /* Max # of interfaces */
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
 static int     restore_term;
 static struct termios inittermios;
@@ -261,7 +266,7 @@ static int get_hw_addr(char *, u_int32_t, struct sockaddr *);
 static int get_hw_addr_dlpi(char *, struct sockaddr *);
 static int dlpi_attach(int, int);
 static int dlpi_info_req(int);
-static int dlpi_get_reply(int, union DL_primitives *, int, int);
+static int dlpi_get_reply(int, union DL_primitives *, int, size_t);
 static int strioctl(int, int, void *, int, int);
 
 #ifdef SOL2
@@ -292,15 +297,15 @@ sifppa(fd, ppa)
 }
 #endif /* SOL2 */
 
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
 /*
- * get_first_ethernet - returns the first Ethernet interface name found in 
- * the system, or NULL if none is found
+ * get_first_ether_hwaddr - get the hardware address for the first
+ * ethernet-style interface on this system.
  *
  * NOTE: This is the lifreq version (Solaris 8 and above)
  */
-char *
-get_first_ethernet(void)
+int
+get_first_ether_hwaddr(u_char *addr)
 {
     struct lifnum lifn;
     struct lifconf lifc;
@@ -312,7 +317,7 @@ get_first_ethernet(void)
 
     fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd < 0) {
-       return 0;
+       return -1;
     }
 
     /*
@@ -323,7 +328,7 @@ get_first_ethernet(void)
     if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) {
        close(fd);
        error("could not determine number of interfaces: %m");
-       return 0;
+       return -1;
     }
 
     num_ifs = lifn.lifn_count;
@@ -332,7 +337,7 @@ get_first_ethernet(void)
     if (req == NULL) {
        close(fd);
        error("out of memory");
-       return 0;
+       return -1;
     }
 
     /*
@@ -346,7 +351,7 @@ get_first_ethernet(void)
        close(fd);
        free(req);
        error("SIOCGLIFCONF: %m");
-       return 0;
+       return -1;
     }
 
     /*
@@ -363,10 +368,8 @@ get_first_ethernet(void)
        memset(&lifr, 0, sizeof(lifr));
        strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name));
        if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
-           close(fd);
-           free(req);
            error("SIOCGLIFFLAGS: %m");
-           return 0;
+           break;
        }
        fl = lifr.lifr_flags;
 
@@ -374,27 +377,29 @@ get_first_ethernet(void)
                != (IFF_UP | IFF_BROADCAST))
            continue;
 
+       if (get_if_hwaddr(addr, lifr.lifr_name) < 0)
+           continue;
+
        found = 1;
        break;
     }
     free(req);
     close(fd);
 
-    if (found) {
-       strncpy(first_ether_name, lifr.lifr_name, sizeof(first_ether_name));
-       return (char *)first_ether_name;
-    } else
-       return NULL;
+    if (found)
+       return 0;
+    else
+       return -1;
 }
 #else
 /*
- * get_first_ethernet - returns the first Ethernet interface name found in 
- * the system, or NULL if none is found
+ * get_first_ether_hwaddr - get the hardware address for the first
+ * ethernet-style interface on this system.
  *
  * NOTE: This is the ifreq version (before Solaris 8). 
  */
-char *
-get_first_ethernet(void)
+int
+get_first_ether_hwaddr(u_char *addr)
 {
     struct ifconf ifc;
     struct ifreq *pifreq;
@@ -405,7 +410,7 @@ get_first_ethernet(void)
 
     fd = socket(AF_INET, SOCK_DGRAM, 0);
     if (fd < 0) {
-       return 0;
+       return -1;
     }
 
     /*
@@ -420,7 +425,7 @@ get_first_ethernet(void)
     if (req == NULL) {
        close(fd);
        error("out of memory");
-       return 0;
+       return -1;
     }
 
     /*
@@ -432,7 +437,7 @@ get_first_ethernet(void)
        close(fd);
        free(req);
        error("SIOCGIFCONF: %m");
-       return 0;
+       return -1;
     }
 
     /*
@@ -449,10 +454,8 @@ get_first_ethernet(void)
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
-           close(fd);
-           free(req);
            error("SIOCGIFFLAGS: %m");
-           return 0;
+           break;
        }
        fl = ifr.ifr_flags;
 
@@ -460,19 +463,21 @@ get_first_ethernet(void)
                != (IFF_UP | IFF_BROADCAST))
            continue;
 
+       if (get_if_hwaddr(addr, ifr.ifr_name) < 0)
+           continue;
+
        found = 1;
        break;
     }
     free(req);
     close(fd);
 
-    if (found) {
-       strncpy(first_ether_name, ifr.ifr_name, sizeof(first_ether_name));
-       return (char *)first_ether_name;
-    } else
-       return NULL;
+    if (found)
+       return 0;
+    else
+       return -1;
 }
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
 
 #if defined(SOL2)
 /*
@@ -501,7 +506,7 @@ get_if_hwaddr(u_char *addr, char *if_name)
 }
 #endif /* SOL2 */
 
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
 /*
  * slifname - Sets interface ppa and flags
  *
@@ -531,51 +536,7 @@ slifname_done:
 
 
 }
-
-
-/*
- * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
- *
- * walks the list of valid ethernet interfaces, and convert the first
- * found 48-bit MAC address into EUI 64. caller also assumes that
- * the system has a properly configured Ethernet interface for this
- * function to return non-zero.
- */
-int
-ether_to_eui64(eui64_t *p_eui64)
-{
-    struct sockaddr s_eth_addr;
-    struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data;
-    char *if_name;
-
-    if ((if_name = get_first_ethernet()) == NULL) {
-       error("no persistent id can be found");
-       return 0;
-    }
-    /*
-     * Send DL_INFO_REQ to the driver to solicit its MAC address
-     */
-    if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) {
-       error("could not obtain hardware address for %s", if_name);
-       return 0;
-    }
-
-    /*
-     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
-     */
-    p_eui64->e8[0] = (eth_addr->ether_addr_octet[0] & 0xFF) | 0x02;
-    p_eui64->e8[1] = (eth_addr->ether_addr_octet[1] & 0xFF);
-    p_eui64->e8[2] = (eth_addr->ether_addr_octet[2] & 0xFF);
-    p_eui64->e8[3] = 0xFF;
-    p_eui64->e8[4] = 0xFE;
-    p_eui64->e8[5] = (eth_addr->ether_addr_octet[3] & 0xFF);
-    p_eui64->e8[6] = (eth_addr->ether_addr_octet[4] & 0xFF);
-    p_eui64->e8[7] = (eth_addr->ether_addr_octet[5] & 0xFF);
-
-    return 1;
-}
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
 
 /*
  * sys_init - System-dependent initialization.
@@ -585,10 +546,10 @@ sys_init(void)
 {
     int ifd, x;
     struct ifreq ifr;
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     int i6fd;
     struct lifreq lifr;
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 #if !defined(SOL2)
     struct {
        union DL_primitives prim;
@@ -600,11 +561,11 @@ sys_init(void)
     if (ipfd < 0)
        fatal("Couldn't open IP device: %m");
 
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0);
     if (ip6fd < 0)
        fatal("Couldn't open IP device (2): %m");
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
     if (default_device && !notty)
        tty_sid = getsid((pid_t)0);
@@ -643,7 +604,7 @@ sys_init(void)
        strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0);
     }
 
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     i6fd = open(PPP_DEV_NAME, O_RDWR, 0);
     if (i6fd < 0) {
        close(ifd);
@@ -653,14 +614,14 @@ sys_init(void)
        x = PPPDBG_LOG + PPPDBG_DRIVER;
        strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0);
     }
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
 #if defined(SOL2)
     if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) {
        close(ifd);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
        close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
        fatal("Can't push IP module: %m");
     }
 
@@ -670,13 +631,13 @@ sys_init(void)
      */
     if (sifppa(ifd, ifunit) < 0) {
         close (ifd);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
        close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
         fatal("Can't set ppa for unit %d: %m", ifunit);
     }
 
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
     /*
      * An IPv6 interface is created anyway, even when the user does not 
      * explicitly enable it. Note that the interface will be marked
@@ -698,14 +659,14 @@ sys_init(void)
        close(i6fd);
        fatal("Can't set ifname for unit %d: %m", ifunit);
     }
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
 
     ipmuxid = ioctl(ipfd, I_PLINK, ifd);
     close(ifd);
     if (ipmuxid < 0) {
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
        close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
        fatal("Can't I_PLINK PPP device to IP: %m");
     }
 
@@ -722,9 +683,9 @@ sys_init(void)
      */
     if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) {
        ioctl(ipfd, I_PUNLINK, ipmuxid);
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
        close(i6fd);
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
        fatal("SIOCSIFMUXID: %m");
     }
 
@@ -742,7 +703,7 @@ sys_init(void)
        fatal("Can't link PPP device to IP: %m");
 #endif /* defined(SOL2) */
 
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     ip6muxid = ioctl(ip6fd, I_PLINK, i6fd);
     close(i6fd);
     if (ip6muxid < 0) {
@@ -762,7 +723,7 @@ sys_init(void)
        ioctl(ip6fd, I_PUNLINK, ip6muxid);
        fatal("Can't link PPP device to IP (2): %m");
     }
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
 #if !defined(SOL2)
     /* Set the interface name for the link. */
@@ -785,15 +746,15 @@ sys_cleanup(void)
 {
 #if defined(SOL2)
     struct ifreq ifr;
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
     struct lifreq lifr;
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
 #endif /* defined(SOL2) */
 
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
     if (if6_is_up)
        sif6down(0);
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
     if (if_is_up)
        sifdown(0);
     if (default_route_gateway)
@@ -825,7 +786,7 @@ sys_cleanup(void)
        error("Can't I_PUNLINK PPP from IP: %m");
        return;
     }
-#if defined(INET6)
+#if defined(PPP_WITH_IPV6CP)
     /*
      * Make sure we ask ip what the muxid, because 'ifconfig modlist' will
      * unlink and re-link the modules, causing the muxid to change.
@@ -847,7 +808,7 @@ sys_cleanup(void)
     if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) {
        error("Can't I_PUNLINK PPP from IP (2): %m");
     }
-#endif /* defined(INET6) */
+#endif /* defined(PPP_WITH_IPV6CP) */
 #endif /* defined(SOL2) */
 }
 
@@ -858,9 +819,9 @@ void
 sys_close(void)
 {
     close(ipfd);
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     close(ip6fd);
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
     if (pppfd >= 0)
        close(pppfd);
 }
@@ -1501,10 +1462,10 @@ void
 netif_set_mtu(int unit, int mtu)
 {
     struct ifreq ifr;
-#if defined(INET6) && defined(SOL2)
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     struct lifreq lifr;
     int        fd;
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 
     memset(&ifr, 0, sizeof(ifr));
     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
@@ -1513,7 +1474,7 @@ netif_set_mtu(int unit, int mtu)
        error("Couldn't set IP MTU (%s): %m", ifr.ifr_name);
     }
 
-#if defined(INET6) && defined(SOL2) 
+#if defined(PPP_WITH_IPV6CP) && defined(SOL2)
     fd = socket(AF_INET6, SOCK_DGRAM, 0);
     if (fd < 0)
        error("Couldn't open IPv6 socket: %m");
@@ -1526,7 +1487,7 @@ netif_set_mtu(int unit, int mtu)
        error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name);
     }
     close(fd);
-#endif /* defined(INET6) && defined(SOL2) */
+#endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */
 }
 
 
@@ -1546,7 +1507,7 @@ netif_get_mtu(int unit)
     error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
     return 0;
     }
-    return ifr.ifr_mtu;
+    return ifr.ifr_metric;
 }
 
 /*
@@ -1683,33 +1644,6 @@ get_ppp_stats(int u, struct pppd_stats *stats)
     return 1;
 }
 
-#if 0
-/*
- * set_filters - transfer the pass and active filters to the kernel.
- */
-int
-set_filters(struct bpf_program *pass, struct bpf_program *active)
-{
-    int ret = 1;
-
-    if (pass->bf_len > 0) {
-       if (strioctl(pppfd, PPPIO_PASSFILT, pass,
-                    sizeof(struct bpf_program), 0) < 0) {
-           error("Couldn't set pass-filter in kernel: %m");
-           ret = 0;
-       }
-    }
-    if (active->bf_len > 0) {
-       if (strioctl(pppfd, PPPIO_ACTIVEFILT, active,
-                    sizeof(struct bpf_program), 0) < 0) {
-           error("Couldn't set active-filter in kernel: %m");
-           ret = 0;
-       }
-    }
-    return ret;
-}
-#endif
-
 /*
  * ccp_fatal_error - returns 1 if decompression was disabled as a
  * result of an error detected after decompression of a packet,
@@ -1820,7 +1754,7 @@ sifnpmode(int u, int proto, enum NPmode mode)
     return 1;
 }
 
-#if defined(SOL2) && defined(INET6)
+#if defined(SOL2) && defined(PPP_WITH_IPV6CP)
 /*
  * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass.
  */
@@ -2004,7 +1938,7 @@ cif6defaultroute(int u, eui64_t l, eui64_t g)
     return 1;
 }
 
-#endif /* defined(SOL2) && defined(INET6) */
+#endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */
 
 
 #define INET_ADDR(x)   (((struct sockaddr_in *) &(x))->sin_addr.s_addr)
@@ -2082,10 +2016,15 @@ cifaddr(int u, u_int32_t o, u_int32_t h)
  * sifdefaultroute - assign a default route through the address given.
  */
 int
-sifdefaultroute(int u, u_int32_t l, u_int32_t g)
+sifdefaultroute(int u, u_int32_t l, u_int32_t g, bool replace)
 {
     struct rtentry rt;
 
+    if (replace) {
+       error("Replacing the default route is not implemented on Solaris yet");
+       return 0;
+    }
+
 #if defined(__USLC__)
     g = l;                     /* use the local address as gateway */
 #endif
@@ -2357,7 +2296,7 @@ dlpi_info_req(int fd)
 }
 
 static int
-dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, maxlen)
+dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, size_t maxlen)
 {
     struct strbuf buf;
     int flags, n;