X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-linux.c;h=ba25a93ec843a653635adda286955dc3a603da99;hp=7f0e581ccee7fd3c1e0ba24c8ebc3dfe84f77915;hb=5ba9d88b943e9d5a3ababdadf1d2e246581dfdc6;hpb=bcffc4820fca2aba7b91657909bc0cb76f69227e diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 7f0e581..ba25a93 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -120,6 +120,7 @@ static unsigned char inbuf[512]; /* buffer for chars read from loopback */ static int if_is_up; /* Interface has been marked up */ static u_int32_t default_route_gateway; /* Gateway for default route added */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ +static char proxy_arp_dev[16]; /* Device for proxy arp entry */ static char *lock_file; @@ -144,8 +145,10 @@ static int open_route_table (void); static int read_route_table (struct rtentry *rt); static int defaultroute_exists (struct rtentry *rt); static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name); + char *name, int namelen); static void decode_version (char *buf, int *version, int *mod, int *patch); +static int set_kdebugflag(int level); +static int ppp_registered(void); extern u_char inpacket_buf[]; /* borrowed from main.c */ @@ -251,7 +254,7 @@ void sys_init(void) * * sys_cleanup - restore any system state we modified before exiting: * mark the interface down, delete default route and/or proxy arp entry. - * This should call die() because it's called from die(). + * This shouldn't call die() because it's called from die(). */ void sys_cleanup(void) @@ -283,28 +286,12 @@ sys_close(void) closelog(); } -/******************************************************************** - * - * note_debug_level - note a change in the debug level. - */ - -void note_debug_level (void) -{ - if (debug) { - SYSDEBUG ((LOG_INFO, "Debug turned ON, Level %d", debug)); - setlogmask(LOG_UPTO(LOG_DEBUG)); - } - else { - setlogmask(LOG_UPTO(LOG_WARNING)); - } -} - /******************************************************************** * * set_kdebugflag - Define the debugging level for the kernel */ -int set_kdebugflag (int requested_level) +static int set_kdebugflag (int requested_level) { if (ioctl(ppp_fd, PPPIOCSDEBUG, &requested_level) < 0) { if ( ! ok_error (errno) ) @@ -660,7 +647,7 @@ void set_up_tty(int tty_fd, int local) fatal("tcsetattr: %m"); baud_rate = baud_rate_of(speed); - restore_term = TRUE; + restore_term = 1; } /******************************************************************** @@ -859,7 +846,7 @@ void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp) * Set the MTU and other parameters for the ppp device */ memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); ifr.ifr_mtu = mtu; if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) @@ -978,6 +965,30 @@ get_idle_time(u, ip) return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0; } +/******************************************************************** + * + * get_ppp_stats - return statistics for the link. + */ +int +get_ppp_stats(u, stats) + int u; + struct pppd_stats *stats; +{ + struct ifpppstatsreq req; + + memset (&req, 0, sizeof (req)); + + req.stats_ptr = (caddr_t) &req.stats; + strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); + if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { + error("Couldn't get PPP statistics: %m"); + return 0; + } + stats->bytes_in = req.stats.p.ppp_ibytes; + stats->bytes_out = req.stats.p.ppp_obytes; + return 1; +} + /******************************************************************** * * ccp_fatal_error - returns 1 if decompression was disabled as a @@ -1020,7 +1031,7 @@ static int path_to_procfs (void) fp = fopen(MOUNTED, "r"); if (fp == NULL) { /* Default the mount location of /proc */ - strlcpy (route_buffer, sizeof (route_buffer), "/proc"); + strlcpy (route_buffer, "/proc", sizeof (route_buffer)); return 1; } @@ -1034,7 +1045,7 @@ static int path_to_procfs (void) if (mntent == 0) return 0; - strlcpy(route_buffer, sizeof (route_buffer), mntent->mnt_dir); + strlcpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer)); return 1; } @@ -1049,7 +1060,7 @@ static char *path_to_route (void) error("proc file system not mounted"); return 0; } - strlcat (route_buffer, sizeof(route_buffer), "/net/route"); + strlcat (route_buffer, "/net/route", sizeof(route_buffer)); return (route_buffer); } @@ -1310,11 +1321,13 @@ int sifproxyarp (int unit, u_int32_t his_adr) * Get the hardware address of an interface on the same subnet * as our local address. */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq.arp_dev)) { + if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, + sizeof(proxy_arp_dev))) { error("Cannot determine ethernet address for proxy ARP"); return 0; } - + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); + if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { if ( ! ok_error ( errno )) error("ioctl(SIOCSARP): %m(%d)", errno); @@ -1342,6 +1355,7 @@ int cifproxyarp (int unit, u_int32_t his_adr) SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { if ( ! ok_error ( errno )) @@ -1360,7 +1374,7 @@ int cifproxyarp (int unit, u_int32_t his_adr) static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name) + char *name, int namelen) { struct ifreq *ifr, *ifend; u_int32_t ina, mask; @@ -1386,7 +1400,7 @@ static int get_ether_addr (u_int32_t ipaddr, for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s", ifreq.ifr_name)); /* @@ -1417,7 +1431,7 @@ static int get_ether_addr (u_int32_t ipaddr, if (ifr >= ifend) return 0; - memcpy (name, ifreq.ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(name, ifreq.ifr_name, namelen); info("found interface %s for proxy arp", name); /* * Now get the hardware address. @@ -1497,7 +1511,7 @@ u_int32_t GetMask (u_int32_t addr) /* * Check that the interface is up, and not point-to-point nor loopback. */ - strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) continue; @@ -1547,7 +1561,7 @@ static void decode_version (char *buf, int *version, * Procedure to determine if the PPP line discipline is registered. */ -int +static int ppp_registered(void) { int local_fd; @@ -1615,7 +1629,7 @@ int ppp_available(void) if (s < 0) return 0; - strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; /* * If the device did not exist then attempt to create one by putting the @@ -1624,7 +1638,7 @@ int ppp_available(void) */ if (!ok) { if (ppp_registered()) { - strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; } } @@ -1727,10 +1741,10 @@ void logwtmp (const char *line, const char *name, const char *host) memset(&ut, 0, sizeof(ut)); if (ut.ut_id[0] == 0) - strlcpy(ut.ut_id, sizeof(ut.ut_id), line + 3); + strlcpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); - strlcpy(ut.ut_user, sizeof(ut.ut_user), name); - strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_user, name, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, line, sizeof(ut.ut_line)); time(&ut.ut_time); @@ -1739,7 +1753,7 @@ void logwtmp (const char *line, const char *name, const char *host) /* Insert the host name if one is supplied */ if (*host) - strlcpy (ut.ut_host, sizeof(ut.ut_host), host); + strlcpy (ut.ut_host, host, sizeof(ut.ut_host)); /* Insert the IP address of the remote system if IP is enabled */ if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) @@ -1939,7 +1953,7 @@ int sifup (int u) struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); @@ -1968,7 +1982,7 @@ int sifdown (int u) if_is_up = 0; memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); @@ -2003,7 +2017,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); /* * Set our IP address */ @@ -2105,45 +2119,71 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) return 1; } -/******************************************************************** - * - * open_loopback - open the device we use for getting packets - * in demand mode. Under Linux, we use our existing fd - * to the ppp driver. +/* + * get_pty - get a pty master/slave pair and chown the slave side + * to the uid given. Assumes slave_name points to >= 12 bytes of space. */ int -open_ppp_loopback(void) +get_pty(master_fdp, slave_fdp, slave_name, uid) + int *master_fdp; + int *slave_fdp; + char *slave_name; + int uid; { - int flags, i; + int i, mfd, sfd; + char pty_name[12]; struct termios tios; - master_fd = -1; + sfd = -1; for (i = 0; i < 64; ++i) { - slprintf(loop_name, sizeof(loop_name), "/dev/pty%c%x", + slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", 'p' + i / 16, i % 16); - master_fd = open(loop_name, O_RDWR | O_NOCTTY, 0); - if (master_fd >= 0) - break; + mfd = open(pty_name, O_RDWR, 0); + if (mfd >= 0) { + pty_name[5] = 't'; + sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); + if (sfd >= 0) + break; + close(mfd); + } } - if (master_fd < 0) - fatal("No free pty for loopback"); - SYSDEBUG(("using %s for loopback", loop_name)); - loop_name[5] = 't'; - slave_fd = open(loop_name, O_RDWR | O_NOCTTY, 0); - if (slave_fd < 0) - fatal("Couldn't open %s for loopback: %m", loop_name); - - set_ppp_fd(slave_fd); + if (sfd < 0) + return 0; - if (tcgetattr(ppp_fd, &tios) == 0) { + strlcpy(slave_name, pty_name, 12); + *master_fdp = mfd; + *slave_fdp = sfd; + fchown(sfd, uid, -1); + fchmod(sfd, S_IRUSR | S_IWUSR); + if (tcgetattr(sfd, &tios) == 0) { tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); tios.c_cflag |= CS8 | CREAD; tios.c_iflag = IGNPAR | CLOCAL; tios.c_oflag = 0; tios.c_lflag = 0; - if (tcsetattr(ppp_fd, TCSAFLUSH, &tios) < 0) - warn("couldn't set attributes on loopback: %m(%d)", errno); - } + if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) + warn("couldn't set attributes on pty: %m"); + } else + warn("couldn't get attributes on pty: %m"); + + return 1; +} + +/******************************************************************** + * + * open_loopback - open the device we use for getting packets + * in demand mode. Under Linux, we use a pty master/slave pair. + */ +int +open_ppp_loopback(void) +{ + int flags; + + if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) + fatal("No free pty for loopback"); + SYSDEBUG(("using %s for loopback", loop_name)); + + set_ppp_fd(slave_fd); flags = fcntl(master_fd, F_GETFL); if (flags == -1 || @@ -2167,7 +2207,7 @@ open_ppp_loopback(void) */ set_kdebugflag (kdebugflag); - return ppp_fd; + return master_fd; } /******************************************************************** @@ -2241,7 +2281,7 @@ int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) } else { memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname); + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); memcpy (sipx->sipx_node, node, IPX_NODE_LEN); sipx->sipx_family = AF_IPX; @@ -2292,7 +2332,7 @@ int cipxfaddr (int unit) } else { memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname); + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); sipx->sipx_type = IPX_FRAME_ETHERII; sipx->sipx_action = IPX_DLTITF; @@ -2366,7 +2406,7 @@ sys_check_options(void) */ while (ipxcp_protent.enabled_flag) { if (path_to_procfs()) { - strlcat (route_buffer, sizeof(route_buffer), "/net/ipx_interface"); + strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer)); if (lstat (route_buffer, &stat_buf) >= 0) break; }