X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-svr4.c;h=db70a15a9bc0ec4bf92dbfd81a8ab3dd628cee6e;hp=258cfae7d9d6ee853b9747c8f8edadc862dc53e5;hb=0d9e6e56127e07e7e39a7612c0bcb3f4edd3da0d;hpb=1e31b548741443095679070638f5344cb5df1c9d diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index 258cfae..db70a15 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,14 +26,13 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-svr4.c,v 1.11 1996/05/27 00:01:53 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.16 1997/04/30 05:59:25 paulus Exp $"; #endif #include #include #include #include -#include #include #include #include @@ -74,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 */ @@ -130,7 +130,7 @@ sys_init() syslog(LOG_ERR, "Can't open /dev/ppp: %m"); die(1); } - if (kdebugflag) { + if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); } @@ -151,7 +151,7 @@ sys_init() syslog(LOG_ERR, "Can't open /dev/ppp (2): %m"); die(1); } - if (kdebugflag) { + if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); } @@ -200,7 +200,7 @@ sys_cleanup() if (if_is_up) sifdown(0); if (default_route_gateway) - cifdefaultroute(0, default_route_gateway); + cifdefaultroute(0, default_route_gateway, default_route_gateway); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr); } @@ -281,10 +281,18 @@ establish_ppp(fd) syslog(LOG_ERR, "Couldn't push PPP Async HDLC module: %m"); die(1); } + if (kdebugflag & 4) { + i = PPPDBG_LOG + PPPDBG_AHDLC; + strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); + } if (ioctl(fd, I_PUSH, "ppp_comp") < 0) { syslog(LOG_ERR, "Couldn't push PPP compression module: %m"); /* die(1); */ } + if (kdebugflag & 2) { + i = PPPDBG_LOG + PPPDBG_COMP; + strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); + } /* Link the serial port under the PPP multiplexor. */ if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) { @@ -504,9 +512,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 @@ -525,10 +535,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 @@ -571,9 +582,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 @@ -649,7 +659,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; @@ -786,6 +796,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) { @@ -793,13 +804,24 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) return; syslog(LOG_ERR, "Couldn't set MTU: %m"); } - if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - syslog(LOG_ERR, "Couldn't set transmit ACCM: %m"); + if (fdmuxid >= 0) { + /* can't set these if we don't have a stream attached below /dev/ppp */ + if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { + syslog(LOG_ERR, "Couldn't set transmit ACCM: %m"); + } + cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); + cf[1] = COMP_PROT | COMP_AC; + if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { + syslog(LOG_ERR, "Couldn't set prot/AC compression: %m"); + } } - cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); - cf[1] = COMP_PROT | COMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - 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"); } } @@ -811,7 +833,8 @@ ppp_set_xaccm(unit, accm) int unit; ext_accm accm; { - if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { + if (fdmuxid >= 0 + && strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { if (!hungup || errno != ENXIO) syslog(LOG_WARNING, "Couldn't set extended ACCM: %m"); } @@ -835,13 +858,16 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) return; syslog(LOG_ERR, "Couldn't set MRU: %m"); } - if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - syslog(LOG_ERR, "Couldn't set receive ACCM: %m"); - } - cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); - cf[1] = DECOMP_PROT | DECOMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - syslog(LOG_ERR, "Couldn't set prot/AC decompression: %m"); + if (fdmuxid >= 0) { + /* can't set these if we don't have a stream attached below /dev/ppp */ + if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { + syslog(LOG_ERR, "Couldn't set receive ACCM: %m"); + } + cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); + cf[1] = DECOMP_PROT | DECOMP_AC; + if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { + syslog(LOG_ERR, "Couldn't set prot/AC decompression: %m"); + } } } @@ -1044,6 +1070,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)); @@ -1051,23 +1078,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; } /* @@ -1079,8 +1124,10 @@ cifaddr(u, o, h) int u; u_int32_t o, h; { -#if 0 +#if defined(__USLC__) /* was: #if 0 */ + cifroute(unit, ouraddr, hisaddr); if (ipmuxid >= 0) { + syslog(LOG_NOTICE, "Removing ppp interface unit"); if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) { syslog(LOG_ERR, "Can't remove ppp interface unit: %m"); return 0; @@ -1095,12 +1142,15 @@ cifaddr(u, o, h) * sifdefaultroute - assign a default route through the address given. */ int -sifdefaultroute(u, g) +sifdefaultroute(u, l, g) int u; - u_int32_t g; + u_int32_t l, g; { struct rtentry rt; +#if defined(__USLC__) + g = l; /* use the local address as gateway */ +#endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; @@ -1121,12 +1171,15 @@ sifdefaultroute(u, g) * cifdefaultroute - delete a default route through the address given. */ int -cifdefaultroute(u, g) +cifdefaultroute(u, l, g) int u; - u_int32_t g; + u_int32_t l, g; { struct rtentry rt; +#if defined(__USLC__) + g = l; /* use the local address as gateway */ +#endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; @@ -1215,11 +1268,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); @@ -1249,15 +1303,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)) { 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; } @@ -1433,11 +1490,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); @@ -1467,15 +1525,16 @@ GetMask(addr) mask |= INET_ADDR(ifreq.ifr_addr); } + free(ifc.ifc_buf); return mask; } /* * logwtmp - write an accounting record to the /var/adm/wtmp file. */ -int +void logwtmp(line, name, host) - char *line, *name, *host; + const char *line, *name, *host; { static struct utmpx utmpx; @@ -1491,7 +1550,6 @@ logwtmp(line, name, host) } gettimeofday(&utmpx.ut_tv, NULL); updwtmpx("/var/adm/wtmpx", &utmpx); - return 0; } /* @@ -1604,3 +1662,29 @@ unlock() lock_file[0] = 0; } } + + +/* + * cifroute - delete a route through the addresses given. + */ +int +cifroute(u, our, his) + int u; + u_int32_t our, his; +{ + struct rtentry rt; + + memset(&rt, 0, sizeof(rt)); + rt.rt_dst.sa_family = AF_INET; + INET_ADDR(rt.rt_dst) = his; + rt.rt_gateway.sa_family = AF_INET; + INET_ADDR(rt.rt_gateway) = our; + rt.rt_flags = RTF_HOST; + + if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { + syslog(LOG_ERR, "Can't delete route: %m"); + return 0; + } + + return 1; +}