-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/util/sock/ch3u_getinterfaces.c
-: 0:Graph:ch3u_getinterfaces.gcno
-: 0:Data:ch3u_getinterfaces.gcda
-: 0:Runs:4382
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2006 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:/* We need to include the conf file first so that we can use
-: 8: the _SVID_SOURCE if needed before any file includes features.h
-: 9: on GNU systems */
-: 10:#include "mpidi_ch3_conf.h"
-: 11:
-: 12:
-: 13:#ifdef USE_NOPOSIX_FOR_IFCONF
-: 14:/* This is a very special case. Allow the use of some extensions for
-: 15: just the rest of this file so that we can get the ifconf structure */
-: 16:#undef _POSIX_C_SOURCE
-: 17:#endif
-: 18:
-: 19:#ifdef USE_SVIDSOURCE_FOR_IFCONF
-: 20:/* This is a very special case. Allow the use of some extensions for just
-: 21: the rest of this file so that we can get the ifconf structure */
-: 22:#define _SVID_SOURCE
-: 23:#endif
-: 24:
-: 25:#include "mpidi_ch3_impl.h"
-: 26:
-: 27:#include <stdlib.h>
-: 28:
-: 29:#ifdef HAVE_NETDB_H
-: 30: #include <netdb.h>
-: 31:#endif
-: 32:
-: 33:/* We set dbg_ifname to 1 to help debug the choice of interface name
-: 34: used when determining which interface to advertise to other processes.
-: 35: The value is -1 if it has not yet been set.
-: 36: */
-: 37:static int dbg_ifname = -1;
-: 38:
-: 39:static int MPIDI_CH3U_GetIPInterface( MPIDU_Sock_ifaddr_t *, int * );
-: 40:
-: 41:/*
-: 42: * Get a description of the network interface to use for socket communication
-: 43: *
-: 44: * Here are the steps. This order of checks is used to provide the
-: 45: * user control over the choice of interface and to avoid, where possible,
-: 46: * the use of non-scalable services, such as centeralized name servers.
-: 47: *
-: 48: * MPICH_INTERFACE_HOSTNAME
-: 49: * MPICH_INTERFACE_HOSTNAME_R%d
-: 50: * a single (non-localhost) available IP address, if possible
-: 51: * gethostbyname(gethostname())
-: 52: *
-: 53: * We return the following items:
-: 54: *
-: 55: * ifname - name of the interface. This may or may not be the same
-: 56: * as the name returned by gethostname (in Unix)
-: 57: * ifaddr - This structure includes the interface IP address (as bytes),
-: 58: * and the type (e.g., AF_INET or AF_INET6). Only
-: 59: * ipv4 (AF_INET) is used so far.
-: 60: */
-: 61:
-: 62:#undef FUNCNAME
-: 63:#define FUNCNAME MPIDU_CH3U_GetSockInterfaceAddr
-: 64:#undef FCNAME
-: 65:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 66:int MPIDU_CH3U_GetSockInterfaceAddr( int myRank, char *ifname, int maxIfname,
-: 67: MPIDU_Sock_ifaddr_t *ifaddr )
4754: 68:{
-: 69: char *ifname_string;
4754: 70: int mpi_errno = MPI_SUCCESS;
4754: 71: int ifaddrFound = 0;
-: 72:
4754: 73: if (dbg_ifname < 0) {
-: 74: int rc;
4382: 75: rc = MPIU_GetEnvBool( "MPICH_DBG_IFNAME", &dbg_ifname );
4382: 76: if (rc != 1) dbg_ifname = 0;
-: 77: }
-: 78:
-: 79: /* Set "not found" for ifaddr */
4754: 80: ifaddr->len = 0;
-: 81:
-: 82: /* Check for the name supplied through an environment variable */
4754: 83: ifname_string = getenv("MPICH_INTERFACE_HOSTNAME");
-: 84:
4754: 85: if (!ifname_string) {
-: 86: /* See if there is a per-process name for the interfaces (e.g.,
-: 87: the process manager only delievers the same values for the
-: 88: environment to each process */
-: 89: char namebuf[1024];
|
#####: 90: MPIU_Snprintf( namebuf, sizeof(namebuf),
-: 91: "MPICH_INTERFACE_HOSTNAME_R%d", myRank );
#####: 92: ifname_string = getenv( namebuf );
#####: 93: if (dbg_ifname && ifname_string) {
#####: 94: fprintf( stdout, "Found interface name %s from %s\n",
-: 95: ifname_string, namebuf );
#####: 96: fflush( stdout );
-: 97: }
-: 98: }
|
4754: 99: else if (dbg_ifname) {
|
#####: 100: fprintf( stdout,
-: 101: "Found interface name %s from MPICH_INTERFACE_HOSTNAME\n",
-: 102: ifname_string );
#####: 103: fflush( stdout );
-: 104: }
-: 105:
|
4754: 106: if (!ifname_string) {
-: 107: int len;
-: 108:
-: 109: /* If we have nothing, then use the host name */
|
#####: 110: mpi_errno = MPID_Get_processor_name(ifname, maxIfname, &len );
|
#####: 111: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
|
#####: 112: ifname_string = ifname;
-: 113:
-: 114: /* If we didn't find a specific name, then try to get an IP address
-: 115: directly from the available interfaces, if that is supported on
-: 116: this platform. Otherwise, we'll drop into the next step that uses
-: 117: the ifname */
#####: 118: mpi_errno = MPIDI_CH3U_GetIPInterface( ifaddr, &ifaddrFound );
|
#####: 119: if (mpi_errno) MPIU_ERR_POP(mpi_errno);
-: 120: }
-: 121: else {
-: 122: /* Copy this name into the output name */
|
4754: 123: MPIU_Strncpy( ifname, ifname_string, maxIfname );
-: 124: }
-: 125:
-: 126: /* If we don't have an IP address, try to get it from the name */
4754: 127: if (!ifaddrFound) {
-: 128: struct hostent *info;
-: 129: /* printf( "Name to check is %s\n", ifname_string ); fflush(stdout); */
4754: 130: info = gethostbyname( ifname_string );
4754: 131: if (info && info->h_addr_list) {
-: 132: /* Use the primary address */
4754: 133: ifaddr->len = info->h_length;
4754: 134: ifaddr->type = info->h_addrtype;
4754: 135: if (ifaddr->len > sizeof(ifaddr->ifaddr)) {
-: 136: /* If the address won't fit in the field, reset to
-: 137: no address */
|
#####: 138: ifaddr->len = 0;
#####: 139: ifaddr->type = -1;
-: 140: }
-: 141: else {
|
4754: 142: MPIU_Memcpy( ifaddr->ifaddr, info->h_addr_list[0], ifaddr->len );
-: 143:#if 0
-: 144: printf( "ifaddr len = %d\n", ifaddr->len );
-: 145: {int i;
-: 146: unsigned char *p = info->h_addr_list[0];
-: 147: for (i=0; i<ifaddr->len; i++) {
-: 148: printf( "%.2x", *p++ );
-: 149: }
-: 150: printf( "\n" ); fflush(stdout);
-: 151: p = info->h_addr_list[0];
-: 152: for (i=0; i<ifaddr->len; i++) {
-: 153: printf( "%.3d", *p++ );
-: 154: }
-: 155: printf( "\n" ); fflush(stdout);
-: 156: }
-: 157:#endif
-: 158: }
-: 159: }
-: 160: }
-: 161:
4754: 162:fn_exit:
4754: 163: return mpi_errno;
|
-: 164:fn_fail:
-: 165: goto fn_exit;
-: 166:}
-: 167:
-: 168:
-: 169:/* These includes are here because they're used just for getting the interface
-: 170: * names
-: 171: */
-: 172:
-: 173:
-: 174:#include <sys/types.h>
-: 175:
-: 176:#ifdef HAVE_SYS_SOCKET_H
-: 177:#include <sys/socket.h>
-: 178:#endif
-: 179:#ifdef HAVE_NET_IF_H
-: 180:#include <net/if.h>
-: 181:#endif
-: 182:#ifdef HAVE_SYS_SOCKIO_H
-: 183:/* Needed for SIOCGIFCONF */
-: 184:#include <sys/sockio.h>
-: 185:#endif
-: 186:
-: 187:#if defined(SIOCGIFCONF) && defined(HAVE_STRUCT_IFCONF)
-: 188:#include <netinet/in.h>
-: 189:#include <arpa/inet.h>
-: 190:#include <sys/ioctl.h>
-: 191:#include <errno.h>
-: 192:
-: 193:/* We can only access the interfaces if we have a number of features.
-: 194: Test for these, otherwise define this routine to return false in the
-: 195: "found" variable */
-: 196:
-: 197:#define NUM_IFREQS 10
-: 198:
-: 199:static int MPIDI_CH3U_GetIPInterface( MPIDU_Sock_ifaddr_t *ifaddr, int *found )
-: 200:{
-: 201: char *buf_ptr, *ptr;
-: 202: int buf_len, buf_len_prev;
-: 203: int fd;
-: 204: MPIDU_Sock_ifaddr_t myifaddr;
-: 205: int nfound = 0, foundLocalhost = 0;
-: 206: /* We predefine the LSB and MSB localhost addresses */
-: 207: unsigned int localhost = 0x0100007f;
-: 208:#ifdef WORDS_BIGENDIAN
-: 209: unsigned int MSBlocalhost = 0x7f000001;
-: 210:#endif
-: 211:
-: 212: if (dbg_ifname < 0) {
-: 213: int rc;
-: 214: rc = MPIU_GetEnvBool( "MPICH_DBG_IFNAME", &dbg_ifname );
-: 215: if (rc != 1) dbg_ifname = 0;
-: 216: }
-: 217:
-: 218: fd = socket(AF_INET, SOCK_DGRAM, 0);
-: 219: if (fd < 0) {
-: 220: fprintf( stderr, "Unable to open an AF_INET socket\n" );
-: 221: return 1;
-: 222: }
-: 223:
-: 224: /* Use MSB localhost if necessary */
-: 225:#ifdef WORDS_BIGENDIAN
-: 226: localhost = MSBlocalhost;
-: 227:#endif
-: 228:
-: 229:
-: 230: /*
-: 231: * Obtain the interface information from the operating system
-: 232: *
-: 233: * Note: much of this code is borrowed from W. Richard Stevens' book
-: 234: * entitled "UNIX Network Programming", Volume 1, Second Edition. See
-: 235: * section 16.6 for details.
-: 236: */
-: 237: buf_len = NUM_IFREQS * sizeof(struct ifreq);
-: 238: buf_len_prev = 0;
-: 239:
-: 240: for(;;)
-: 241: {
-: 242: struct ifconf ifconf;
-: 243: int rc;
-: 244:
-: 245: buf_ptr = (char *) MPIU_Malloc(buf_len);
-: 246: if (buf_ptr == NULL) {
-: 247: fprintf( stderr, "Unable to allocate %d bytes\n", buf_len );
-: 248: return 1;
-: 249: }
-: 250:
-: 251: ifconf.ifc_buf = buf_ptr;
-: 252: ifconf.ifc_len = buf_len;
-: 253:
-: 254: rc = ioctl(fd, SIOCGIFCONF, &ifconf);
-: 255: if (rc < 0) {
-: 256: if (errno != EINVAL || buf_len_prev != 0) {
-: 257: fprintf( stderr, "Error from ioctl = %d\n", errno );
-: 258: perror(" Error is: ");
-: 259: return 1;
-: 260: }
-: 261: }
-: 262: else {
-: 263: if (ifconf.ifc_len == buf_len_prev) {
-: 264: buf_len = ifconf.ifc_len;
-: 265: break;
-: 266: }
-: 267:
-: 268: buf_len_prev = ifconf.ifc_len;
-: 269: }
-: 270:
-: 271: MPIU_Free(buf_ptr);
-: 272: buf_len += NUM_IFREQS * sizeof(struct ifreq);
-: 273: }
-: 274:
-: 275: /*
-: 276: * Now that we've got the interface information, we need to run through
-: 277: * the interfaces and check out the ip addresses. If we find a
-: 278: * unique, non-lcoal host (127.0.0.1) address, return that, otherwise
-: 279: * return nothing.
-: 280: */
-: 281: ptr = buf_ptr;
-: 282:
-: 283: while(ptr < buf_ptr + buf_len) {
-: 284: struct ifreq * ifreq;
-: 285:
-: 286: ifreq = (struct ifreq *) ptr;
-: 287:
-: 288: if (dbg_ifname) {
-: 289: fprintf( stdout, "%10s\t", ifreq->ifr_name ); fflush(stdout);
-: 290: }
-: 291:
-: 292: if (ifreq->ifr_addr.sa_family == AF_INET) {
-: 293: struct in_addr addr;
-: 294:
-: 295: addr = ((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr;
-: 296: if (dbg_ifname) {
-: 297: fprintf( stdout, "IPv4 address = %08x (%s)\n", addr.s_addr,
-: 298: inet_ntoa( addr ) );
-: 299: }
-: 300:
-: 301: if (addr.s_addr == localhost && dbg_ifname) {
-: 302: fprintf( stdout, "Found local host\n" );
-: 303: }
-: 304: /* Save localhost if we find it. Let any new interface
-: 305: overwrite localhost. However, if we find more than
-: 306: one non-localhost interface, then we'll choose none for the
-: 307: interfaces */
-: 308: if (addr.s_addr == localhost) {
-: 309: foundLocalhost = 1;
-: 310: if (nfound == 0) {
-: 311: myifaddr.type = AF_INET;
-: 312: myifaddr.len = 4;
-: 313: MPIU_Memcpy( myifaddr.ifaddr, &addr.s_addr, 4 );
-: 314: }
-: 315: }
-: 316: else {
-: 317: nfound++;
-: 318: myifaddr.type = AF_INET;
-: 319: myifaddr.len = 4;
-: 320: MPIU_Memcpy( myifaddr.ifaddr, &addr.s_addr, 4 );
-: 321: }
-: 322: }
-: 323: else {
-: 324: if (dbg_ifname) {
-: 325: fprintf( stdout, "\n" );
-: 326: }
-: 327: }
-: 328:
-: 329: /*
-: 330: * Increment pointer to the next ifreq; some adjustment may be
-: 331: * required if the address is an IPv6 address
-: 332: */
-: 333: /* This is needed for MAX OSX */
-: 334:#ifdef _SIZEOF_ADDR_IFREQ
-: 335: ptr += _SIZEOF_ADDR_IFREQ(*ifreq);
-: 336:#else
-: 337: ptr += sizeof(struct ifreq);
-: 338:
-: 339:# if defined(AF_INET6)
-: 340: {
-: 341: if (ifreq->ifr_addr.sa_family == AF_INET6)
-: 342: {
-: 343: ptr += sizeof(struct sockaddr_in6) - sizeof(struct sockaddr);
-: 344: }
-: 345: }
-: 346:# endif
-: 347:#endif
-: 348: }
-: 349:
-: 350: MPIU_Free(buf_ptr);
-: 351: close(fd);
-: 352:
-: 353: /* If we found a unique address, use that */
-: 354: if (nfound == 1 || (nfound == 0 && foundLocalhost == 1)) {
-: 355: *ifaddr = myifaddr;
-: 356: *found = 1;
-: 357: }
-: 358: else {
-: 359: *found = 0;
-: 360: }
-: 361:
-: 362: return 0;
-: 363:}
-: 364:
-: 365:#else /* things needed to find the interfaces */
-: 366:
-: 367:/* In this case, just return false for interfaces found */
-: 368:static int MPIDI_CH3U_GetIPInterface( MPIDU_Sock_ifaddr_t *ifaddr, int *found )
|
#####: 369:{
#####: 370: *found = 0;
#####: 371: return 0;
-: 372:}
-: 373:#endif
|