X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-osf.c;h=cba5e356ee5674e1b752e92b940ed14e22e4da6a;hp=b328ebb18e87b271413fed7ab5086fa6d69996db;hb=1fae28ce79350b03f0cf8a69ad06dd68637cd6b1;hpb=26a7a28f129d72feaa08ef589e9a49aafd16d984 diff --git a/pppd/sys-osf.c b/pppd/sys-osf.c index b328ebb..cba5e35 100644 --- a/pppd/sys-osf.c +++ b/pppd/sys-osf.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-osf.c,v 1.11 1997/03/04 03:43:53 paulus Exp $"; +static char rcsid[] = "$Id: sys-osf.c,v 1.18 1999/03/12 06:07:22 paulus Exp $"; #endif #include @@ -50,12 +50,15 @@ static char rcsid[] = "$Id: sys-osf.c,v 1.11 1997/03/04 03:43:53 paulus Exp $"; #include #include #include +#include #include +#include #include #include #include #include #include +#include #include "pppd.h" @@ -202,9 +205,10 @@ sys_close() /* * sys_check_options - check the options that the user specified */ -void +int sys_check_options() { + return 1; } @@ -750,7 +754,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; @@ -981,6 +985,8 @@ ccp_test(unit, opt_ptr, opt_len, for_transmit) break; wait_time(&tval); } + if (errno != 0) + syslog(LOG_ERR, "hard failure trying to get memory for a compressor: %m"); return (errno == ENOSR)? 0: -1; } @@ -1071,7 +1077,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface up (get): %m"); return 0; @@ -1094,7 +1100,7 @@ sifdown(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface down (get): %m"); return 0; @@ -1157,7 +1163,7 @@ sifaddr(u, o, h, m) /* flush old address, if any */ bzero(&ifr, sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if ((ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) @@ -1167,7 +1173,7 @@ sifaddr(u, o, h, m) } bzero(&addreq, sizeof (addreq)); - strncpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name)); + strlcpy(addreq.ifra_name, sizeof (addreq.ifra_name), ifname); SET_SA_FAMILY(addreq.ifra_addr, AF_INET); SET_SA_FAMILY(addreq.ifra_broadaddr, AF_INET); ((struct sockaddr_in *)&addreq.ifra_addr)->sin_addr.s_addr = o; @@ -1186,6 +1192,12 @@ sifaddr(u, o, h, m) ret = 0; } + ifr.ifr_metric = link_mtu; + if (ioctl(sockfd, SIOCSIPMTU, &ifr) < 0) { + syslog(LOG_ERR, "Couldn't set IP MTU: %m"); + ret = 0; + } + ifaddrs[0] = o; ifaddrs[1] = h; return (ret); @@ -1204,8 +1216,9 @@ cifaddr(u, o, h) struct ifreq ifr; ifaddrs[0] = 0; + ifaddrs[1] = 0; bzero(&ifr, sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if (ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) { @@ -1355,7 +1368,7 @@ get_ether_addr(ipaddr, hwaddr) * Check that the interface is up, and not point-to-point * or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1384,7 +1397,7 @@ get_ether_addr(ipaddr, hwaddr) return 0; syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); - strncpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name)); + strlcpy(ifdevreq.ifr_name, sizeof(ifdevreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) { perror("ioctl(SIOCRPHYSADDR)"); @@ -1409,9 +1422,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1468,7 +1481,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1490,6 +1503,71 @@ GetMask(addr) return mask; } +/* + * have_route_to - determine if the system has any route to + * a given IP address. `addr' is in network byte order. + * For demand mode to work properly, we have to ignore routes + * through our own interface. + */ +int have_route_to(u_int32_t addr) +{ + char buf[sizeof(struct rt_msghdr) + (sizeof(struct sockaddr_in))]; + int status; + int s, n; + struct rt_msghdr *rtm; + struct sockaddr_in *sin; + int msglen = sizeof(*rtm) + (sizeof(*sin)); + char *cp; + char msg[2048]; + + rtm = (struct rt_msghdr *)buf; + memset(rtm, 0, msglen); + rtm->rtm_msglen = msglen; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_addrs = RTA_DST; + /* rtm->rtm_addrs, rtm_flags should be set on output */ + + sin = (struct sockaddr_in *)((u_char *)rtm + sizeof(*rtm)); + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = addr; + + status = 0; + + if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) + return -1; + if (write(s, (char *)rtm, msglen) != msglen) { + close(s); + return status == ESRCH? 0: -1; + } + + n = read(s, msg, 2048); + close(s); + if (n <= 0) + return -1; + + rtm = (struct rt_msghdr *) msg; + if (rtm->rtm_version != RTM_VERSION) + return -1; + + /* here we try to work out if the route is through our own interface */ + cp = (char *)(rtm + 1); + if (rtm->rtm_addrs & RTA_DST) { + struct sockaddr *sa = (struct sockaddr *) cp; + cp = (char *)(((unsigned long)cp + sa->sa_len + + sizeof(long) - 1) & ~(sizeof(long) - 1)); + } + if (rtm->rtm_addrs & RTA_GATEWAY) { + sin = (struct sockaddr_in *) cp; + if (sin->sin_addr.s_addr == ifaddrs[0] + || sin->sin_addr.s_addr == ifaddrs[1]) + return 0; /* route is through our interface */ + } + + return 1; +} + static int strioctl(fd, cmd, ptr, ilen, olen) int fd, cmd, ilen, olen; @@ -1509,6 +1587,15 @@ strioctl(fd, cmd, ptr, ilen, olen) return 0; } +/* + * Use the hostid as part of the random number seed. + */ +int +get_host_seed() +{ + return gethostid(); +} + /* * Code for locking/unlocking the serial device. * This code is derived from chat.c. @@ -1539,13 +1626,15 @@ lock(dev) char hdb_lock_buffer[12]; int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST