X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-linux.c;h=329a141d2940024b0efec25e416eb5d53a315a88;hp=e1bb8108ea0964d81d0c4b64ead2132e97aa5889;hb=a12ffcd5b0a1cf9a4920064295c9b02b127465b3;hpb=d2858ab22a536c8e58f7796b2947f5ff72bb4450 diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index e1bb810..329a141 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -83,6 +83,7 @@ #include #include +#include #include #include #include @@ -96,8 +97,8 @@ #include #include #include -#include #include +#include /* This is in netdevice.h. However, this compile will fail miserably if you attempt to include netdevice.h because it has so many references @@ -110,7 +111,6 @@ #if !defined(__GLIBC__) || __GLIBC__ >= 2 #include /* glibc 2 conflicts with linux/types.h */ -#include #include #include #include @@ -128,14 +128,25 @@ #include #include -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP #include #include +#include +/* Attempt at retaining compile-support with older than 4.7 kernels, or kernels + * where RTM_NEWSTATS isn't defined for whatever reason. + */ +#ifndef RTM_NEWSTATS +#define RTM_NEWSTATS 92 +#define RTM_GETSTATS 94 +#define IFLA_STATS_LINK_64 1 +#endif /* PPP_WITH_IPV6CP */ + #include /* glibc versions prior to 2.24 do not define SOL_NETLINK */ #ifndef SOL_NETLINK #define SOL_NETLINK 270 #endif + /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */ #ifndef NETLINK_CAP_ACK #define NETLINK_CAP_ACK 10 @@ -146,40 +157,22 @@ #include "fsm.h" #include "ipcp.h" -#ifdef IPX_CHANGE -#include "ipxcp.h" -#if __GLIBC__ >= 2 && \ - !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -#include -#else -#include -#endif -#endif /* IPX_CHANGE */ - -#ifdef PPP_FILTER +#ifdef PPP_WITH_FILTER #include #include -#endif /* PPP_FILTER */ +#endif /* PPP_WITH_FILTER */ #ifdef LOCKLIB #include #endif -#ifndef BOTHER -#define BOTHER 0010000 -#endif -struct termios2 { - unsigned int c_iflag; - unsigned int c_oflag; - unsigned int c_cflag; - unsigned int c_lflag; - unsigned char c_line; - unsigned char c_cc[19]; - unsigned int c_ispeed; - unsigned int c_ospeed; -}; +/* + * Instead of system header file use local "termios_linux.h" header + * file as it provides additional support for arbitrary baud rates via BOTHER. + */ +#include "termios_linux.h" -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP #ifndef _LINUX_IN6_H /* * This is in linux/include/net/ipv6.h. @@ -199,7 +192,7 @@ struct in6_ifreq { } while (0) static const eui64_t nulleui64; -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ /* We can get an EIO error on an ioctl if the modem has hung up */ #define ok_error(num) ((num)==EIO) @@ -211,9 +204,9 @@ static int ppp_fd = -1; /* fd which is set to PPP discipline */ static int sock_fd = -1; /* socket for doing interface ioctls */ static int slave_fd = -1; /* pty for old-style demand mode, slave */ static int master_fd = -1; /* pty for old-style demand mode, master */ -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP static int sock6_fd = -1; -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ /* * For the old-style kernel driver, this is the same as ppp_fd. @@ -356,7 +349,7 @@ void sys_init(void) if (sock_fd < 0) fatal("Couldn't create IP socket: %m(%d)", errno); -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); if (sock6_fd < 0) sock6_fd = -errno; /* save errno for later */ @@ -382,15 +375,17 @@ void sys_cleanup(void) if_is_up = 0; sifdown(0); } +#ifdef PPP_WITH_IPV6CP if (if6_is_up) sif6down(0); +#endif /* * Delete any routes through the device. */ if (have_default_route) cifdefaultroute(0, 0, 0); -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP if (have_default_route6) cif6defaultroute(0, nulleui64, nulleui64); #endif @@ -410,7 +405,7 @@ sys_close(void) close(ppp_dev_fd); if (sock_fd >= 0) close(sock_fd); -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP if (sock6_fd >= 0) close(sock6_fd); #endif @@ -907,6 +902,9 @@ struct speed { #ifdef B115200 { 115200, B115200 }, #endif +#ifdef B153600 + { 153600, B153600 }, +#endif #ifdef EXTA { 19200, EXTA }, #endif @@ -916,6 +914,9 @@ struct speed { #ifdef B230400 { 230400, B230400 }, #endif +#ifdef B307200 + { 307200, B307200 }, +#endif #ifdef B460800 { 460800, B460800 }, #endif @@ -925,6 +926,9 @@ struct speed { #ifdef B576000 { 576000, B576000 }, #endif +#ifdef B614400 + { 614400, B614400 }, +#endif #ifdef B921600 { 921600, B921600 }, #endif @@ -1053,40 +1057,32 @@ void set_up_tty(int tty_fd, int local) cfsetospeed (&tios, speed); cfsetispeed (&tios, speed); speed = cfgetospeed(&tios); + baud_rate = baud_rate_of(speed); + } else { +#ifdef BOTHER + tios.c_cflag &= ~CBAUD; + tios.c_cflag |= BOTHER; + tios.c_ospeed = inspeed; +#ifdef IBSHIFT + /* B0 sets input baudrate to the output baudrate */ + tios.c_cflag &= ~(CBAUD << IBSHIFT); + tios.c_cflag |= B0 << IBSHIFT; + tios.c_ispeed = inspeed; +#endif + baud_rate = inspeed; +#else + baud_rate = 0; +#endif } - baud_rate = baud_rate_of(speed); } else { speed = cfgetospeed(&tios); baud_rate = baud_rate_of(speed); - } - - while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) - if (errno != EINTR) - fatal("tcsetattr: %m (line %d)", __LINE__); - restore_term = 1; - -/* Most Linux architectures and drivers support arbitrary baud rate values via BOTHER */ -#ifdef TCGETS2 - if (!baud_rate) { - struct termios2 tios2; - if (ioctl(tty_fd, TCGETS2, &tios2) == 0) { - if (inspeed) { - tios2.c_cflag &= ~CBAUD; - tios2.c_cflag |= BOTHER; - tios2.c_ispeed = inspeed; - tios2.c_ospeed = inspeed; -#ifdef TCSETS2 - if (ioctl(tty_fd, TCSETS2, &tios2) == 0) - baud_rate = inspeed; +#ifdef BOTHER + if (!baud_rate) + baud_rate = tios.c_ospeed; #endif - } else { - if ((tios2.c_cflag & CBAUD) == BOTHER && tios2.c_ospeed) - baud_rate = tios2.c_ospeed; - } - } } -#endif /* * We can't proceed if the serial port baud rate is unknown, @@ -1098,6 +1094,11 @@ void set_up_tty(int tty_fd, int local) else fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } + + while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) + if (errno != EINTR) + fatal("tcsetattr: %m (line %d)", __LINE__); + restore_term = 1; } /******************************************************************** @@ -1424,7 +1425,7 @@ void ccp_flags_set (int unit, int isopen, int isup) modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x); } -#ifdef PPP_FILTER +#ifdef PPP_WITH_FILTER /* * set_filters - set the active and pass filters in the kernel driver. */ @@ -1449,7 +1450,7 @@ int set_filters(struct bpf_program *pass, struct bpf_program *active) } return 1; } -#endif /* PPP_FILTER */ +#endif /* PPP_WITH_FILTER */ /******************************************************************** * @@ -1463,11 +1464,17 @@ get_idle_time(int u, struct ppp_idle *ip) /******************************************************************** * - * get_ppp_stats - return statistics for the link. + * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method, + * this only supports 32-bit counters, so need to count the wraps. */ -int -get_ppp_stats(int u, struct pppd_stats *stats) +static int +get_ppp_stats_ioctl(int u, struct pppd_stats *stats) { + static u_int32_t previbytes = 0; + static u_int32_t prevobytes = 0; + static u_int32_t iwraps = 0; + static u_int32_t owraps = 0; + struct ifpppstatsreq req; memset (&req, 0, sizeof (req)); @@ -1482,7 +1489,262 @@ get_ppp_stats(int u, struct pppd_stats *stats) stats->bytes_out = req.stats.p.ppp_obytes; stats->pkts_in = req.stats.p.ppp_ipackets; stats->pkts_out = req.stats.p.ppp_opackets; + + if (stats->bytes_in < previbytes) + ++iwraps; + if (stats->bytes_out < prevobytes) + ++owraps; + + previbytes = stats->bytes_in; + prevobytes = stats->bytes_out; + + stats->bytes_in += (uint64_t)iwraps << 32; + stats->bytes_out += (uint64_t)owraps << 32; + + return 1; +} + +/******************************************************************** + * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink + * This provides native 64-bit counters. + */ +static int +get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats) +{ + static int rtnl_fd = -1; + + struct sockaddr_nl nladdr; + struct { + struct nlmsghdr nlh; + struct if_stats_msg ifsm; + } nlreq; + struct nlresp { + struct nlmsghdr nlh; + union { + struct { + struct nlmsgerr nlerr; + char __end_err[0]; + }; + struct { + struct rtmsg rth; + struct { + /* We only case about these first fields from rtnl_link_stats64 */ + uint64_t rx_packets; + uint64_t tx_packets; + uint64_t rx_bytes; + uint64_t tx_bytes; + } stats; + char __end_stats[0]; + }; + }; + } nlresp; + ssize_t nlresplen; + struct iovec iov; + struct msghdr msg; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + + if (rtnl_fd < 0) { + rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (rtnl_fd < 0) { + error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__); + return 0; + } + + if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { + error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__); + goto err; + } + } + + memset(&nlreq, 0, sizeof(nlreq)); + nlreq.nlh.nlmsg_len = sizeof(nlreq); + nlreq.nlh.nlmsg_type = RTM_GETSTATS; + nlreq.nlh.nlmsg_flags = NLM_F_REQUEST; + + nlreq.ifsm.ifindex = if_nametoindex(ifname); + nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64; + + memset(&iov, 0, sizeof(iov)); + iov.iov_base = &nlreq; + iov.iov_len = sizeof(nlreq); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &nladdr; + msg.msg_namelen = sizeof(nladdr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + if (sendmsg(rtnl_fd, &msg, 0) < 0) { + error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__); + goto err; + } + + /* We just need to repoint to IOV ... everything else stays the same */ + iov.iov_base = &nlresp; + iov.iov_len = sizeof(nlresp); + + nlresplen = recvmsg(rtnl_fd, &msg, 0); + + if (nlresplen < 0) { + error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__); + goto err; + } + + if (nlresplen < sizeof(nlresp.nlh)) { + error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__); + goto err; + } + + if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) { + if (nlresplen < offsetof(struct nlresp, __end_err)) { + if (kernel_version >= KVERSION(4,7,0)) + error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__); + } else { + error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).", + __LINE__); + } + goto err; + } + + if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) { + error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)", + nlresp.nlh.nlmsg_type, __LINE__); + goto err; + } + + if (nlresplen < offsetof(struct nlresp, __end_stats)) { + error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__); + goto err; + } + + stats->bytes_in = nlresp.stats.rx_bytes; + stats->bytes_out = nlresp.stats.tx_bytes; + stats->pkts_in = nlresp.stats.rx_packets; + stats->pkts_out = nlresp.stats.tx_packets; + return 1; +err: + close(rtnl_fd); + rtnl_fd = -1; + return 0; +} + +/******************************************************************** + * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs, + * this provides native 64-bit counters. + */ +static int +get_ppp_stats_sysfs(int u, struct pppd_stats *stats) +{ + char fname[PATH_MAX+1]; + char buf[21], *err; /* 2^64 < 10^20 */ + int blen, fd, rlen; + unsigned long long val; + + struct { + const char* fname; + void* ptr; + unsigned size; + } slist[] = { +#define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) } + statfield(rx_bytes, bytes_in), + statfield(tx_bytes, bytes_out), + statfield(rx_packets, pkts_in), + statfield(tx_packets, pkts_out), +#undef statfield + }; + + blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname); + if (blen >= sizeof(fname)) + return 0; /* ifname max 15, so this should be impossible */ + + for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) { + if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) { + fname[blen] = 0; + error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname); + return 0; + } + + fd = open(fname, O_RDONLY); + if (fd < 0) { + error("%s: %m", fname); + return 0; + } + + rlen = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (rlen < 0) { + error("%s: %m", fname); + return 0; + } + /* trim trailing \n if present */ + while (rlen > 0 && buf[rlen-1] == '\n') + rlen--; + buf[rlen] = 0; + + errno = 0; + val = strtoull(buf, &err, 10); + if (*buf < '0' || *buf > '9' || errno != 0 || *err) { + error("string to number conversion error converting %s (from %s) for remaining string %s%s%s", + buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : ""); + return 0; + } + switch (slist[i].size) { +#define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break + stattype(uint64_t); + stattype(uint32_t); + stattype(uint16_t); + stattype(uint8_t); +#undef stattype + default: + error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size); + return 0; + } + } + + return 1; +} + +/******************************************************************** + * Periodic timer function to be used to keep stats up to date in case of ioctl + * polling. + * + * Given the 25s interval this should be fine up to data rates of 1.37Gbps. + * If you do change the timer, remember to also bring the get_ppp_stats (which + * sets up the initial trigger) as well. + */ +static void +ppp_stats_poller(void* u) +{ + struct pppd_stats dummy; + get_ppp_stats_ioctl((long)u, &dummy); + TIMEOUT(ppp_stats_poller, u, 25); +} + +/******************************************************************** + * get_ppp_stats - return statistics for the link. + */ +int get_ppp_stats(int u, struct pppd_stats *stats) +{ + static int (*func)(int, struct pppd_stats*) = NULL; + + if (!func) { + if (get_ppp_stats_rtnetlink(u, stats)) { + func = get_ppp_stats_rtnetlink; + return 1; + } + if (get_ppp_stats_sysfs(u, stats)) { + func = get_ppp_stats_sysfs; + return 1; + } + warn("statistics falling back to ioctl which only supports 32-bit counters"); + func = get_ppp_stats_ioctl; + TIMEOUT(ppp_stats_poller, (void*)(long)u, 25); + } + + return func(u, stats); } /******************************************************************** @@ -1844,7 +2106,7 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) return 1; } -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP /* * /proc/net/ipv6_route parsing stuff. */ @@ -2034,7 +2296,7 @@ int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway) return 1; } -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ /******************************************************************** * @@ -2660,15 +2922,15 @@ int sifdown (int u) if (if_is_up && --if_is_up > 0) return 1; -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP if (if6_is_up) return 1; -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ return setifstate(u, 0); } -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP /******************************************************************** * * sif6up - Config the interface up for IPv6 @@ -2699,7 +2961,7 @@ int sif6down (int u) return setifstate(u, 0); } -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ /******************************************************************** * @@ -2870,7 +3132,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) } } - /* This way it is possible to have an IPX-only or IPv6-only interface */ + /* This way it is possible to have an IPv6-only interface */ memset(&ifr, 0, sizeof(ifr)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -2887,7 +3149,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) return 1; } -#ifdef INET6 +#ifdef PPP_WITH_IPV6CP /******************************************************************** * * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink @@ -2954,7 +3216,19 @@ static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64); nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]); nlreq.addrs[1].rta.rta_type = IFA_ADDRESS; - IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64); + + /* + * To set only local address, older kernel expects that local address is + * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer + * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward + * compatibility when setting only local address, set it via both IFA_LOCAL + * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command + * from iproute2 project. + */ + if (!eui64_iszero(his_eui64)) + IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64); + else + IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64); memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -3072,7 +3346,9 @@ int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); return 0; } + } + if (!ret && !eui64_iszero(his_eui64)) { /* * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for * setting remote peer host address, so set only route to remote host. @@ -3134,7 +3410,7 @@ int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) } return 1; } -#endif /* INET6 */ +#endif /* PPP_WITH_IPV6CP */ /* * get_pty - get a pty master/slave pair and chown the slave side @@ -3143,7 +3419,7 @@ int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) int get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) { - int i, mfd, sfd = -1; + int i, mfd, ret, sfd = -1; char pty_name[16]; struct termios tios; @@ -3181,8 +3457,14 @@ get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) pty_name[5] = 't'; sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); if (sfd >= 0) { - fchown(sfd, uid, -1); - fchmod(sfd, S_IRUSR | S_IWUSR); + ret = fchown(sfd, uid, -1); + if (ret != 0) { + warn("Couldn't change ownership of %s, %m", pty_name); + } + ret = fchmod(sfd, S_IRUSR | S_IWUSR); + if (ret != 0) { + warn("Couldn't change permissions of %s, %m", pty_name); + } break; } close(mfd); @@ -3281,99 +3563,6 @@ sifnpmode(int u, int proto, enum NPmode mode) return 1; } - -/******************************************************************** - * - * sipxfaddr - Config the interface IPX networknumber - */ - -int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (line %d)", __LINE__); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - memcpy (sipx->sipx_node, node, IPX_NODE_LEN); - sipx->sipx_family = AF_IPX; - sipx->sipx_port = 0; - sipx->sipx_network = htonl (network); - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_CRTITF; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - result = 0; - if (errno != EEXIST) { - if (! ok_error (errno)) - dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__); - } - else { - warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); - } - } - close (skfd); - } -#endif - return result; -} - -/******************************************************************** - * - * cipxfaddr - Clear the information for the IPX network. The IPX routes - * are removed and the device is no longer able to pass IPX - * frames. - */ - -int cipxfaddr (int unit) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (line %d)", __LINE__); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_DLTITF; - sipx->sipx_family = AF_IPX; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__); - result = 0; - } - close (skfd); - } -#endif - return result; -} - /* * Use the hostname as part of the random number seed. */ @@ -3397,22 +3586,6 @@ get_host_seed(void) int sys_check_options(void) { -#ifdef IPX_CHANGE -/* - * Disable the IPX protocol if the support is not present in the kernel. - */ - char *path; - - if (ipxcp_protent.enabled_flag) { - struct stat stat_buf; - if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL - && (path = path_to_procfs("/net/ipx_interface")) == NULL) - || lstat(path, &stat_buf) < 0) { - error("IPX support is not present in the kernel\n"); - ipxcp_protent.enabled_flag = 0; - } - } -#endif if (demand && driver_is_old) { option_error("demand dialling is not supported by kernel driver " "version %d.%d.%d", driver_version, driver_modification,