int libcfs_ipif_query (char *name, int *up, __u32 *ip) { struct ifreq ifr; int nob; int rc; __u32 val; nob = strlen(name); if (nob >= IFNAMSIZ) { CERROR("Interface name %s too long\n", name); return -EINVAL; } CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ); strcpy(ifr.ifr_name, name); rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get flags for interface %s\n", name); return rc; } if ((ifr.ifr_flags & IFF_UP) == 0) { CDEBUG(D_NET, "Interface %s down\n", name); *up = 0; *ip = 0; return 0; } *up = 1; strcpy(ifr.ifr_name, name); ifr.ifr_addr.sa_family = AF_INET; rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get IP address for interface %s\n", name); return rc; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *ip = ntohl(val); return 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; }
int libcfs_ipif_query (char *name, int *up, __u32 *ip) { struct ifreq ifr; int nob; int rc; __u32 val; #ifdef __FreeBSD__ char *idx; #endif nob = strlen(name); if (nob >= IFNAMSIZ) { CERROR("Interface name %s too long\n", name); return -EINVAL; } #ifdef __FreeBSD__ idx = strchr(name, ':'); if (idx) *idx++ = '\0'; #endif CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ); strcpy(ifr.ifr_name, name); rc = libcfs_sock_ioctl(SIOCGIFFLAGS, &ifr); if (rc != 0) { CERROR("Can't get flags for interface %s: %s\n", name, strerror(errno)); return rc; } if ((ifr.ifr_flags & IFF_UP) == 0) { CDEBUG(D_NET, "Interface %s down\n", name); *up = 0; *ip = 0; return 0; } *up = 1; #ifdef __FreeBSD__ if (idx) { struct ifaddrs *ifa0, *ifa; char *endp; int nidx; nidx = strtol(idx, &endp, 10); if (nidx < 0 || nidx >= INT_MAX || endp == idx || *endp) abort(); rc = -1; errno = EADDRNOTAVAIL; getifaddrs(&ifa0); for (ifa = ifa0; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family == AF_INET && strcmp(ifa->ifa_name, name) == 0 && !nidx--) { rc = 0; memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); break; } } freeifaddrs(ifa); } else { #endif strcpy(ifr.ifr_name, name); ifr.ifr_addr.sa_family = AF_INET; rc = libcfs_sock_ioctl(SIOCGIFADDR, &ifr); #ifdef __FreeBSD__ } #endif if (rc != 0) { CERROR("Can't get IP address for interface %s\n", name); return rc; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *ip = ntohl(val); return 0; }