add a have_route_to
authorPaul Mackerras <paulus@samba.org>
Fri, 26 Feb 1999 10:35:34 +0000 (10:35 +0000)
committerPaul Mackerras <paulus@samba.org>
Fri, 26 Feb 1999 10:35:34 +0000 (10:35 +0000)
pppd/sys-svr4.c

index d2bc489dd991797211b087d1fcaccaf1c679e5a2..fcdc6ba22564384a0901871f3d84c5edaf720018 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.19 1999/01/20 00:01:53 paulus Exp $";
+static char rcsid[] = "$Id: sys-svr4.c,v 1.20 1999/02/26 10:35:34 paulus Exp $";
 #endif
 
 #include <limits.h>
@@ -61,6 +61,10 @@ static char rcsid[] = "$Id: sys-svr4.c,v 1.19 1999/01/20 00:01:53 paulus Exp $";
 #include <net/ppp_defs.h>
 #include <net/pppio.h>
 #include <netinet/in.h>
+#include <sys/tihdr.h>
+#include <sys/tiuser.h>
+#include <inet/common.h>
+#include <inet/mib2.h>
 
 #include "pppd.h"
 
@@ -623,6 +627,14 @@ restore_tty(fd)
     }
 }
 
+/*
+ * hangup_modem - hang up the modem by clearing DTR.
+ */
+void hangup_modem(int ttyfd)
+{
+    setdtr(ttyfd, 0);
+}
+
 /*
  * setdtr - control the DTR line on the serial port.
  * This is called from die(), so it shouldn't call die().
@@ -1337,10 +1349,10 @@ get_hw_addr(name, ina, hwaddr)
     if (s < 0)
        return 0;
     memset(&req, 0, sizeof(req));
-    req.arp_pa.sin_family = AF_INET;
+    req.arp_pa.sa_family = AF_INET;
     INET_ADDR(req.arp_pa) = ina;
     if (ioctl(s, SIOCGARP, &req) < 0) {
-       syslog(LOG_ERR, "Couldn't get ARP entry for %s: %m", inet_itoa(ina));
+       syslog(LOG_ERR, "Couldn't get ARP entry for %s: %m", ip_ntoa(ina));
        return 0;
     }
     *hwaddr = req.arp_ha;
@@ -1710,3 +1722,106 @@ cifroute(u, our, his)
 
     return 1;
 }
+
+/*
+ * have_route_to - determine if the system has a route to the specified
+ * IP address.  Returns 0 if not, 1 if so, -1 if we can't tell.
+ */
+#ifndef T_CURRENT              /* needed for Solaris 2.5 */
+#define T_CURRENT      MI_T_CURRENT
+#endif
+
+int
+have_route_to(addr)
+    u_int32_t addr;
+{
+    int fd, r, flags, i;
+    struct {
+       struct T_optmgmt_req req;
+       struct opthdr hdr;
+    } req;
+    union {
+       struct T_optmgmt_ack ack;
+       unsigned char space[64];
+    } ack;
+    struct opthdr *rh;
+    struct strbuf cbuf, dbuf;
+    int nroutes;
+    mib2_ipRouteEntry_t routes[8];
+    mib2_ipRouteEntry_t *rp;
+
+    fd = open("/dev/ip", O_RDWR);
+    if (fd < 0) {
+       syslog(LOG_WARNING, "have_route_to: couldn't open /dev/ip: %m");
+       return -1;
+    }
+
+    req.req.PRIM_type = T_OPTMGMT_REQ;
+    req.req.OPT_offset = (char *) &req.hdr - (char *) &req;
+    req.req.OPT_length = sizeof(req.hdr);
+    req.req.MGMT_flags = T_CURRENT;
+
+    req.hdr.level = MIB2_IP;
+    req.hdr.name = 0;
+    req.hdr.len = 0;
+
+    cbuf.buf = (char *) &req;
+    cbuf.len = sizeof(req);
+
+    if (putmsg(fd, &cbuf, NULL, 0) == -1) {
+       syslog(LOG_WARNING, "have_route_to: putmsg: %m");
+       close(fd);
+       return -1;
+    }
+
+    for (;;) {
+       cbuf.buf = (char *) &ack;
+       cbuf.maxlen = sizeof(ack);
+       dbuf.buf = (char *) routes;
+       dbuf.maxlen = sizeof(routes);
+       flags = 0;
+       r = getmsg(fd, &cbuf, &dbuf, &flags);
+       if (r == -1) {
+           syslog(LOG_WARNING, "have_route_to: getmsg: %m");
+           close(fd);
+           return -1;
+       }
+
+       if (cbuf.len < sizeof(struct T_optmgmt_ack)
+           || ack.ack.PRIM_type != T_OPTMGMT_ACK
+           || ack.ack.MGMT_flags != T_SUCCESS
+           || ack.ack.OPT_length < sizeof(struct opthdr)) {
+           syslog(LOG_DEBUG, "have_route_to: bad message len=%d prim=%d",
+                  cbuf.len, ack.ack.PRIM_type);
+           close(fd);
+           return -1;
+       }
+
+       rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset);
+       if (rh->level == 0 && rh->name == 0)
+           break;
+       if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) {
+           while (r == MOREDATA)
+               r = getmsg(fd, NULL, &dbuf, &flags);
+           continue;
+       }
+
+       for (;;) {
+           nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t);
+           for (rp = routes, i = 0; i < nroutes; ++i, ++rp) {
+               if (rp->ipRouteMask != ~0) {
+                   syslog(LOG_DEBUG, "have_route_to: dest=%x gw=%x mask=%x\n",
+                          rp->ipRouteDest, rp->ipRouteNextHop,
+                          rp->ipRouteMask);
+                   if (((addr ^ rp->ipRouteDest) && rp->ipRouteMask) == 0)
+                       return 1;
+               }
+           }
+           if (r == 0)
+               break;
+           r = getmsg(fd, NULL, &dbuf, &flags);
+       }
+    }
+    close(fd);
+    return 0;
+}