DAT_RETURN getlocalipaddr(char *addr, int addr_len)
{
struct sockaddr_in *sin;
- struct addrinfo *res, hint, *ai;
- int ret;
- char hostname[256];
+ int ret, skfd, i;
char *netdev = getenv("DAPL_SCM_NETDEV");
+ struct ifreq ifr[10];
+ struct ifconf ifc;
-retry:
/* use provided netdev instead of default hostname */
if (netdev != NULL) {
ret = getipaddr_netdev(netdev, addr, addr_len);
return DAT_SUCCESS;
}
- if (addr_len < sizeof(*sin)) {
+ if (addr_len < sizeof(*sin))
return DAT_INTERNAL_ERROR;
- }
- ret = gethostname(hostname, 256);
+ memset(&ifc,0,sizeof(ifc));
+ ifc.ifc_buf = (char *)ifr;
+ ifc.ifc_len = sizeof(ifr);
+
+ skfd = socket(PF_INET, SOCK_STREAM, 0);
+ ret = ioctl(skfd, SIOCGIFCONF, &ifc);
if (ret)
- return dapl_convert_errno(ret, "gethostname");
-
- memset(&hint, 0, sizeof hint);
- hint.ai_flags = AI_PASSIVE;
- hint.ai_family = AF_INET;
- hint.ai_socktype = SOCK_STREAM;
- hint.ai_protocol = IPPROTO_TCP;
-
- ret = getaddrinfo(hostname, NULL, &hint, &res);
- if (ret) {
- dapl_log(DAPL_DBG_TYPE_ERR,
- " getaddrinfo ERR: %d %s\n", ret, gai_strerror(ret));
- return DAT_INVALID_ADDRESS;
- }
+ goto bail;
- ret = DAT_INVALID_ADDRESS;
- for (ai = res; ai; ai = ai->ai_next) {
- sin = (struct sockaddr_in *)ai->ai_addr;
- if (*((uint32_t *) & sin->sin_addr) != htonl(0x7f000001)) {
- *((struct sockaddr_in *)addr) = *sin;
- ret = DAT_SUCCESS;
+ /* first non-loopback interface in list */
+ for (i=0; i < ifc.ifc_len/sizeof(struct ifreq); i++) {
+ if (strcmp(ifr[i].ifr_name, "lo"))
break;
- }
}
+ memcpy(addr, &ifr[i].ifr_addr, sizeof(struct sockaddr_in));
- freeaddrinfo(res);
-
- /* only loopback found, retry netdev eth0 */
- if (ret == DAT_INVALID_ADDRESS) {
- netdev = "eth0";
- goto retry;
- }
-
- return ret;
+bail:
+ close(skfd);
+ return dapl_convert_errno(ret, "getlocalipaddr");
}
/*