X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-svr4.c;h=fcdc6ba22564384a0901871f3d84c5edaf720018;hp=db70a15a9bc0ec4bf92dbfd81a8ab3dd628cee6e;hb=50f06d79e6f4c457a68929df21d4c71b9d2dade1;hpb=d3c4f4748e7df927ea0f6a17dfb215ead2fbb408 diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index db70a15..fcdc6ba 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-svr4.c,v 1.16 1997/04/30 05:59:25 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.20 1999/02/26 10:35:34 paulus Exp $"; #endif #include @@ -61,6 +61,10 @@ static char rcsid[] = "$Id: sys-svr4.c,v 1.16 1997/04/30 05:59:25 paulus Exp $"; #include #include #include +#include +#include +#include +#include #include "pppd.h" @@ -94,7 +98,7 @@ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ 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)); @@ -219,9 +223,10 @@ sys_close() /* * sys_check_options - check the options that the user specified */ -void +int sys_check_options() { + return 1; } @@ -622,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(). @@ -747,7 +760,7 @@ read_packet(buf) 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); @@ -1308,7 +1321,7 @@ get_ether_addr(ipaddr, hwaddr) } 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; @@ -1322,10 +1335,30 @@ get_ether_addr(ipaddr, hwaddr) * 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; @@ -1372,6 +1405,7 @@ get_hw_addr(name, hwaddr) #endif hwaddr->sa_family = AF_UNSPEC; memcpy(hwaddr->sa_data, adrp, adrlen); +#endif /* 0 */ return 1; } @@ -1553,10 +1587,10 @@ logwtmp(line, name, host) } /* - * gethostid - return the serial number of this machine. + * get_host_seed - return the serial number of this machine. */ int -gethostid() +get_host_seed() { char buf[32]; @@ -1688,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; +}