root/opal/mca/pmix/pmix4x/pmix/src/util/pif.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmix_ifnametoaddr
  2. pmix_ifnametoindex
  3. pmix_ifnametokindex
  4. pmix_ifindextokindex
  5. pmix_ifaddrtoname
  6. pmix_ifaddrtokindex
  7. pmix_ifcount
  8. pmix_ifbegin
  9. pmix_ifnext
  10. pmix_ifindextoaddr
  11. pmix_ifkindextoaddr
  12. pmix_ifindextomask
  13. pmix_ifindextomac
  14. pmix_ifindextomtu
  15. pmix_ifindextoflags
  16. pmix_ifindextoname
  17. pmix_ifkindextoname
  18. pmix_ifislocal
  19. parse_ipv4_dots
  20. pmix_iftupletoaddr
  21. pmix_ifisloopback
  22. pmix_ifmatches
  23. pmix_ifgetaliases
  24. pmix_ifnametoaddr
  25. pmix_ifaddrtoname
  26. pmix_ifnametoindex
  27. pmix_ifnametokindex
  28. pmix_ifindextokindex
  29. pmix_ifcount
  30. pmix_ifbegin
  31. pmix_ifnext
  32. pmix_ifindextoname
  33. pmix_ifkindextoname
  34. pmix_ifindextoaddr
  35. pmix_ifindextomask
  36. pmix_ifislocal
  37. pmix_iftupletoaddr
  38. pmix_ifmatches
  39. pmix_ifgetaliases

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2009 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2008      Sun Microsystems, Inc.  All rights reserved.
  14  * Copyright (c) 2010-2015 Cisco Systems, Inc.  All rights reserved.
  15  * Copyright (c) 2014      Los Alamos National Security, LLC. All rights
  16  *                         reserved.
  17  * Copyright (c) 2015-2016 Research Organization for Information Science
  18  *                         and Technology (RIST). All rights reserved.
  19  * Copyright (c) 2016-2018 Intel, Inc.  All rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 
  27 #include "pmix_config.h"
  28 #include "pmix_common.h"
  29 
  30 #include <string.h>
  31 #ifdef HAVE_UNISTD_H
  32 #include <unistd.h>
  33 #endif
  34 #include <errno.h>
  35 #ifdef HAVE_SYS_TYPES_H
  36 #include <sys/types.h>
  37 #endif
  38 #ifdef HAVE_SYS_SOCKET_H
  39 #include <sys/socket.h>
  40 #endif
  41 #ifdef HAVE_SYS_SOCKIO_H
  42 #include <sys/sockio.h>
  43 #endif
  44 #ifdef HAVE_SYS_IOCTL_H
  45 #include <sys/ioctl.h>
  46 #endif
  47 #ifdef HAVE_NETINET_IN_H
  48 #include <netinet/in.h>
  49 #endif
  50 #ifdef HAVE_ARPA_INET_H
  51 #include <arpa/inet.h>
  52 #endif
  53 #ifdef HAVE_NET_IF_H
  54 #include <net/if.h>
  55 #endif
  56 #ifdef HAVE_NETDB_H
  57 #include <netdb.h>
  58 #endif
  59 #ifdef HAVE_IFADDRS_H
  60 #include <ifaddrs.h>
  61 #endif
  62 #include <ctype.h>
  63 
  64 #include "src/class/pmix_list.h"
  65 #include "src/util/error.h"
  66 #include "src/util/pif.h"
  67 #include "src/util/net.h"
  68 #include "src/util/output.h"
  69 #include "src/util/argv.h"
  70 #include "src/util/show_help.h"
  71 
  72 #include "src/mca/pif/base/base.h"
  73 
  74 #ifdef HAVE_STRUCT_SOCKADDR_IN
  75 
  76 #ifndef MIN
  77 #  define MIN(a,b)                ((a) < (b) ? (a) : (b))
  78 #endif
  79 
  80 /*
  81  *  Look for interface by name and returns its address
  82  *  as a dotted decimal formatted string.
  83  */
  84 
  85 int pmix_ifnametoaddr(const char* if_name, struct sockaddr* addr, int length)
  86 {
  87     pmix_pif_t* intf;
  88 
  89     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
  90         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
  91         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
  92         if (strcmp(intf->if_name, if_name) == 0) {
  93             memcpy(addr, &intf->if_addr, length);
  94             return PMIX_SUCCESS;
  95         }
  96     }
  97     return PMIX_ERROR;
  98 }
  99 
 100 
 101 /*
 102  *  Look for interface by name and returns its
 103  *  corresponding pmix_list index.
 104  */
 105 
 106 int pmix_ifnametoindex(const char* if_name)
 107 {
 108     pmix_pif_t* intf;
 109 
 110     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 111         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 112         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 113         if (strcmp(intf->if_name, if_name) == 0) {
 114             return intf->if_index;
 115         }
 116     }
 117     return -1;
 118 }
 119 
 120 
 121 /*
 122  *  Look for interface by name and returns its
 123  *  corresponding kernel index.
 124  */
 125 
 126 int16_t pmix_ifnametokindex(const char* if_name)
 127 {
 128     pmix_pif_t* intf;
 129 
 130     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 131         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 132         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 133         if (strcmp(intf->if_name, if_name) == 0) {
 134             return intf->if_kernel_index;
 135         }
 136     }
 137     return -1;
 138 }
 139 
 140 
 141 /*
 142  *  Look for interface by pmix_list index and returns its
 143  *  corresponding kernel index.
 144  */
 145 
 146 int pmix_ifindextokindex(int if_index)
 147 {
 148     pmix_pif_t* intf;
 149 
 150     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 151         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 152         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 153         if (if_index == intf->if_index) {
 154             return intf->if_kernel_index;
 155         }
 156     }
 157     return -1;
 158 }
 159 
 160 
 161 /*
 162  *  Attempt to resolve the adddress (given as either IPv4/IPv6 string
 163  *  or hostname) and lookup corresponding interface.
 164  */
 165 
 166 int pmix_ifaddrtoname(const char* if_addr, char* if_name, int length)
 167 {
 168     pmix_pif_t* intf;
 169     int error;
 170     struct addrinfo hints, *res = NULL, *r;
 171 
 172     /* if the user asked us not to resolve interfaces, then just return */
 173     if (pmix_if_do_not_resolve) {
 174         /* return not found so ifislocal will declare
 175          * the node to be non-local
 176          */
 177         return PMIX_ERR_NOT_FOUND;
 178     }
 179 
 180     memset(&hints, 0, sizeof(hints));
 181     hints.ai_family = PF_UNSPEC;
 182     hints.ai_socktype = SOCK_STREAM;
 183     error = getaddrinfo(if_addr, NULL, &hints, &res);
 184 
 185     if (error) {
 186         if (NULL != res) {
 187             freeaddrinfo (res);
 188         }
 189         return PMIX_ERR_NOT_FOUND;
 190     }
 191 
 192     for (r = res; r != NULL; r = r->ai_next) {
 193         for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 194             intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 195             intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 196 
 197             if (AF_INET == r->ai_family) {
 198                 struct sockaddr_in ipv4;
 199                 struct sockaddr_in *inaddr;
 200 
 201                 inaddr = (struct sockaddr_in*) &intf->if_addr;
 202                 memcpy (&ipv4, r->ai_addr, r->ai_addrlen);
 203 
 204                 if (inaddr->sin_addr.s_addr == ipv4.sin_addr.s_addr) {
 205                     pmix_strncpy(if_name, intf->if_name, length-1);
 206                     freeaddrinfo (res);
 207                     return PMIX_SUCCESS;
 208                 }
 209             }
 210             else {
 211                 if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*) &intf->if_addr)->sin6_addr,
 212                     &((struct sockaddr_in6*) r->ai_addr)->sin6_addr)) {
 213                     pmix_strncpy(if_name, intf->if_name, length-1);
 214                     freeaddrinfo (res);
 215                     return PMIX_SUCCESS;
 216                 }
 217             }
 218         }
 219     }
 220     if (NULL != res) {
 221         freeaddrinfo (res);
 222     }
 223 
 224     /* if we get here, it wasn't found */
 225     return PMIX_ERR_NOT_FOUND;
 226 }
 227 
 228 /*
 229  *  Attempt to resolve the address (given as either IPv4/IPv6 string
 230  *  or hostname) and return the kernel index of the interface
 231  *  on the same network as the specified address
 232  */
 233 int16_t pmix_ifaddrtokindex(const char* if_addr)
 234 {
 235     pmix_pif_t* intf;
 236     int error;
 237     struct addrinfo hints, *res = NULL, *r;
 238     int if_kernel_index;
 239     size_t len;
 240 
 241     memset(&hints, 0, sizeof(hints));
 242     hints.ai_family = PF_UNSPEC;
 243     hints.ai_socktype = SOCK_STREAM;
 244     error = getaddrinfo(if_addr, NULL, &hints, &res);
 245 
 246     if (error) {
 247         if (NULL != res) {
 248             freeaddrinfo (res);
 249         }
 250         return PMIX_ERR_NOT_FOUND;
 251     }
 252 
 253     for (r = res; r != NULL; r = r->ai_next) {
 254         PMIX_LIST_FOREACH(intf, &pmix_if_list, pmix_pif_t) {
 255             if (AF_INET == r->ai_family && AF_INET == intf->af_family) {
 256                 struct sockaddr_in ipv4, intv4;
 257                 memset(&ipv4, 0, sizeof(struct sockaddr_in));
 258                 len = (r->ai_addrlen < sizeof(struct sockaddr_in)) ? r->ai_addrlen : sizeof(struct sockaddr_in);
 259                 memcpy(&ipv4, r->ai_addr, len);
 260                 memset(&intv4, 0, sizeof(struct sockaddr_in));
 261                 memcpy(&intv4, &intf->if_addr, sizeof(struct sockaddr_in));
 262                 if (pmix_net_samenetwork((struct sockaddr*)&ipv4, (struct sockaddr*)&intv4, intf->if_mask)) {
 263                     if_kernel_index = intf->if_kernel_index;
 264                     freeaddrinfo (res);
 265                     return if_kernel_index;
 266                 }
 267             } else if (AF_INET6 == r->ai_family && AF_INET6 == intf->af_family) {
 268                 struct sockaddr_in6 ipv6, intv6;
 269                 memset(&ipv6, 0, sizeof(struct sockaddr));
 270                 len = (r->ai_addrlen < sizeof(struct sockaddr_in6)) ? r->ai_addrlen : sizeof(struct sockaddr_in6);
 271                 memcpy(&ipv6, r->ai_addr, len);
 272                 memset(&intv6, 0, sizeof(struct sockaddr));
 273                 memcpy(&intv6, &intf->if_addr, sizeof(struct sockaddr_in6));
 274                 if (pmix_net_samenetwork((struct sockaddr*)&intv6,
 275                                          (struct sockaddr*)&ipv6, intf->if_mask)) {
 276                     if_kernel_index = intf->if_kernel_index;
 277                     freeaddrinfo (res);
 278                     return if_kernel_index;
 279                 }
 280             }
 281         }
 282     }
 283     if (NULL != res) {
 284         freeaddrinfo (res);
 285     }
 286     return PMIX_ERR_NOT_FOUND;
 287 }
 288 
 289 /*
 290  *  Return the number of discovered interface.
 291  */
 292 
 293 int pmix_ifcount(void)
 294 {
 295     return pmix_list_get_size(&pmix_if_list);
 296 }
 297 
 298 
 299 /*
 300  *  Return the pmix_list interface index for the first
 301  *  interface in our list.
 302  */
 303 
 304 int pmix_ifbegin(void)
 305 {
 306     pmix_pif_t *intf;
 307 
 308     intf = (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 309     if (NULL != intf)
 310         return intf->if_index;
 311     return (-1);
 312 }
 313 
 314 
 315 /*
 316  *  Located the current position in the list by if_index and
 317  *  return the interface index of the next element in our list
 318  *  (if it exists).
 319  */
 320 
 321 int pmix_ifnext(int if_index)
 322 {
 323     pmix_pif_t *intf;
 324 
 325     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 326         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 327         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 328         if (intf->if_index == if_index) {
 329             do {
 330                 pmix_pif_t* if_next = (pmix_pif_t*)pmix_list_get_next(intf);
 331                 pmix_pif_t* if_end =  (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 332                 if (if_next == if_end) {
 333                     return -1;
 334                 }
 335                 intf = if_next;
 336             } while(intf->if_index == if_index);
 337             return intf->if_index;
 338         }
 339     }
 340     return (-1);
 341 }
 342 
 343 
 344 /*
 345  *  Lookup the interface by pmix_list index and return the
 346  *  primary address assigned to the interface.
 347  */
 348 
 349 int pmix_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
 350 {
 351     pmix_pif_t* intf;
 352 
 353     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 354          intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 355          intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 356         if (intf->if_index == if_index) {
 357             memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
 358             return PMIX_SUCCESS;
 359         }
 360     }
 361     return PMIX_ERROR;
 362 }
 363 
 364 
 365 /*
 366  *  Lookup the interface by pmix_list kindex and return the
 367  *  primary address assigned to the interface.
 368  */
 369 int pmix_ifkindextoaddr(int if_kindex, struct sockaddr* if_addr, unsigned int length)
 370 {
 371     pmix_pif_t* intf;
 372 
 373     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 374          intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 375          intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 376         if (intf->if_kernel_index == if_kindex) {
 377             memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
 378             return PMIX_SUCCESS;
 379         }
 380     }
 381     return PMIX_ERROR;
 382 }
 383 
 384 
 385 /*
 386  *  Lookup the interface by pmix_list index and return the
 387  *  network mask assigned to the interface.
 388  */
 389 
 390 int pmix_ifindextomask(int if_index, uint32_t* if_mask, int length)
 391 {
 392     pmix_pif_t* intf;
 393 
 394     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 395         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 396         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 397         if (intf->if_index == if_index) {
 398             memcpy(if_mask, &intf->if_mask, length);
 399             return PMIX_SUCCESS;
 400         }
 401     }
 402     return PMIX_ERROR;
 403 }
 404 
 405 /*
 406  *  Lookup the interface by pmix_list index and return the
 407  *  MAC assigned to the interface.
 408  */
 409 
 410 int pmix_ifindextomac(int if_index, uint8_t mac[6])
 411 {
 412     pmix_pif_t* intf;
 413 
 414     for (intf = (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 415         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 416         intf = (pmix_pif_t*)pmix_list_get_next(intf)) {
 417         if (intf->if_index == if_index) {
 418             memcpy(mac, &intf->if_mac, 6);
 419             return PMIX_SUCCESS;
 420         }
 421     }
 422     return PMIX_ERROR;
 423 }
 424 
 425 /*
 426  *  Lookup the interface by pmix_list index and return the
 427  *  MTU assigned to the interface.
 428  */
 429 
 430 int pmix_ifindextomtu(int if_index, int *mtu)
 431 {
 432     pmix_pif_t* intf;
 433 
 434     for (intf = (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 435         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 436         intf = (pmix_pif_t*)pmix_list_get_next(intf)) {
 437         if (intf->if_index == if_index) {
 438             *mtu = intf->ifmtu;
 439             return PMIX_SUCCESS;
 440         }
 441     }
 442     return PMIX_ERROR;
 443 }
 444 
 445 /*
 446  *  Lookup the interface by pmix_list index and return the
 447  *  flags assigned to the interface.
 448  */
 449 
 450 int pmix_ifindextoflags(int if_index, uint32_t* if_flags)
 451 {
 452     pmix_pif_t* intf;
 453 
 454     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 455         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 456         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 457         if (intf->if_index == if_index) {
 458             memcpy(if_flags, &intf->if_flags, sizeof(uint32_t));
 459             return PMIX_SUCCESS;
 460         }
 461     }
 462     return PMIX_ERROR;
 463 }
 464 
 465 
 466 
 467 /*
 468  *  Lookup the interface by pmix_list index and return
 469  *  the associated name.
 470  */
 471 
 472 int pmix_ifindextoname(int if_index, char* if_name, int length)
 473 {
 474     pmix_pif_t *intf;
 475 
 476     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 477         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 478         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 479         if (intf->if_index == if_index) {
 480             pmix_strncpy(if_name, intf->if_name, length-1);
 481             return PMIX_SUCCESS;
 482         }
 483     }
 484     return PMIX_ERROR;
 485 }
 486 
 487 
 488 /*
 489  *  Lookup the interface by kernel index and return
 490  *  the associated name.
 491  */
 492 
 493 int pmix_ifkindextoname(int if_kindex, char* if_name, int length)
 494 {
 495     pmix_pif_t *intf;
 496 
 497     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 498         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 499         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 500         if (intf->if_kernel_index == if_kindex) {
 501             pmix_strncpy(if_name, intf->if_name, length-1);
 502             return PMIX_SUCCESS;
 503         }
 504     }
 505     return PMIX_ERROR;
 506 }
 507 
 508 
 509 #define ADDRLEN 100
 510 bool
 511 pmix_ifislocal(const char *hostname)
 512 {
 513     char addrname[NI_MAXHOST]; /* should be larger than ADDRLEN, but I think
 514                                   they really mean IFNAMESIZE */
 515 
 516     if (PMIX_SUCCESS == pmix_ifaddrtoname(hostname, addrname, ADDRLEN)) {
 517         return true;
 518     }
 519 
 520     return false;
 521 }
 522 
 523 static int parse_ipv4_dots(const char *addr, uint32_t* net, int* dots)
 524 {
 525     const char *start = addr, *end;
 526     uint32_t n[]={0,0,0,0};
 527     int i;
 528 
 529     /* now assemble the address */
 530     for( i = 0; i < 4; i++ ) {
 531         n[i] = strtoul(start, (char**)&end, 10);
 532         if( end == start ) {
 533             /* this is not an error, but indicates that
 534              * we were given a partial address - e.g.,
 535              * 192.168 - usually indicating an IP range
 536              * in CIDR notation. So just return what we have
 537              */
 538             break;
 539         }
 540         /* did we read something sensible? */
 541         if( n[i] > 255 ) {
 542             return PMIX_ERR_NETWORK_NOT_PARSEABLE;
 543         }
 544         /* skip all the . */
 545         for( start = end; '\0' != *start; start++ )
 546             if( '.' != *start ) break;
 547     }
 548     *dots = i;
 549     *net = PMIX_PIF_ASSEMBLE_NETWORK(n[0], n[1], n[2], n[3]);
 550     return PMIX_SUCCESS;
 551 }
 552 
 553 int
 554 pmix_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
 555 {
 556     int pval, dots, rc = PMIX_SUCCESS;
 557     const char *ptr;
 558 
 559     /* if a mask was desired... */
 560     if (NULL != mask) {
 561         /* set default */
 562         *mask = 0xFFFFFFFF;
 563 
 564         /* if entry includes mask, split that off */
 565         if (NULL != (ptr = strchr(inaddr, '/'))) {
 566             ptr = ptr + 1;  /* skip the / */
 567             /* is the mask a tuple? */
 568             if (NULL != strchr(ptr, '.')) {
 569                 /* yes - extract mask from it */
 570                 rc = parse_ipv4_dots(ptr, mask, &dots);
 571             } else {
 572                 /* no - must be an int telling us how much of the addr to use: e.g., /16
 573                  * For more information please read http://en.wikipedia.org/wiki/Subnetwork.
 574                  */
 575                 pval = strtol(ptr, NULL, 10);
 576                 if ((pval > 31) || (pval < 1)) {
 577                     pmix_output(0, "pmix_iftupletoaddr: unknown mask");
 578                     return PMIX_ERR_NETWORK_NOT_PARSEABLE;
 579                 }
 580                 *mask = 0xFFFFFFFF << (32 - pval);
 581             }
 582         } else {
 583             /* use the number of dots to determine it */
 584             for (ptr = inaddr, pval = 0; '\0'!= *ptr; ptr++) {
 585                 if ('.' == *ptr) {
 586                     pval++;
 587                 }
 588             }
 589             /* if we have three dots, then we have four
 590              * fields since it is a full address, so the
 591              * default netmask is fine
 592              */
 593             if (3 == pval) {
 594                 *mask = 0xFFFFFFFF;
 595             } else if (2 == pval) {         /* 2 dots */
 596                 *mask = 0xFFFFFF00;
 597             } else if (1 == pval) {  /* 1 dot */
 598                 *mask = 0xFFFF0000;
 599             } else if (0 == pval) {  /* no dots */
 600                 *mask = 0xFF000000;
 601             } else {
 602                 pmix_output(0, "pmix_iftupletoaddr: unknown mask");
 603                 return PMIX_ERR_NETWORK_NOT_PARSEABLE;
 604             }
 605         }
 606     }
 607 
 608     /* if network addr is desired... */
 609     if (NULL != net) {
 610         /* now assemble the address */
 611         rc = parse_ipv4_dots(inaddr, net, &dots);
 612     }
 613 
 614     return rc;
 615 }
 616 
 617 /*
 618  *  Determine if the specified interface is loopback
 619  */
 620 
 621 bool pmix_ifisloopback(int if_index)
 622 {
 623     pmix_pif_t* intf;
 624 
 625     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 626         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 627         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 628         if (intf->if_index == if_index) {
 629             if ((intf->if_flags & IFF_LOOPBACK) != 0) {
 630                 return true;
 631             }
 632         }
 633     }
 634     return false;
 635 }
 636 
 637 /* Determine if an interface matches any entry in the given list, taking
 638  * into account that the list entries could be given as named interfaces,
 639  * IP addrs, or subnet+mask
 640  */
 641 int pmix_ifmatches(int kidx, char **nets)
 642 {
 643     bool named_if;
 644     int i, rc;
 645     size_t j;
 646     int kindex;
 647     struct sockaddr_in inaddr;
 648     uint32_t addr, netaddr, netmask;
 649 
 650     /* get the address info for the given network in case we need it */
 651     if (PMIX_SUCCESS != (rc = pmix_ifkindextoaddr(kidx, (struct sockaddr*)&inaddr, sizeof(inaddr)))) {
 652         return rc;
 653     }
 654     addr = ntohl(inaddr.sin_addr.s_addr);
 655 
 656     for (i=0; NULL != nets[i]; i++) {
 657         /* if the specified interface contains letters in it, then it
 658          * was given as an interface name and not an IP tuple
 659          */
 660         named_if = false;
 661         for (j=0; j < strlen(nets[i]); j++) {
 662             if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
 663                 named_if = true;
 664                 break;
 665             }
 666         }
 667         if (named_if) {
 668             if (0 > (kindex = pmix_ifnametokindex(nets[i]))) {
 669                 continue;
 670             }
 671             if (kindex == kidx) {
 672                 return PMIX_SUCCESS;
 673             }
 674         } else {
 675             if (PMIX_SUCCESS != (rc = pmix_iftupletoaddr(nets[i], &netaddr, &netmask))) {
 676                 pmix_show_help("help-pmix-util.txt", "invalid-net-mask", true, nets[i]);
 677                 return rc;
 678             }
 679             if (netaddr == (addr & netmask)) {
 680                 return PMIX_SUCCESS;
 681             }
 682         }
 683     }
 684     /* get here if not found */
 685     return PMIX_ERR_NOT_FOUND;
 686 }
 687 
 688 void pmix_ifgetaliases(char ***aliases)
 689 {
 690     pmix_pif_t* intf;
 691     char ipv4[INET_ADDRSTRLEN];
 692     struct sockaddr_in *addr;
 693     char ipv6[INET6_ADDRSTRLEN];
 694     struct sockaddr_in6 *addr6;
 695 
 696     /* set default answer */
 697     *aliases = NULL;
 698 
 699     for (intf =  (pmix_pif_t*)pmix_list_get_first(&pmix_if_list);
 700         intf != (pmix_pif_t*)pmix_list_get_end(&pmix_if_list);
 701         intf =  (pmix_pif_t*)pmix_list_get_next(intf)) {
 702         addr = (struct sockaddr_in*) &intf->if_addr;
 703         /* ignore purely loopback interfaces */
 704         if ((intf->if_flags & IFF_LOOPBACK) != 0) {
 705             continue;
 706         }
 707         if (addr->sin_family == AF_INET) {
 708             inet_ntop(AF_INET, &(addr->sin_addr.s_addr), ipv4, INET_ADDRSTRLEN);
 709             pmix_argv_append_nosize(aliases, ipv4);
 710         } else {
 711             addr6 = (struct sockaddr_in6*) &intf->if_addr;
 712             inet_ntop(AF_INET6, &(addr6->sin6_addr), ipv6, INET6_ADDRSTRLEN);
 713             pmix_argv_append_nosize(aliases, ipv6);
 714         }
 715     }
 716 }
 717 
 718 #else /* HAVE_STRUCT_SOCKADDR_IN */
 719 
 720 /* if we don't have struct sockaddr_in, we don't have traditional
 721    ethernet devices.  Just make everything a no-op error call */
 722 
 723 int
 724 pmix_ifnametoaddr(const char* if_name,
 725                   struct sockaddr* if_addr, int size)
 726 {
 727     return PMIX_ERR_NOT_SUPPORTED;
 728 }
 729 
 730 int
 731 pmix_ifaddrtoname(const char* if_addr,
 732                   char* if_name, int size)
 733 {
 734     return PMIX_ERR_NOT_SUPPORTED;
 735 }
 736 
 737 int
 738 pmix_ifnametoindex(const char* if_name)
 739 {
 740     return PMIX_ERR_NOT_SUPPORTED;
 741 }
 742 
 743 int16_t
 744 pmix_ifnametokindex(const char* if_name)
 745 {
 746     return PMIX_ERR_NOT_SUPPORTED;
 747 }
 748 
 749 int
 750 pmix_ifindextokindex(int if_index)
 751 {
 752     return PMIX_ERR_NOT_SUPPORTED;
 753 }
 754 
 755 int
 756 pmix_ifcount(void)
 757 {
 758     return PMIX_ERR_NOT_SUPPORTED;
 759 }
 760 
 761 int
 762 pmix_ifbegin(void)
 763 {
 764     return PMIX_ERR_NOT_SUPPORTED;
 765 }
 766 
 767 int
 768 pmix_ifnext(int if_index)
 769 {
 770     return PMIX_ERR_NOT_SUPPORTED;
 771 }
 772 
 773 int
 774 pmix_ifindextoname(int if_index, char* if_name, int length)
 775 {
 776     return PMIX_ERR_NOT_SUPPORTED;
 777 }
 778 
 779 int
 780 pmix_ifkindextoname(int kif_index, char* if_name, int length)
 781 {
 782     return PMIX_ERR_NOT_SUPPORTED;
 783 }
 784 
 785 int
 786 pmix_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
 787 {
 788     return PMIX_ERR_NOT_SUPPORTED;
 789 }
 790 
 791 int
 792 pmix_ifindextomask(int if_index, uint32_t* if_addr, int length)
 793 {
 794     return PMIX_ERR_NOT_SUPPORTED;
 795 }
 796 
 797 bool
 798 pmix_ifislocal(const char *hostname)
 799 {
 800     return false;
 801 }
 802 
 803 int
 804 pmix_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
 805 {
 806     return 0;
 807 }
 808 
 809 int pmix_ifmatches(int idx, char **nets)
 810 {
 811     return PMIX_ERR_NOT_SUPPORTED;
 812 }
 813 
 814 void pmix_ifgetaliases(char ***aliases)
 815 {
 816     /* set default answer */
 817     *aliases = NULL;
 818 }
 819 
 820 #endif /* HAVE_STRUCT_SOCKADDR_IN */

/* [<][>][^][v][top][bottom][index][help] */