Пример #1
0
int
libcfs_ipif_enumerate (char ***namesp)
{
        /* Allocate and fill in 'names', returning # interfaces/error */
        char           **names;
        int             toobig;
        int             nalloc;
        int             nfound;
        struct socket  *so;
        struct ifreq   *ifr;
        struct ifconf   ifc;
        int             rc;
        int             nob;
        int             i;
        CFS_DECL_FUNNEL_DATA;

        CFS_NET_IN;
        rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
        CFS_NET_EX;
        if (rc != 0) {
                CERROR ("Can't create socket: %d\n", rc);
                return (-rc);
        }

        nalloc = 16;    /* first guess at max interfaces */
        toobig = 0;
        for (;;) {
                if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
                        toobig = 1;
                        nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
                        CWARN("Too many interfaces: only enumerating first %d\n",
                              nalloc);
                }

                LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
                if (ifr == NULL) {
                        CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
                                rc = -ENOMEM;
                        goto out0;
                }
                                
                ifc.ifc_buf = (char *)ifr;
                ifc.ifc_len = nalloc * sizeof(*ifr);
                                        
                CFS_NET_IN;
                rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc());
                CFS_NET_EX;
                                
                if (rc < 0) {
                        CERROR ("Error %d enumerating interfaces\n", rc);
                        goto out1;
                }

                nfound = ifc.ifc_len/sizeof(*ifr);
                LASSERT (nfound <= nalloc);

                if (nfound < nalloc || toobig)
                        break;

                LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
                nalloc *= 2;
        }
        if (nfound == 0)
                goto out1;

        LIBCFS_ALLOC(names, nfound * sizeof(*names));
        if (names == NULL) {
                rc = -ENOMEM;
                goto out1;
        }
        /* NULL out all names[i] */
        memset (names, 0, nfound * sizeof(*names));

        for (i = 0; i < nfound; i++) {

                nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
                if (nob == IFNAMSIZ) {
                        /* no space for terminating NULL */
                        CERROR("interface name %.*s too long (%d max)\n",
                               nob, ifr[i].ifr_name, IFNAMSIZ);
                        rc = -ENAMETOOLONG;
                        goto out2;
                }

                LIBCFS_ALLOC(names[i], IFNAMSIZ);
                if (names[i] == NULL) {
                        rc = -ENOMEM;
                        goto out2;
                }

                memcpy(names[i], ifr[i].ifr_name, nob);
                names[i][nob] = 0;
        }

        *namesp = names;
        rc = nfound;

out2:
        if (rc < 0)
                libcfs_ipif_free_enumeration(names, nfound);
out1:
        LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
out0:
        CFS_NET_IN;
        soclose(so);
        CFS_NET_EX;
        return rc;
}
Пример #2
0
int
libcfs_ipif_enumerate (char ***namesp)
{
        /* Allocate and fill in 'names', returning # interfaces/error */
        char          **names;
        int             nalloc;
        int             nfound;
        struct ifreq   *ifr;
        struct ifconf   ifc;
        int             rc;
        int             nob;
        int             i;


        nalloc = 16;        /* first guess at max interfaces */
        for (;;) {
                LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
                if (ifr == NULL) {
                        CERROR ("ENOMEM enumerating up to %d interfaces\n",
                                nalloc);
                        rc = -ENOMEM;
                        goto out0;
                }

                ifc.ifc_buf = (char *)ifr;
                ifc.ifc_len = nalloc * sizeof(*ifr);

                rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);

                if (rc < 0) {
                        CERROR ("Error %d enumerating interfaces\n", rc);
                        goto out1;
                }

                LASSERT (rc == 0);

                nfound = ifc.ifc_len/sizeof(*ifr);
                LASSERT (nfound <= nalloc);

                if (nfound < nalloc)
                        break;

                LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
                nalloc *= 2;
        }

        if (nfound == 0)
                goto out1;

        LIBCFS_ALLOC(names, nfound * sizeof(*names));
        if (names == NULL) {
                rc = -ENOMEM;
                goto out1;
        }
        /* NULL out all names[i] */
        memset (names, 0, nfound * sizeof(*names));

        for (i = 0; i < nfound; i++) {

                nob = strlen (ifr[i].ifr_name);
                if (nob >= IFNAMSIZ) {
                        /* no space for terminating NULL */
                        CERROR("interface name %.*s too long (%d max)\n",
                               nob, ifr[i].ifr_name, IFNAMSIZ);
                        rc = -ENAMETOOLONG;
                        goto out2;
                }

                LIBCFS_ALLOC(names[i], IFNAMSIZ);
                if (names[i] == NULL) {
                        rc = -ENOMEM;
                        goto out2;
                }

                memcpy(names[i], ifr[i].ifr_name, nob);
                names[i][nob] = 0;
        }

        *namesp = names;
        rc = nfound;

 out2:
        if (rc < 0)
                libcfs_ipif_free_enumeration(names, nfound);
 out1:
        LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
 out0:
        return rc;
}
Пример #3
0
int
libcfs_ipif_enumerate (char ***namesp)
{
        /* Allocate and fill in 'names', returning # interfaces/error */
        char           **names;
        int             toobig;
        int             nalloc;
        int             nfound;
        socket_t        so;
        struct ifreq   *ifr;
        struct ifconf   ifc;
        int             rc;
        int             nob;
        int             i;

        rc = -sock_socket(PF_INET, SOCK_STREAM, 0, 
                          NULL, NULL, &so);
        if (rc != 0) {
                CERROR ("Can't create socket: %d\n", rc);
                return (rc);
        }

        nalloc = 16;    /* first guess at max interfaces */
        toobig = 0;
        for (;;) {
                if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
                        toobig = 1;
                        nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
                        CWARN("Too many interfaces: only enumerating first %d\n",
                              nalloc);
                }

                LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
                if (ifr == NULL) {
                        CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
                                rc = -ENOMEM;
                        goto out0;
                }
                                
                ifc.ifc_buf = (char *)ifr;
                ifc.ifc_len = nalloc * sizeof(*ifr);
                                        
#if 1
                /*
                 * XXX Liang:
                 * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in
                 * kernel space because it always try to copy result to userspace. 
                 * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...).
                 * I've created a bug for Apple, let's wait...
                 */
                nfound = 0;
                for (i = 0; i < 16; i++) {
                        struct ifreq    en;
                        bzero(&en, sizeof(en));
                        snprintf(en.ifr_name, IFNAMSIZ, "en%d", i);
                        rc = -sock_ioctl (so, SIOCGIFFLAGS, &en);
                        if (rc != 0)
                                continue;
                        strcpy(ifr[nfound++].ifr_name, en.ifr_name);
                }

#else           /* NOT in using now */
                rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc);
                                
                if (rc < 0) {
                        CERROR ("Error %d enumerating interfaces\n", rc);
                        goto out1;
                }

                nfound = ifc.ifc_len/sizeof(*ifr);
                LASSERT (nfound <= nalloc);
#endif

                if (nfound < nalloc || toobig)
                        break;

                LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
                nalloc *= 2;
        }
        if (nfound == 0)
                goto out1;

        LIBCFS_ALLOC(names, nfound * sizeof(*names));
        if (names == NULL) {
                rc = -ENOMEM;
                goto out1;
        }
        /* NULL out all names[i] */
        memset (names, 0, nfound * sizeof(*names));

        for (i = 0; i < nfound; i++) {

                nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
                if (nob == IFNAMSIZ) {
                        /* no space for terminating NULL */
                        CERROR("interface name %.*s too long (%d max)\n",
                               nob, ifr[i].ifr_name, IFNAMSIZ);
                        rc = -ENAMETOOLONG;
                        goto out2;
                }

                LIBCFS_ALLOC(names[i], IFNAMSIZ);
                if (names[i] == NULL) {
                        rc = -ENOMEM;
                        goto out2;
                }

                memcpy(names[i], ifr[i].ifr_name, nob);
                names[i][nob] = 0;
        }

        *namesp = names;
        rc = nfound;

out2:
        if (rc < 0)
                libcfs_ipif_free_enumeration(names, nfound);
out1:
        LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
out0:
        sock_close(so);
        return rc;

}