X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fsys-svr4.c;h=d2bc489dd991797211b087d1fcaccaf1c679e5a2;hb=24af3d4d6dbf452f8acaa1a15a9e08f96a0e6eb2;hp=f82a2163e1d34707fe6a235f327d0d66943a1a81;hpb=26a7a28f129d72feaa08ef589e9a49aafd16d984;p=ppp.git diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index f82a216..d2bc489 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,18 +26,13 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-svr4.c,v 1.15 1997/03/04 03:43:54 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.19 1999/01/20 00:01:53 paulus Exp $"; #endif #include #include #include #include -#if defined(SNI) || defined(__USLC__) -extern void *alloca(size_t); -#else -#include -#endif #include #include #include @@ -78,6 +73,7 @@ static int restore_term; static struct termios inittermios; #ifndef CRTSCTS static struct termiox inittermiox; +static int termiox_ok; #endif static struct winsize wsinfo; /* Initial window size info */ static pid_t tty_sid; /* original session ID for terminal */ @@ -98,7 +94,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)); @@ -223,9 +219,10 @@ sys_close() /* * sys_check_options - check the options that the user specified */ -void +int sys_check_options() { + return 1; } @@ -516,9 +513,11 @@ set_up_tty(fd, local) } #ifndef CRTSCTS + termiox_ok = 1; if (ioctl (fd, TCGETX, &tiox) < 0) { - syslog (LOG_ERR, "TCGETX: %m"); - die (1); + termiox_ok = 0; + if (errno != ENOTTY) + syslog (LOG_ERR, "TCGETX: %m"); } #endif @@ -537,10 +536,11 @@ set_up_tty(fd, local) else if (crtscts < 0) tios.c_cflag &= ~CRTSCTS; #else - if (crtscts > 0) { + if (crtscts != 0 && !termiox_ok) { + syslog(LOG_ERR, "Can't set RTS/CTS flow control"); + } else if (crtscts > 0) { tiox.x_hflag |= RTSXOFF|CTSXON; - } - else if (crtscts < 0) { + } else if (crtscts < 0) { tiox.x_hflag &= ~(RTSXOFF|CTSXON); } #endif @@ -583,9 +583,8 @@ set_up_tty(fd, local) } #ifndef CRTSCTS - if (ioctl (fd, TCSETXF, &tiox) < 0){ + if (termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){ syslog (LOG_ERR, "TCSETXF: %m"); - die (1); } #endif @@ -661,7 +660,7 @@ output(unit, p, len) struct pollfd pfd; if (debug) - log_packet(p, len, "sent "); + log_packet(p, len, "sent ", LOG_DEBUG); data.len = len; data.buf = (caddr_t) p; @@ -749,7 +748,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); @@ -798,6 +797,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) int pcomp, accomp; { int cf[2]; + struct ifreq ifr; link_mtu = mtu; if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { @@ -816,6 +816,14 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) syslog(LOG_ERR, "Couldn't set prot/AC compression: %m"); } } + + /* set the MTU for IP as well */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_metric = link_mtu; + if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { + syslog(LOG_ERR, "Couldn't set IP MTU: %m"); + } } /* @@ -1063,6 +1071,7 @@ sifaddr(u, o, h, m) u_int32_t o, h, m; { struct ifreq ifr; + int ret = 1; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -1070,23 +1079,41 @@ sifaddr(u, o, h, m) INET_ADDR(ifr.ifr_addr) = m; if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP netmask: %m"); + ret = 0; } ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = o; if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set local IP address: %m"); + ret = 0; + } + + /* + * On some systems, we have to explicitly set the point-to-point + * flag bit before we can set a destination address. + */ + if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0 + && (ifr.ifr_flags & IFF_POINTOPOINT) == 0) { + ifr.ifr_flags |= IFF_POINTOPOINT; + if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { + syslog(LOG_ERR, "Couldn't mark interface pt-to-pt: %m"); + ret = 0; + } } ifr.ifr_dstaddr.sa_family = AF_INET; INET_ADDR(ifr.ifr_dstaddr) = h; if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set remote IP address: %m"); + ret = 0; } +#if 0 /* now done in ppp_send_config */ ifr.ifr_metric = link_mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP MTU: %m"); } +#endif - return 1; + return ret; } /* @@ -1242,11 +1269,12 @@ get_ether_addr(ipaddr, hwaddr) #endif nif = MAX_IFS; ifc.ifc_len = nif * sizeof(struct ifreq); - ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len); - if (ifc.ifc_req == 0) + ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); + if (ifc.ifc_buf == 0) return 0; if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { syslog(LOG_WARNING, "Couldn't get system interface list: %m"); + free(ifc.ifc_buf); return 0; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); @@ -1276,15 +1304,18 @@ get_ether_addr(ipaddr, hwaddr) if (ifr >= ifend) { syslog(LOG_WARNING, "No suitable interface found for proxy ARP"); + free(ifc.ifc_buf); return 0; } 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; } + free(ifc.ifc_buf); return 1; } @@ -1292,10 +1323,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.sin_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)); + return 0; + } + *hwaddr = req.arp_ha; + hwaddr->sa_family = AF_UNSPEC; + +#else /* 0 */ char *p, *q; int unit, iffd, adrlen; unsigned char *adrp; @@ -1342,6 +1393,7 @@ get_hw_addr(name, hwaddr) #endif hwaddr->sa_family = AF_UNSPEC; memcpy(hwaddr->sa_data, adrp, adrlen); +#endif /* 0 */ return 1; } @@ -1460,11 +1512,12 @@ GetMask(addr) #endif nif = MAX_IFS; ifc.ifc_len = nif * sizeof(struct ifreq); - ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len); - if (ifc.ifc_req == 0) + ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); + if (ifc.ifc_buf == 0) return mask; if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { syslog(LOG_WARNING, "Couldn't get system interface list: %m"); + free(ifc.ifc_buf); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); @@ -1494,6 +1547,7 @@ GetMask(addr) mask |= INET_ADDR(ifreq.ifr_addr); } + free(ifc.ifc_buf); return mask; } @@ -1521,10 +1575,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];