X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-svr4.c;h=0743da189060271b1194ff54726f242d9dc3e1b9;hp=5357aebfeb91bcb45aac7f6c7abc069068534cb9;hb=baf120b604ced444e816f4b362ccca4b123b0fcf;hpb=6a53c48e7fe9a14bc21750afdf5d309e6720bba0 diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index 5357aeb..0743da1 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -25,7 +25,7 @@ * OR MODIFICATIONS. */ -#define RCSID "$Id: sys-svr4.c,v 1.35 1999/09/30 19:59:06 masputra Exp $" +#define RCSID "$Id: sys-svr4.c,v 1.41 2000/02/11 03:09:19 masputra Exp $" #include #include @@ -67,9 +67,52 @@ #endif #include "pppd.h" +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" +#include "ccp.h" + +#if !defined(PPP_DEV_NAME) +#define PPP_DEV_NAME "/dev/ppp" +#endif /* !defined(PPP_DEV_NAME) */ + +#if !defined(AHDLC_MOD_NAME) +#define AHDLC_MOD_NAME "ppp_ahdl" +#endif /* !defined(AHDLC_MOD_NAME) */ + +#if !defined(COMP_MOD_NAME) +#define COMP_MOD_NAME "ppp_comp" +#endif /* !defined(COMP_MOD_NAME) */ + +#if !defined(IP_DEV_NAME) +#define IP_DEV_NAME "/dev/ip" +#endif /* !defined(IP_DEV_NAME) */ + +#if !defined(IP_MOD_NAME) +#define IP_MOD_NAME "ip" +#endif /* !defined(IP_MOD_NAME) */ + +#if !defined(UDP_DEV_NAME) && defined(SOL2) +#define UDP_DEV_NAME "/dev/udp" +#endif /* !defined(UDP_DEV_NAME) && defined(SOL2) */ + +#if !defined(UDP6_DEV_NAME) && defined(SOL2) +#define UDP6_DEV_NAME "/dev/udp6" +#endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */ static const char rcsid[] = RCSID; +#if defined(SOL2) +/* + * "/dev/udp" is used as a multiplexor to PLINK the interface stream + * under. It is used in place of "/dev/ip" since STREAMS will not let + * a driver be PLINK'ed under itself, and "/dev/ip" is typically the + * driver at the bottom of the tunneling interfaces stream. + */ +static char *mux_dev_name = UDP_DEV_NAME; +#else +static char *mux_dev_name = IP_DEV_NAME; +#endif static int pppfd; static int fdmuxid = -1; static int ipfd; @@ -156,8 +199,8 @@ static int strioctl __P((int, int, void *, int, int)); */ static int sifppa(fd, ppa) - int fd; - int ppa; + int fd; + int ppa; { return (int)ioctl(fd, IF_UNITSEL, (char *)&ppa); } @@ -172,8 +215,8 @@ sifppa(fd, ppa) */ static int slifname(fd, ppa) - int fd; - int ppa; + int fd; + int ppa; { struct lifreq lifr; int ret; @@ -323,23 +366,24 @@ void sys_init() { int ifd, x; + struct ifreq ifr; #if defined(INET6) && defined(SOL2) int i6fd; + struct lifreq lifr; #endif /* defined(INET6) && defined(SOL2) */ #if !defined(SOL2) - struct ifreq ifr; struct { union DL_primitives prim; char space[64]; } reply; #endif /* !defined(SOL2) */ - ipfd = open("/dev/ip", O_RDWR, 0); + ipfd = open(mux_dev_name, O_RDWR, 0); if (ipfd < 0) fatal("Couldn't open IP device: %m"); #if defined(INET6) && defined(SOL2) - ip6fd = open("/dev/ip", O_RDWR, 0); + ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0); if (ip6fd < 0) fatal("Couldn't open IP device (2): %m"); #endif /* defined(INET6) && defined(SOL2) */ @@ -347,9 +391,9 @@ sys_init() if (default_device && !notty) tty_sid = getsid((pid_t)0); - pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); + pppfd = open(PPP_DEV_NAME, O_RDWR | O_NONBLOCK, 0); if (pppfd < 0) - fatal("Can't open /dev/ppp: %m"); + fatal("Can't open %s: %m", PPP_DEV_NAME); if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); @@ -359,31 +403,33 @@ sys_init() if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) fatal("Can't create new PPP interface: %m"); +#if defined(SOL2) + /* + * Since sys_init() is called prior to ifname being set in main(), + * we need to get the ifname now, otherwise slifname(), and others, + * will fail, or maybe, I should move them to a later point ? + * + */ + sprintf(ifname, "ppp%d", ifunit); +#endif /* defined(SOL2) */ /* * Open the ppp device again and link it under the ip multiplexor. * IP will assign a unit number which hopefully is the same as ifunit. * I don't know any way to be certain they will be the same. :-( */ - ifd = open("/dev/ppp", O_RDWR, 0); + ifd = open(PPP_DEV_NAME, O_RDWR, 0); if (ifd < 0) - fatal("Can't open /dev/ppp (2): %m"); + fatal("Can't open %s (2): %m", PPP_DEV_NAME); if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); } #if defined(INET6) && defined(SOL2) - /* - * Since sys_init() is called prior to ifname being set in main(), - * we need to get the ifname now, otherwise slifname() will fail, - * or maybe, I should move slifname() to a later point ? - */ - sprintf(ifname, "ppp%d", ifunit); - - i6fd = open("/dev/ppp", O_RDWR, 0); + i6fd = open(PPP_DEV_NAME, O_RDWR, 0); if (i6fd < 0) { close(ifd); - fatal("Can't open /dev/ppp (3): %m"); + fatal("Can't open %s (3): %m", PPP_DEV_NAME); } if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; @@ -392,7 +438,7 @@ sys_init() #endif /* defined(INET6) && defined(SOL2) */ #if defined(SOL2) - if (ioctl(ifd, I_PUSH, "ip") < 0) { + if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd); #if defined(INET6) close(i6fd); @@ -418,7 +464,7 @@ sys_init() * explicitly enable it. Note that the interface will be marked * IPv6 during slifname(). */ - if (ioctl(i6fd, I_PUSH, "ip") < 0) { + if (ioctl(i6fd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd); close(i6fd); fatal("Can't push IP module (2): %m"); @@ -436,6 +482,34 @@ sys_init() } #endif /* defined(INET6) */ + ipmuxid = ioctl(ipfd, I_PLINK, ifd); + close(ifd); + if (ipmuxid < 0) { +#if defined(INET6) + close(i6fd); +#endif /* defined(INET6) */ + fatal("Can't I_PLINK PPP device to IP: %m"); + } + + memset(&ifr, 0, sizeof(ifr)); + sprintf(ifr.ifr_name, "%s", ifname); + ifr.ifr_ip_muxid = ipmuxid; + + /* + * In Sol 8 and later, STREAMS dynamic module plumbing feature exists. + * This is so that an arbitrary module can be inserted, or deleted, + * between ip module and the device driver without tearing down the + * existing stream. Such feature requires the mux ids, which is set + * by SIOCSIFMUXID (or SIOCLSIFMUXID). + */ + if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) { + ioctl(ipfd, I_PUNLINK, ipmuxid); +#if defined(INET6) + close(i6fd); +#endif /* defined(INET6) */ + fatal("SIOCSIFMUXID: %m"); + } + #else /* else if !defined(SOL2) */ if (dlpi_attach(ifd, ifunit) < 0 || @@ -443,18 +517,33 @@ sys_init() close(ifd); fatal("Can't attach to ppp%d: %m", ifunit); } -#endif /* defined(SOL2) */ ipmuxid = ioctl(ipfd, I_LINK, ifd); close(ifd); if (ipmuxid < 0) fatal("Can't link PPP device to IP: %m"); +#endif /* defined(SOL2) */ #if defined(INET6) && defined(SOL2) - ip6muxid = ioctl(ip6fd, I_LINK, i6fd); + ip6muxid = ioctl(ip6fd, I_PLINK, i6fd); close(i6fd); - if (ip6muxid < 0) + if (ip6muxid < 0) { + ioctl(ipfd, I_PUNLINK, ipmuxid); + fatal("Can't I_PLINK PPP device to IP (2): %m"); + } + + memset(&lifr, 0, sizeof(lifr)); + sprintf(lifr.lifr_name, "%s", ifname); + lifr.lifr_ip_muxid = ip6muxid; + + /* + * Let IP know of the mux id [see comment for SIOCSIFMUXID above] + */ + if (ioctl(ip6fd, SIOCSLIFMUXID, &lifr) < 0) { + ioctl(ipfd, I_PUNLINK, ipmuxid); + ioctl(ip6fd, I_PUNLINK, ip6muxid); fatal("Can't link PPP device to IP (2): %m"); + } #endif /* defined(INET6) && defined(SOL2) */ #if !defined(SOL2) @@ -476,7 +565,12 @@ sys_init() void sys_cleanup() { +#if defined(SOL2) struct ifreq ifr; +#if defined(INET6) + struct lifreq lifr; +#endif /* defined(INET6) */ +#endif /* defined(SOL2) */ #if defined(SOL2) && defined(INET6) if (if6_is_up) @@ -488,6 +582,53 @@ sys_cleanup() cifdefaultroute(0, default_route_gateway, default_route_gateway); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr); +#if defined(SOL2) + /* + * Make sure we ask ip what the muxid, because 'ifconfig modlist' will + * unlink and re-link the modules, causing the muxid to change. + */ + memset(&ifr, 0, sizeof(ifr)); + sprintf(ifr.ifr_name, "%s", ifname); + if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { + error("SIOCGIFFLAGS: %m"); + return; + } + + if (ioctl(ipfd, SIOCGIFMUXID, &ifr) < 0) { + error("SIOCGIFMUXID: %m"); + return; + } + + ipmuxid = ifr.ifr_ip_muxid; + + if (ioctl(ipfd, I_PUNLINK, ipmuxid) < 0) { + error("Can't I_PUNLINK PPP from IP: %m"); + return; + } +#if defined(INET6) + /* + * Make sure we ask ip what the muxid, because 'ifconfig modlist' will + * unlink and re-link the modules, causing the muxid to change. + */ + memset(&lifr, 0, sizeof(lifr)); + sprintf(lifr.lifr_name, "%s", ifname); + if (ioctl(ip6fd, SIOCGLIFFLAGS, &lifr) < 0) { + error("SIOCGLIFFLAGS: %m"); + return; + } + + if (ioctl(ip6fd, SIOCGLIFMUXID, &lifr) < 0) { + error("SIOCGLIFMUXID: %m"); + return; + } + + ip6muxid = lifr.lifr_ip_muxid; + + if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) { + error("Can't I_PUNLINK PPP from IP (2): %m"); + } +#endif /* defined(INET6) */ +#endif /* defined(SOL2) */ } /* @@ -547,7 +688,28 @@ ppp_available() { struct stat buf; - return stat("/dev/ppp", &buf) >= 0; + return stat(PPP_DEV_NAME, &buf) >= 0; +} + +/* + * any_compressions - see if compression is enabled or not + * + * In the STREAMS implementation of kernel-portion pppd, + * the comp STREAMS module performs the ACFC, PFC, as well + * CCP and VJ compressions. However, if the user has explicitly + * declare to not enable them from the command line, there is + * no point of having the comp module be pushed on the stream. + */ +static int +any_compressions() +{ + if ((!lcp_wantoptions[0].neg_accompression) && + (!lcp_wantoptions[0].neg_pcompression) && + (!ccp_protent.enabled_flag) && + (!ipcp_wantoptions[0].neg_vj)) { + return 0; + } + return 1; } /* @@ -571,7 +733,7 @@ establish_ppp(fd) tty_npushed = 0; if(!sync_serial) { - if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0) { + if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) { error("Couldn't push PPP Async HDLC module: %m"); return -1; } @@ -581,12 +743,21 @@ establish_ppp(fd) i = PPPDBG_LOG + PPPDBG_AHDLC; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } - if (ioctl(fd, I_PUSH, "ppp_comp") < 0) - error("Couldn't push PPP compression module: %m"); - else - ++tty_npushed; + /* + * There's no need to push comp module if we don't intend + * to compress anything + */ + if (any_compressions()) { + if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0) + error("Couldn't push PPP compression module: %m"); + else + ++tty_npushed; + } + if (kdebugflag & 2) { - i = PPPDBG_LOG + PPPDBG_COMP; + i = PPPDBG_LOG; + if (any_compressions()) + i += PPPDBG_COMP; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } @@ -753,6 +924,18 @@ struct speed { #endif #ifdef B115200 { 115200, B115200 }, +#endif +#ifdef B153600 + { 153600, B153600 }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif +#ifdef B307200 + { 307200, B307200 }, +#endif +#ifdef B460800 + { 460800, B460800 }, #endif { 0, 0 } }; @@ -812,7 +995,7 @@ set_up_tty(fd, local) #ifndef CRTSCTS termiox_ok = 1; - if (ioctl (fd, TCGETX, &tiox) < 0) { + if (!sync_serial && ioctl (fd, TCGETX, &tiox) < 0) { termiox_ok = 0; if (errno != ENOTTY) error("TCGETX: %m"); @@ -824,7 +1007,8 @@ set_up_tty(fd, local) #ifndef CRTSCTS inittermiox = tiox; #endif - ioctl(fd, TIOCGWINSZ, &wsinfo); + if (!sync_serial) + ioctl(fd, TIOCGWINSZ, &wsinfo); } tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); @@ -868,7 +1052,7 @@ set_up_tty(fd, local) * We can't proceed if the serial port speed is 0, * since that implies that the serial port is disabled. */ - if (speed == B0) + if ((speed == B0) && !sync_serial) fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } @@ -876,13 +1060,14 @@ set_up_tty(fd, local) fatal("tcsetattr: %m"); #ifndef CRTSCTS - if (termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){ + if (!sync_serial && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){ error("TCSETXF: %m"); } #endif baud_rate = inspeed = baud_rate_of(speed); - restore_term = 1; + if (!sync_serial) + restore_term = 1; } /* @@ -902,16 +1087,17 @@ restore_tty(fd) */ inittermios.c_lflag &= ~(ECHO | ECHONL); } - if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) + if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) if (!hungup && errno != ENXIO) warn("tcsetattr: %m"); #ifndef CRTSCTS - if (ioctl (fd, TCSETXF, &inittermiox) < 0){ + if (!sync_serial && ioctl (fd, TCSETXF, &inittermiox) < 0){ if (!hungup && errno != ENXIO) error("TCSETXF: %m"); } #endif - ioctl(fd, TIOCSWINSZ, &wsinfo); + if (!sync_serial) + ioctl(fd, TIOCSWINSZ, &wsinfo); restore_term = 0; } } @@ -1135,13 +1321,15 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) error("Couldn't set MTU: %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) { - error("Couldn't set transmit ACCM: %m"); + if (!sync_serial) { + if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { + error("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) { + if (any_compressions() && + strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC compression: %m"); } } @@ -1178,6 +1366,9 @@ ppp_set_xaccm(unit, accm) int unit; ext_accm accm; { + if (sync_serial) + return; + if (fdmuxid >= 0 && strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { if (!hungup || errno != ENXIO) @@ -1204,13 +1395,15 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) error("Couldn't set MRU: %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) { - error("Couldn't set receive ACCM: %m"); + if (!sync_serial) { + if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { + error("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) { + if (any_compressions() && + strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC decompression: %m"); } } @@ -1269,7 +1462,8 @@ get_ppp_stats(u, stats) { struct ppp_stats s; - if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { + if (!sync_serial && + strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { error("Couldn't get link statistics: %m"); return 0; } @@ -2251,9 +2445,9 @@ have_route_to(addr) mib2_ipRouteEntry_t routes[8]; mib2_ipRouteEntry_t *rp; - fd = open("/dev/ip", O_RDWR); + fd = open(mux_dev_name, O_RDWR); if (fd < 0) { - warn("have_route_to: couldn't open /dev/ip: %m"); + warn("have_route_to: couldn't open %s: %m", mux_dev_name); return -1; }