*/
#ifndef lint
-static char rcsid[] = "$Id: sys-svr4.c,v 1.17 1998/03/25 02:19:31 paulus Exp $";
+static char rcsid[] = "$Id: sys-svr4.c,v 1.20 1999/02/26 10:35:34 paulus Exp $";
#endif
#include <limits.h>
#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"
static int translate_speed __P((int));
static int baud_rate_of __P((int));
static int get_ether_addr __P((u_int32_t, struct sockaddr *));
-static int get_hw_addr __P((char *, struct sockaddr *));
+static int get_hw_addr __P((char *, u_int32_t, struct sockaddr *));
static int dlpi_attach __P((int, int));
static int dlpi_info_req __P((int));
static int dlpi_get_reply __P((int, union DL_primitives *, int, int));
/*
* sys_check_options - check the options that the user specified
*/
-void
+int
sys_check_options()
{
+ return 1;
}
}
}
+/*
+ * 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().
flags = 0;
len = getmsg(pppfd, &ctrl, &data, &flags);
if (len < 0) {
- if (errno = EAGAIN || errno == EINTR)
+ if (errno == EAGAIN || errno == EINTR)
return -1;
syslog(LOG_ERR, "Error reading packet: %m");
die(1);
}
syslog(LOG_INFO, "found interface %s for proxy ARP", ifr->ifr_name);
- if (!get_hw_addr(ifr->ifr_name, hwaddr)) {
+ if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) {
syslog(LOG_ERR, "Couldn't get hardware address for %s", ifr->ifr_name);
free(ifc.ifc_buf);
return 0;
* get_hw_addr - obtain the hardware address for a named interface.
*/
static int
-get_hw_addr(name, hwaddr)
+get_hw_addr(name, ina, hwaddr)
char *name;
+ u_int32_t ina;
struct sockaddr *hwaddr;
{
+#if 1
+ /* New way - get the address by doing an arp request. */
+ int s;
+ struct arpreq req;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return 0;
+ memset(&req, 0, sizeof(req));
+ 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", ip_ntoa(ina));
+ return 0;
+ }
+ *hwaddr = req.arp_ha;
+ hwaddr->sa_family = AF_UNSPEC;
+
+#else /* 0 */
char *p, *q;
int unit, iffd, adrlen;
unsigned char *adrp;
#endif
hwaddr->sa_family = AF_UNSPEC;
memcpy(hwaddr->sa_data, adrp, adrlen);
+#endif /* 0 */
return 1;
}
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;
+}