Same story for me. Without the patch ppp spins forever and eats all cpu. With the patch ppp runs fine. I'm pretty sure it worked for me with the Jun 21 snapshot.
Mike Erdely wrote: > With prodding from Todd, I tested the diff on my macppc and my alpha. > Before the diff, running `ppp default` as root would hang before > presenting me with the interactive prompt. With the diff, it > immediately goes into interactive mode and presents me with the prompt. > > Unfortunately, I don't have another way to test. > > -ME > > On Wed, Jul 01, 2009 at 11:23:20AM -0500, Todd T. Fries wrote: >> Guys, >> >> I tested this and it seems ppp in the tree is busted to the point of not >> working without this diff. >> >> If you use ppp please test current snaps to confirm it is busted then >> apply claudio's diff below and test again. >> >> If you use ppp and do not test, do not be surprised if it does not work in >> the next release. >> >> Thanks, >> >> Penned by Claudio Jeker on 20090630 17:05.28, we have: >> | So ppp(8) did insane routing message handling in its sysctl handlers. The >> | worst thing about them are that their actually not needed and better >> | replaced with libc functions (getifaddrs and if_nametoindex). >> | >> | This diff is not haevily tested (my last ppp usage is years ago) so I'm >> | hopeing people with ppp(8) issues could give this a whirl and see if it >> | fixes the problems. >> | -- >> | :wq Claudio >> | >> | Index: ppp/arp.c >> | =================================================================== >> | RCS file: /cvs/src/usr.sbin/ppp/ppp/arp.c,v >> | retrieving revision 1.15 >> | diff -u -p -r1.15 arp.c >> | --- ppp/arp.c 6 May 2008 06:34:10 -0000 1.15 >> | +++ ppp/arp.c 30 Jun 2009 14:52:53 -0000 >> | @@ -38,6 +38,7 @@ >> | #include <sys/un.h> >> | >> | #include <errno.h> >> | +#include <ifaddrs.h> >> | #include <stdio.h> >> | #include <stdlib.h> >> | #include <string.h> >> | @@ -229,93 +230,58 @@ int >> | arp_EtherAddr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr, >> | int verbose) >> | { >> | - int mib[6], skip; >> | - size_t needed; >> | - char *buf, *ptr, *end; >> | - struct if_msghdr *ifm; >> | - struct ifa_msghdr *ifam; >> | - struct sockaddr_dl *dl; >> | - struct sockaddr *sa[RTAX_MAX]; >> | - >> | - mib[0] = CTL_NET; >> | - mib[1] = PF_ROUTE; >> | - mib[2] = 0; >> | - mib[3] = 0; >> | - mib[4] = NET_RT_IFLIST; >> | - mib[5] = 0; >> | - >> | - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { >> | - log_Printf(LogERROR, "arp_EtherAddr: sysctl: estimate: %s\n", >> | - strerror(errno)); >> | - return 0; >> | - } >> | - >> | - if ((buf = malloc(needed)) == NULL) >> | - return 0; >> | + struct sockaddr_dl *dl = NULL; >> | + struct ifaddrs *ifa, *ifap; >> | + int skip = 1; >> | >> | - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { >> | - free(buf); >> | + if (getifaddrs(&ifap) != 0) { >> | + log_Printf(LogERROR, "arp_EtherAddr: getifaddrs: %s\n", >> strerror(errno)); >> | return 0; >> | } >> | - end = buf + needed; >> | >> | - ptr = buf; >> | - while (ptr < end) { >> | - ifm = (struct if_msghdr *)ptr; /* On if_msghdr */ >> | - if (ifm->ifm_type != RTM_IFINFO) >> | - break; >> | - ptr += ifm->ifm_msglen; >> | - if (ifm->ifm_version != RTM_VERSION) >> | - continue; >> | - dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */ >> | - skip = (ifm->ifm_flags & (IFF_UP | IFF_BROADCAST | IFF_POINTOPOINT | >> | + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { >> | + if (ifa->ifa_addr->sa_family == AF_LINK) { >> | + dl = (struct sockaddr_dl *)ifa->ifa_addr; >> | + skip = (ifa->ifa_flags & (IFF_UP | IFF_BROADCAST | IFF_POINTOPOINT | >> | IFF_NOARP | IFF_LOOPBACK)) != (IFF_UP | IFF_BROADCAST); >> | - while (ptr < end) { >> | - ifam = (struct ifa_msghdr *)ptr; /* Next ifa_msghdr (alias) */ >> | - if (ifam->ifam_type != RTM_NEWADDR) /* finished ? */ >> | - break; >> | - ptr += ifam->ifam_msglen; >> | - if (ifam->ifam_version != RTM_VERSION) >> | - continue; >> | - if (skip || (ifam->ifam_addrs & (RTA_NETMASK|RTA_IFA)) != >> | - (RTA_NETMASK|RTA_IFA)) >> | - continue; >> | - /* Found a candidate. Do the addresses match ? */ >> | - if (log_IsKept(LogDEBUG) && >> | - ptr == (char *)ifm + ifm->ifm_msglen + ifam->ifam_msglen) >> | - log_Printf(LogDEBUG, "%.*s interface is a candidate for proxy\n", >> | - dl->sdl_nlen, dl->sdl_data); >> | - >> | - iface_ParseHdr(ifam, sa); >> | - >> | - if (sa[RTAX_IFA]->sa_family == AF_INET) { >> | - struct sockaddr_in *ifa, *netmask; >> | - >> | - ifa = (struct sockaddr_in *)sa[RTAX_IFA]; >> | - netmask = (struct sockaddr_in *)sa[RTAX_NETMASK]; >> | - >> | - if (log_IsKept(LogDEBUG)) { >> | - char a[16]; >> | - >> | - strncpy(a, inet_ntoa(netmask->sin_addr), sizeof a - 1); >> | - a[sizeof a - 1] = '\0'; >> | - log_Printf(LogDEBUG, "Check addr %s, mask %s\n", >> | - inet_ntoa(ifa->sin_addr), a); >> | - } >> | - >> | - if ((ifa->sin_addr.s_addr & netmask->sin_addr.s_addr) == >> | - (ipaddr.s_addr & netmask->sin_addr.s_addr)) { >> | - log_Printf(verbose ? LogPHASE : LogDEBUG, >> | - "Found interface %.*s for %s\n", dl->sdl_nlen, >> | - dl->sdl_data, inet_ntoa(ipaddr)); >> | - memcpy(hwaddr, dl, dl->sdl_len); >> | - free(buf); >> | - return 1; >> | - } >> | + continue; >> | + } >> | + if (skip) >> | + /* Skip unusable interface */ >> | + continue; >> | + >> | + /* Found a candidate. Do the addresses match ? */ >> | + if (log_IsKept(LogDEBUG)) >> | + log_Printf(LogDEBUG, "%.*s interface is a candidate for proxy\n", >> | + dl->sdl_nlen, dl->sdl_data); >> | + >> | + if (ifa->ifa_addr->sa_family == AF_INET) { >> | + struct sockaddr_in *addr, *netmask; >> | + >> | + addr = (struct sockaddr_in *)ifa->ifa_addr; >> | + netmask = (struct sockaddr_in *)ifa->ifa_netmask; >> | + >> | + if (log_IsKept(LogDEBUG)) { >> | + char a[16]; >> | + >> | + strncpy(a, inet_ntoa(netmask->sin_addr), sizeof a - 1); >> | + a[sizeof a - 1] = '\0'; >> | + log_Printf(LogDEBUG, "Check addr %s, mask %s\n", >> | + inet_ntoa(addr->sin_addr), a); >> | + } >> | + >> | + if ((addr->sin_addr.s_addr & netmask->sin_addr.s_addr) == >> | + (ipaddr.s_addr & netmask->sin_addr.s_addr)) { >> | + log_Printf(verbose ? LogPHASE : LogDEBUG, >> | + "Found interface %.*s for %s\n", dl->sdl_nlen, >> | + dl->sdl_data, inet_ntoa(ipaddr)); >> | + memcpy(hwaddr, dl, dl->sdl_len); >> | + freeifaddrs(ifap); >> | + return 1; >> | } >> | } >> | } >> | - free(buf); >> | + freeifaddrs(ifap); >> | >> | return 0; >> | } >> | Index: ppp/iface.c >> | =================================================================== >> | RCS file: /cvs/src/usr.sbin/ppp/ppp/iface.c,v >> | retrieving revision 1.28 >> | diff -u -p -r1.28 iface.c >> | --- ppp/iface.c 25 Jun 2009 15:59:28 -0000 1.28 >> | +++ ppp/iface.c 30 Jun 2009 14:54:08 -0000 >> | @@ -44,6 +44,7 @@ >> | #include <sys/un.h> >> | >> | #include <errno.h> >> | +#include <ifaddrs.h> >> | #include <string.h> >> | #include <stdarg.h> >> | #include <stdio.h> >> | @@ -90,114 +91,64 @@ static const struct in6_addr in6mask128 >> | struct iface * >> | iface_Create(const char *name) >> | { >> | - int mib[6], maxtries, err; >> | - size_t needed, namelen; >> | - char *buf, *ptr, *end; >> | - struct if_msghdr *ifm; >> | - struct ifa_msghdr *ifam; >> | + size_t namelen; >> | struct sockaddr_dl *dl; >> | - struct sockaddr *sa[RTAX_MAX]; >> | + struct ifaddrs *ifap, *ifa; >> | struct iface *iface; >> | struct iface_addr *addr; >> | >> | - mib[0] = CTL_NET; >> | - mib[1] = PF_ROUTE; >> | - mib[2] = 0; >> | - mib[3] = 0; >> | - mib[4] = NET_RT_IFLIST; >> | - mib[5] = 0; >> | - >> | - maxtries = 20; >> | - err = 0; >> | - do { >> | - if (maxtries-- == 0 || (err && err != ENOMEM)) { >> | - fprintf(stderr, "iface_Create: sysctl: %s\n", strerror(err)); >> | - return NULL; >> | - } >> | - >> | - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { >> | - fprintf(stderr, "iface_Create: sysctl: estimate: %s\n", >> | - strerror(errno)); >> | - return NULL; >> | - } >> | - >> | - if ((buf = (char *)malloc(needed)) == NULL) { >> | - fprintf(stderr, "iface_Create: malloc failed: %s\n", >> strerror(errno)); >> | - return NULL; >> | - } >> | - >> | - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { >> | - err = errno; >> | - free(buf); >> | - buf = NULL; >> | - } >> | - } while (buf == NULL); >> | + if (getifaddrs(&ifap) != 0) { >> | + fprintf(stderr, "iface_Create: getifaddrs: %s\n", strerror(errno)); >> | + return NULL; >> | + } >> | >> | - ptr = buf; >> | - end = buf + needed; >> | iface = NULL; >> | namelen = strlen(name); >> | >> | - while (ptr < end && iface == NULL) { >> | - ifm = (struct if_msghdr *)ptr; /* On if_msghdr >> */ >> | - if (ifm->ifm_version != RTM_VERSION) >> | + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { >> | + if (strcmp(name, ifa->ifa_name)) >> | continue; >> | - if (ifm->ifm_type != RTM_IFINFO) >> | - break; >> | - dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */ >> | - if (dl->sdl_nlen == namelen && !strncmp(name, dl->sdl_data, namelen)) >> { >> | + if (ifa->ifa_addr->sa_family == AF_LINK) { >> | + dl = (struct sockaddr_dl *)ifa->ifa_addr; >> | iface = (struct iface *)malloc(sizeof *iface); >> | if (iface == NULL) { >> | fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno)); >> | + freeifaddrs(ifap); >> | return NULL; >> | } >> | iface->name = strdup(name); >> | - iface->index = ifm->ifm_index; >> | - iface->flags = ifm->ifm_flags; >> | + iface->index = if_nametoindex(name); >> | + iface->flags = ifa->ifa_flags; >> | iface->mtu = 0; >> | iface->addrs = 0; >> | iface->addr = NULL; >> | } >> | - ptr += ifm->ifm_msglen; /* First >> ifa_msghdr */ >> | - for (; ptr < end; ptr += ifam->ifam_msglen) { >> | - ifam = (struct ifa_msghdr *)ptr; /* Next if >> address */ >> | - >> | - if (ifam->ifam_type != RTM_NEWADDR) /* finished this if */ >> | - break; >> | - if (ifm->ifm_version != RTM_VERSION) >> | - continue; >> | - >> | - if (iface != NULL && ifam->ifam_addrs & RTA_IFA) { >> | - /* Found a configured interface ! */ >> | - iface_ParseHdr(ifam, sa); >> | >> | - if (sa[RTAX_IFA] && (sa[RTAX_IFA]->sa_family == AF_INET >> | + if (ifa->ifa_addr->sa_family == AF_INET >> | #ifndef NOINET6 >> | - || sa[RTAX_IFA]->sa_family == AF_INET6 >> | + || ifa->ifa_addr->sa_family == AF_INET6 >> | #endif >> | - )) { >> | - /* Record the address */ >> | + ) { >> | + /* Record the address */ >> | >> | - addr = (struct iface_addr *) >> | - realloc(iface->addr, (iface->addrs + 1) * sizeof >> iface->addr[0]); >> | - if (addr == NULL) >> | - break; >> | - iface->addr = addr; >> | - >> | - addr += iface->addrs; >> | - iface->addrs++; >> | - >> | - ncprange_setsa(&addr->ifa, sa[RTAX_IFA], sa[RTAX_NETMASK]); >> | - if (sa[RTAX_BRD]) >> | - ncpaddr_setsa(&addr->peer, sa[RTAX_BRD]); >> | - else >> | - ncpaddr_init(&addr->peer); >> | - } >> | - } >> | + addr = (struct iface_addr *) >> | + realloc(iface->addr, (iface->addrs + 1) * sizeof iface->addr[0]); >> | + if (addr == NULL) >> | + break; >> | + iface->addr = addr; >> | + >> | + addr += iface->addrs; >> | + iface->addrs++; >> | + >> | + ncprange_setsa(&addr->ifa, ifa->ifa_addr, ifa->ifa_netmask); >> | + if (ifa->ifa_broadaddr) >> | + ncpaddr_setsa(&addr->peer, ifa->ifa_broadaddr); >> | + else >> | + ncpaddr_init(&addr->peer); >> | } >> | } >> | >> | - free(buf); >> | + freeifaddrs(ifap); >> | >> | return iface; >> | } >> | @@ -700,20 +651,4 @@ iface_Show(struct cmdargs const *arg) >> | } >> | >> | return 0; >> | -} >> | - >> | -void >> | -iface_ParseHdr(struct ifa_msghdr *ifam, struct sockaddr *sa[RTAX_MAX]) >> | -{ >> | - char *wp; >> | - int rtax; >> | - >> | - wp = (char *)(ifam + 1); >> | - >> | - for (rtax = 0; rtax < RTAX_MAX; rtax++) >> | - if (ifam->ifam_addrs & (1 << rtax)) { >> | - sa[rtax] = (struct sockaddr *)wp; >> | - wp += ROUNDUP(sa[rtax]->sa_len); >> | - } else >> | - sa[rtax] = NULL; >> | } >> | Index: ppp/iface.h >> | =================================================================== >> | RCS file: /cvs/src/usr.sbin/ppp/ppp/iface.h,v >> | retrieving revision 1.8 >> | diff -u -p -r1.8 iface.h >> | --- ppp/iface.h 19 Aug 2001 23:22:17 -0000 1.8 >> | +++ ppp/iface.h 30 Jun 2009 14:51:03 -0000 >> | @@ -62,4 +62,3 @@ extern int iface_Show(struct cmdargs con >> | extern int iface_SetFlags(const char *, int); >> | extern int iface_ClearFlags(const char *, int); >> | extern void iface_Destroy(struct iface *); >> | -extern void iface_ParseHdr(struct ifa_msghdr *, struct sockaddr >> *[RTAX_MAX]); >> | Index: ppp/route.c >> | =================================================================== >> | RCS file: /cvs/src/usr.sbin/ppp/ppp/route.c,v >> | retrieving revision 1.37 >> | diff -u -p -r1.37 route.c >> | --- ppp/route.c 25 Jun 2009 15:59:28 -0000 1.37 >> | +++ ppp/route.c 30 Jun 2009 14:03:36 -0000 >> | @@ -204,113 +204,15 @@ static int route_nifs = -1; >> | const char * >> | Index2Nam(int idx) >> | { >> | - /* >> | - * XXX: Maybe we should select() on the routing socket so that we can >> | - * notice interfaces that come & go (PCCARD support). >> | - * Or we could even support a signal that resets these so that >> | - * the PCCARD insert/remove events can signal ppp. >> | - */ >> | - static char **ifs; /* Figure these out once */ >> | - static int debug_done; /* Debug once */ >> | + static char ifname[IF_NAMESIZE]; >> | + char *ifn; >> | >> | - if (idx > route_nifs || (idx > 0 && ifs[idx-1] == NULL)) { >> | - int mib[6], have, had; >> | - size_t needed; >> | - char *buf, *ptr, *end; >> | - struct sockaddr_dl *dl; >> | - struct if_msghdr *ifm; >> | + ifn = if_indextoname(idx, ifname); >> | >> | - if (ifs) { >> | - free(ifs); >> | - ifs = NULL; >> | - route_nifs = 0; >> | - } >> | - debug_done = 0; >> | - >> | - mib[0] = CTL_NET; >> | - mib[1] = PF_ROUTE; >> | - mib[2] = 0; >> | - mib[3] = 0; >> | - mib[4] = NET_RT_IFLIST; >> | - mib[5] = 0; >> | - >> | - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { >> | - log_Printf(LogERROR, "Index2Nam: sysctl: estimate: %s\n", >> | - strerror(errno)); >> | - return NumStr(idx, NULL, 0); >> | - } >> | - if ((buf = malloc(needed)) == NULL) >> | - return NumStr(idx, NULL, 0); >> | - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { >> | - free(buf); >> | - return NumStr(idx, NULL, 0); >> | - } >> | - end = buf + needed; >> | - >> | - have = 0; >> | - for (ptr = buf; ptr < end; ptr += ifm->ifm_msglen) { >> | - ifm = (struct if_msghdr *)ptr; >> | - if (ifm->ifm_version != RTM_VERSION) >> | - continue; >> | - if (ifm->ifm_type != RTM_IFINFO) >> | - continue; >> | - dl = (struct sockaddr_dl *)(ifm + 1); >> | - if (ifm->ifm_index > 0) { >> | - if (ifm->ifm_index > have) { >> | - char **newifs; >> | - >> | - had = have; >> | - have = ifm->ifm_index + 5; >> | - if (had) >> | - newifs = (char **)realloc(ifs, sizeof(char *) * have); >> | - else >> | - newifs = (char **)calloc(sizeof(char *), have); >> | - if (!newifs) { >> | - log_Printf(LogDEBUG, "Index2Nam: %s\n", strerror(errno)); >> | - route_nifs = 0; >> | - if (ifs) { >> | - free(ifs); >> | - ifs = NULL; >> | - } >> | - free(buf); >> | - return NumStr(idx, NULL, 0); >> | - } >> | - ifs = newifs; >> | - memset(ifs + had, '\0', sizeof(char *) * (have - had)); >> | - } >> | - if (ifs[ifm->ifm_index-1] == NULL) { >> | - ifs[ifm->ifm_index-1] = (char *)malloc(dl->sdl_nlen+1); >> | - if (ifs[ifm->ifm_index-1] == NULL) >> | - log_Printf(LogDEBUG, "Skipping interface %d: Out of memory\n", >> | - ifm->ifm_index); >> | - else { >> | - memcpy(ifs[ifm->ifm_index-1], dl->sdl_data, dl->sdl_nlen); >> | - ifs[ifm->ifm_index-1][dl->sdl_nlen] = '\0'; >> | - if (route_nifs < ifm->ifm_index) >> | - route_nifs = ifm->ifm_index; >> | - } >> | - } >> | - } else if (log_IsKept(LogDEBUG)) >> | - log_Printf(LogDEBUG, "Skipping out-of-range interface %d!\n", >> | - ifm->ifm_index); >> | - } >> | - free(buf); >> | - } >> | - >> | - if (log_IsKept(LogDEBUG) && !debug_done) { >> | - int f; >> | - >> | - log_Printf(LogDEBUG, "Found the following interfaces:\n"); >> | - for (f = 0; f < route_nifs; f++) >> | - if (ifs[f] != NULL) >> | - log_Printf(LogDEBUG, " Index %d, name \"%s\"\n", f+1, ifs[f]); >> | - debug_done = 1; >> | - } >> | - >> | - if (idx < 1 || idx > route_nifs || ifs[idx-1] == NULL) >> | + if (idx < 1 || ifn == NULL) >> | return NumStr(idx, NULL, 0); >> | >> | - return ifs[idx-1]; >> | + return ifn; >> | } >> | >> | void >> >> -- >> Todd Fries .. t...@fries.net >> >> _____________________________________________ >> | \ 1.636.410.0632 (voice) >> | Free Daemon Consulting, LLC \ 1.405.227.9094 (voice) >> | http://FreeDaemonConsulting.com \ 1.866.792.3418 (FAX) >> | "..in support of free software solutions." \ 250797 (FWD) >> | \ >> \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ >> >> 37E7 D3EB 74D0 8D66 A68D B866 0326 204E 3F42 004A >> http://todd.fries.net/pgp.txt