I have a look at this. The ppp code is a total nightmare.
On Sun, Jun 28, 2009 at 02:17:13PM +0200, Oliver Klima wrote:
> Hi,
>
> after the latest change in ppp(8)/iface.c ppp(8) will loop endlessly if
> there's an interface with ifm_version != RTM_VERSION. The pointer to the
> if_msghdr structure doesn't point to the next element when continue is
> executed.
>
> In addition the inner loop checks the ifm_version a second time,
> although that loop iterates over ifa_msghdr structures. That doesn't
> make sense to me.
>
> I attached a patch that solved the problem for me (amd64/GENERIC.MP).
>
> Regards,
>
> Oliver Klima
> --- usr.sbin/ppp/ppp/iface.c.orig Sat Jun 27 20:41:25 2009
> +++ usr.sbin/ppp/ppp/iface.c Sun Jun 28 13:46:54 2009
> @@ -140,23 +140,23 @@
>
> while (ptr < end && iface == NULL) {
> ifm = (struct if_msghdr *)ptr; /* On if_msghdr */
> - if (ifm->ifm_version != RTM_VERSION)
> - 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)) {
> - iface = (struct iface *)malloc(sizeof *iface);
> - if (iface == NULL) {
> - fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno));
> - return NULL;
> - }
> - iface->name = strdup(name);
> - iface->index = ifm->ifm_index;
> - iface->flags = ifm->ifm_flags;
> - iface->mtu = 0;
> - iface->addrs = 0;
> - iface->addr = NULL;
> + if (ifm->ifm_version == RTM_VERSION) {
> + 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)) {
> + iface = (struct iface *)malloc(sizeof *iface);
> + if (iface == NULL) {
> + fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno));
> + return NULL;
> + }
> + iface->name = strdup(name);
> + iface->index = ifm->ifm_index;
> + iface->flags = ifm->ifm_flags;
> + iface->mtu = 0;
> + iface->addrs = 0;
> + iface->addr = NULL;
> + }
> }
> ptr += ifm->ifm_msglen; /* First ifa_msghdr */
> for (; ptr < end; ptr += ifam->ifam_msglen) {
> @@ -164,7 +164,7 @@
>
> if (ifam->ifam_type != RTM_NEWADDR) /* finished this if */
> break;
> - if (ifm->ifm_version != RTM_VERSION)
> + if (ifam->ifam_version != RTM_VERSION)
> continue;
>
> if (iface != NULL && ifam->ifam_addrs & RTA_IFA) {
>
--
:wq Claudio