Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ipv6 disabled/linux



Ademar, David,

Thanks for reporting this. We fixed it and it's checked into CVS. Please let us know if you still have problems with IPv6 disabled.

Best Regards,

-Marc


On Nov 8, 2004, at 1:20 PM, David Brower wrote:

Funny, I ran into this last week too, but I thought it was a personal
problem so I didn't bother passing it on.   (Personal in the sense that
maybe I was the only one who turned of ipv6 because of the stupid
Mozilla slow resolver in the face of misconfigured ip6 name service
insanity.)    What I think is the correct fix is below...

From: "Ademar de Souza Reis Jr." <email@hidden>
Subject: Failure with ipv6 disabled on Linux
To: email@hidden
Message-ID: <email@hidden>
Content-Type: text/plain; charset=us-ascii; format=flowed

Hi.

On Linux (Conectiva Linux, kernel 2.6.8), I can't run mDNS* applications
(updated CVS) if I keep ipv6 disabled. I get the following failure:


[ademar@optimus mDNSPosix]$ ./build/prod/mDNSNetMonitor
mDNSNetMonitor: mDNSNetMonitor failed -65537
[ademar@optimus mDNSPosix]$ ./build/prod/mDNSClientPosix
mDNSClientPosix: Finished with status -65537, result 2

Looks like the error resides in the mDNSUNP.c:get_ifi_info() function, which
fails if socket6() returns an error on line 152.


If I remove the check after the socket6() call it works fine, but I'm doing
it blindly, I hope someone with a good understanding of the code can fix
this issue the right way :-)


Just to remember, programs should not fail if ipv6 is disabled, even if the
platform supports it.




Below is what works for me.

struct ifi_info *get_ifi_info(int family, int doaliases)
{
    int                 junk;
    struct ifi_info     *ifi, *ifihead, **ifipnext;
    int                 sockfd, sockf6, len, lastlen, flags, myflags;
#ifdef NOT_HAVE_IF_NAMETOINDEX
    int                 index = 200;
#endif
    char                *ptr, *buf, lastname[IFNAMSIZ], *cptr;
    struct ifconf       ifc;
    struct ifreq        *ifr, ifrcopy;
    struct sockaddr_in  *sinptr;

#if defined(AF_INET6) && HAVE_IPV6
    struct sockaddr_in6 *sinptr6;
    int             useip6 = 1;
#endif

    sockfd = -1;
    sockf6 = -1;
    buf = NULL;
    ifihead = NULL;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        goto gotError;
    }

#if defined(AF_INET6) && HAVE_IPV6
    sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
    if (sockf6 < 0) {

      /* don't just error out.  ip6 might be disabled on the machine
         for other reasons.   Just don't use it.   Maybe complain?  */
      useip6 = 0;
    }
#endif

    lastlen = 0;
    len = 100 * sizeof(struct ifreq);   /* initial buffer size guess */
    for ( ; ; ) {
        buf = (char*)malloc(len);
        if (buf == NULL) {
            goto gotError;
        }
        ifc.ifc_len = len;
        ifc.ifc_buf = buf;
        if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
            if (errno != EINVAL || lastlen != 0) {
                goto gotError;
            }
        } else {
            if (ifc.ifc_len == lastlen)
                break;      /* success, len has not changed */
            lastlen = ifc.ifc_len;
        }
        len += 10 * sizeof(struct ifreq);   /* increment */
        free(buf);
    }
    ifihead = NULL;
    ifipnext = &ifihead;
    lastname[0] = 0;
/* end get_ifi_info1 */

/* include get_ifi_info2 */
    for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
        ifr = (struct ifreq *) ptr;

len = GET_SA_LEN(ifr->ifr_addr);
ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */


//        fprintf(stderr, "intf %d name=%s AF=%d\n", index,
ifr->ifr_name, ifr->ifr_addr.sa_family);

        if (ifr->ifr_addr.sa_family != family)
            continue;   /* ignore if not desired address family */

        myflags = 0;
        if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)
            *cptr = 0;      /* replace colon will null */
        if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
            if (doaliases == 0)
                continue;   /* already processed this interface */
            myflags = IFI_ALIAS;
        }
        memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

        ifrcopy = *ifr;
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
            goto gotError;
        }

        flags = ifrcopy.ifr_flags;
        if ((flags & IFF_UP) == 0)
            continue;   /* ignore if interface not up */

        ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
        if (ifi == NULL) {
            goto gotError;
        }
        *ifipnext = ifi;            /* prev points to this new one */
        ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */

ifi->ifi_flags = flags; /* IFF_xxx values */
ifi->ifi_myflags = myflags; /* IFI_xxx values */
#ifndef NOT_HAVE_IF_NAMETOINDEX
ifi->ifi_index = if_nametoindex(ifr->ifr_name);
#else
ifrcopy = *ifr;
if ( 0 >= ioctl(sockfd, SIOCGIFINDEX, &ifrcopy))
ifi->ifi_index = ifrcopy.ifr_index;
else
ifi->ifi_index = index++; /* SIOCGIFINDEX is broken on
Solaris 2.5ish, so fake it */
#endif
memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
ifi->ifi_name[IFI_NAME-1] = '\0';
/* end get_ifi_info2 */
/* include get_ifi_info3 */
switch (ifr->ifr_addr.sa_family) {
case AF_INET:
sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
if (ifi->ifi_addr == NULL) {
ifi->ifi_addr = (struct sockaddr*)calloc(1,
sizeof(struct sockaddr_in));
if (ifi->ifi_addr == NULL) {
goto gotError;
}
memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));


#ifdef  SIOCGIFNETMASK
                if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) goto
gotError;
                ifi->ifi_netmask = (struct sockaddr*)calloc(1,
sizeof(struct sockaddr_in));
                if (ifi->ifi_netmask == NULL) goto gotError;
                sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
                memcpy(ifi->ifi_netmask, sinptr, sizeof(struct
sockaddr_in));
#endif

#ifdef SIOCGIFBRDADDR
if (flags & IFF_BROADCAST) {
if (ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy) < 0) {
goto gotError;
}
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
ifi->ifi_brdaddr = (struct sockaddr*)calloc(1,
sizeof(struct sockaddr_in));
if (ifi->ifi_brdaddr == NULL) {
goto gotError;
}
memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct
sockaddr_in));
}
#endif


#ifdef SIOCGIFDSTADDR
if (flags & IFF_POINTOPOINT) {
if (ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy) < 0) {
goto gotError;
}
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
ifi->ifi_dstaddr = (struct sockaddr*)calloc(1,
sizeof(struct sockaddr_in));
if (ifi->ifi_dstaddr == NULL) {
goto gotError;
}
memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct
sockaddr_in));
}
#endif useip6 = 0;
}
break;


#if defined(AF_INET6) && HAVE_IPV6
        case AF_INET6:
            sinptr6 = (struct sockaddr_in6 *) &ifr->ifr_addr;
            if (ifi->ifi_addr == NULL) {
                ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
                if (ifi->ifi_addr == NULL) {
                    goto gotError;
                }

/* Some platforms (*BSD) inject the prefix in IPv6LL
addresses */
/* We need to strip that out */
if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
sinptr6->sin6_addr.s6_addr[2] =
sinptr6->sin6_addr.s6_addr[3] = 0;
memcpy(ifi->ifi_addr, sinptr6, sizeof(struct sockaddr_in6));


#ifdef SIOCGIFNETMASK_IN6
if( useip6 )
{
struct in6_ifreq ifr6;
bzero(&ifr6, sizeof(ifr6));
memcpy(&ifr6.ifr_name, &ifr->ifr_name,
sizeof(ifr6.ifr_name ));
memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr,
sizeof(ifr6.ifr_ifru.ifru_addr));
if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) goto
gotError;
ifi->ifi_netmask = (struct sockaddr*)calloc(1,
sizeof(struct sockaddr_in6));
if (ifi->ifi_netmask == NULL) goto gotError;
sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct
sockaddr_in6));
}
#endif
}
break;
#endif


        default:
            break;
        }
    }
    goto done;

gotError:
    if (ifihead != NULL) {
        free_ifi_info(ifihead);
        ifihead = NULL;
    }

done:
    if (buf != NULL) {
        free(buf);
    }
    if (sockfd != -1) {
        junk = close(sockfd);
        assert(junk == 0);
    }
    if (sockf6 != -1) {
        junk = close(sockf6);
        assert(junk == 0);
    }
    return(ifihead);    /* pointer to first structure in linked list */
}
/* end get_ifi_info3 */





-dB




_______________________________________________ Do not post admin requests to the list. They will be ignored. Rendezvous-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/rendezvous-dev/email@hidden

This email sent to email@hidden

_______________________________________________ Do not post admin requests to the list. They will be ignored. Rendezvous-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/rendezvous-dev/email@hidden

This email sent to email@hidden
References: 
 >ipv6 disabled/linux (From: David Brower <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.