This source file includes following definitions.
- pmix_net_isaddr
- hostname_cleanup
- get_hostname_buffer
- pmix_net_init
- pmix_net_finalize
- pmix_net_prefix2netmask
- pmix_net_islocalhost
- pmix_net_samenetwork
- pmix_net_addr_isipv4public
- pmix_net_get_hostname
- pmix_net_get_port
- pmix_net_init
- pmix_net_finalize
- pmix_net_prefix2netmask
- pmix_net_islocalhost
- pmix_net_samenetwork
- pmix_net_addr_isipv4public
- pmix_net_get_hostname
- pmix_net_get_port
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 #include "pmix_config.h"
  26 #include "pmix_common.h"
  27 
  28 #include <stdio.h>
  29 #include <string.h>
  30 #ifdef HAVE_UNISTD_H
  31 #include <unistd.h>
  32 #endif
  33 #include <errno.h>
  34 #ifdef HAVE_SYS_TYPES_H
  35 #include <sys/types.h>
  36 #endif
  37 #ifdef HAVE_SYS_SOCKET_H
  38 #include <sys/socket.h>
  39 #endif
  40 #ifdef HAVE_SYS_SOCKIO_H
  41 #include <sys/sockio.h>
  42 #endif
  43 #ifdef HAVE_SYS_IOCTL_H
  44 #include <sys/ioctl.h>
  45 #endif
  46 #ifdef HAVE_NETINET_IN_H
  47 #include <netinet/in.h>
  48 #endif
  49 #ifdef HAVE_ARPA_INET_H
  50 #include <arpa/inet.h>
  51 #endif
  52 #ifdef HAVE_NET_IF_H
  53 #include <net/if.h>
  54 #endif
  55 #ifdef HAVE_NETDB_H
  56 #include <netdb.h>
  57 #endif
  58 #ifdef HAVE_IFADDRS_H
  59 #include <ifaddrs.h>
  60 #endif
  61 
  62 #include "src/util/net.h"
  63 #include "src/util/output.h"
  64 #include "src/util/argv.h"
  65 #include "src/util/show_help.h"
  66 #include "src/threads/tsd.h"
  67 #include "src/runtime/pmix_rte.h"
  68 
  69 
  70 bool pmix_net_isaddr(const char *name)
  71 {
  72     struct addrinfo hint, *res = NULL;
  73 
  74     
  75     memset(&hint, '\0', sizeof hint);
  76 
  77     
  78     hint.ai_family = PF_UNSPEC;
  79     hint.ai_flags = AI_NUMERICHOST;
  80 
  81     if (0 != getaddrinfo(name, NULL, &hint, &res)) {
  82         
  83         return false;
  84     }
  85     
  86 
  87 
  88     freeaddrinfo(res);
  89     return true;
  90 }
  91 
  92 #ifdef HAVE_STRUCT_SOCKADDR_IN
  93 
  94 typedef struct private_ipv4_t {
  95     in_addr_t addr;
  96     uint32_t netmask_bits;
  97 } private_ipv4_t;
  98 
  99 static private_ipv4_t* private_ipv4 = NULL;
 100 
 101 static pmix_tsd_key_t hostname_tsd_key;
 102 
 103 
 104 static void
 105 hostname_cleanup(void *value)
 106 {
 107     if (NULL != value) free(value);
 108 }
 109 
 110 
 111 static char*
 112 get_hostname_buffer(void)
 113 {
 114     void *buffer;
 115     int ret;
 116 
 117     ret = pmix_tsd_getspecific(hostname_tsd_key, &buffer);
 118     if (PMIX_SUCCESS != ret) return NULL;
 119 
 120     if (NULL == buffer) {
 121         buffer = (void*) malloc((NI_MAXHOST + 1) * sizeof(char));
 122         ret = pmix_tsd_setspecific(hostname_tsd_key, buffer);
 123     }
 124 
 125     return (char*) buffer;
 126 }
 127 
 128 int
 129 pmix_net_init(void)
 130 {
 131     char **args, *arg;
 132     uint32_t a, b, c, d, bits, addr;
 133     int i, count, found_bad = 0;
 134 
 135     args = pmix_argv_split(pmix_net_private_ipv4, ';');
 136     if( NULL != args ) {
 137         count = pmix_argv_count(args);
 138         private_ipv4 = (private_ipv4_t*)malloc( (count + 1) * sizeof(private_ipv4_t));
 139         if( NULL == private_ipv4 ) {
 140             pmix_output(0, "Unable to allocate memory for the private addresses array" );
 141             pmix_argv_free(args);
 142             goto do_local_init;
 143         }
 144         for( i = 0; i < count; i++ ) {
 145             arg = args[i];
 146 
 147             (void)sscanf( arg, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &bits );
 148 
 149             if( (a > 255) || (b > 255) || (c > 255) ||
 150                 (d > 255) || (bits > 32) ) {
 151                 if (0 == found_bad) {
 152                     pmix_show_help("help-pmix-runtime.txt",
 153                                    "malformed net_private_ipv4",
 154                                    true, args[i]);
 155                     found_bad = 1;
 156                 }
 157                 continue;
 158             }
 159             addr = (a << 24) | (b << 16) | (c << 8) | d;
 160             private_ipv4[i].addr = htonl(addr);
 161             private_ipv4[i].netmask_bits = bits;
 162         }
 163         private_ipv4[i].addr         = 0;
 164         private_ipv4[i].netmask_bits = 0;
 165         pmix_argv_free(args);
 166     }
 167 
 168  do_local_init:
 169     return pmix_tsd_key_create(&hostname_tsd_key, hostname_cleanup);
 170 }
 171 
 172 
 173 int
 174 pmix_net_finalize()
 175 {
 176     free(private_ipv4);
 177     private_ipv4 = NULL;
 178 
 179     return PMIX_SUCCESS;
 180 }
 181 
 182 
 183 
 184 uint32_t
 185 pmix_net_prefix2netmask(uint32_t prefixlen)
 186 {
 187     return htonl (((1 << prefixlen) - 1) << (32 - prefixlen));
 188 }
 189 
 190 
 191 bool
 192 pmix_net_islocalhost(const struct sockaddr *addr)
 193 {
 194     switch (addr->sa_family) {
 195     case AF_INET:
 196         {
 197             const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr;
 198             
 199 
 200             if (0x7F000000 == (0x7F000000 & ntohl(inaddr->sin_addr.s_addr))) {
 201                 return true;
 202             }
 203             return false;
 204         }
 205         break;
 206 
 207     case AF_INET6:
 208         {
 209             const struct sockaddr_in6 *inaddr = (struct sockaddr_in6*) addr;
 210             if (IN6_IS_ADDR_LOOPBACK (&inaddr->sin6_addr)) {
 211                return true; 
 212             }
 213             return false;
 214         }
 215         break;
 216 
 217     default:
 218         pmix_output(0, "unhandled sa_family %d passed to pmix_net_islocalhost",
 219                     addr->sa_family);
 220         return false;
 221         break;
 222     }
 223 }
 224 
 225 
 226 bool
 227 pmix_net_samenetwork(const struct sockaddr *addr1,
 228                      const struct sockaddr *addr2,
 229                      uint32_t plen)
 230 {
 231     uint32_t prefixlen;
 232 
 233     if(addr1->sa_family != addr2->sa_family) {
 234         return false; 
 235     }
 236 
 237     switch (addr1->sa_family) {
 238     case AF_INET:
 239         {
 240             if (0 == plen) {
 241                 prefixlen = 32;
 242             } else {
 243                 prefixlen = plen;
 244             }
 245             struct sockaddr_in inaddr1, inaddr2;
 246             
 247 
 248             memcpy(&inaddr1, addr1, sizeof(inaddr1));
 249             memcpy(&inaddr2, addr2, sizeof(inaddr2));
 250             uint32_t netmask = pmix_net_prefix2netmask (prefixlen);
 251 
 252             if((inaddr1.sin_addr.s_addr & netmask) ==
 253                (inaddr2.sin_addr.s_addr & netmask)) {
 254                 return true;
 255             }
 256             return false;
 257         }
 258         break;
 259 
 260     case AF_INET6:
 261         {
 262             struct sockaddr_in6 inaddr1, inaddr2;
 263             
 264 
 265             memcpy(&inaddr1, addr1, sizeof(inaddr1));
 266             memcpy(&inaddr2, addr2, sizeof(inaddr2));
 267             struct in6_addr *a6_1 = (struct in6_addr*) &inaddr1.sin6_addr;
 268             struct in6_addr *a6_2 = (struct in6_addr*) &inaddr2.sin6_addr;
 269 
 270             if (0 == plen) {
 271                 prefixlen = 64;
 272             } else {
 273                 prefixlen = plen;
 274             }
 275             if (64 == prefixlen) {
 276                 
 277 
 278 
 279 
 280 
 281                 if (((const uint32_t *) (a6_1))[0] ==
 282                     ((const uint32_t *) (a6_2))[0] &&
 283                     ((const uint32_t *) (a6_1))[1] ==
 284                     ((const uint32_t *) (a6_2))[1]) {
 285                     return true;
 286                 }
 287             }
 288             return false;
 289         }
 290         break;
 291 
 292     default:
 293         pmix_output(0, "unhandled sa_family %d passed to pmix_samenetwork",
 294                     addr1->sa_family);
 295     }
 296 
 297     return false;
 298 }
 299 
 300 
 301 
 302 
 303 
 304 bool
 305 pmix_net_addr_isipv4public(const struct sockaddr *addr)
 306 {
 307     switch (addr->sa_family) {
 308         case AF_INET6:
 309             return false;
 310 
 311         case AF_INET:
 312             {
 313                 const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr;
 314                 int i;
 315 
 316                 if( NULL == private_ipv4 ) {
 317                     return true;
 318                 }
 319 
 320                 for( i = 0; private_ipv4[i].addr != 0; i++ ) {
 321                     if( private_ipv4[i].addr == (inaddr->sin_addr.s_addr &
 322                                                  pmix_net_prefix2netmask(private_ipv4[i].netmask_bits)) )
 323                         return false;
 324                 }
 325 
 326             }
 327             return true;
 328         default:
 329             pmix_output (0,
 330                          "unhandled sa_family %d passed to pmix_net_addr_isipv4public\n",
 331                          addr->sa_family);
 332     }
 333 
 334     return false;
 335 }
 336 
 337 
 338 char*
 339 pmix_net_get_hostname(const struct sockaddr *addr)
 340 {
 341     char *name = get_hostname_buffer();
 342     int error;
 343     socklen_t addrlen;
 344     char *p;
 345 
 346     if (NULL == name) {
 347         pmix_output(0, "pmix_sockaddr2str: malloc() failed\n");
 348         return NULL;
 349     }
 350     memset(name, 0, sizeof(*name));
 351 
 352     switch (addr->sa_family) {
 353     case AF_INET:
 354         addrlen = sizeof (struct sockaddr_in);
 355         break;
 356     case AF_INET6:
 357 #if defined( __NetBSD__)
 358         
 359 
 360         if(NULL == inet_ntop(AF_INET6, &((struct sockaddr_in6*) addr)->sin6_addr,
 361                              name, NI_MAXHOST)) {
 362             pmix_output(0, "pmix_sockaddr2str failed with error code %d", errno);
 363             free(name);
 364             return NULL;
 365         }
 366         return name;
 367 #else
 368         addrlen = sizeof (struct sockaddr_in6);
 369 #endif
 370         break;
 371     default:
 372         free(name);
 373         return NULL;
 374     }
 375 
 376     error = getnameinfo(addr, addrlen,
 377                         name, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
 378 
 379     if (error) {
 380        int err = errno;
 381        pmix_output (0, "pmix_sockaddr2str failed:%s (return code %i)\n",
 382                     gai_strerror(err), error);
 383        free (name);
 384        return NULL;
 385     }
 386     
 387     if (NULL != (p = strrchr(name, '%'))) {
 388         *p = '\0';
 389     }
 390     return name;
 391 }
 392 
 393 
 394 int
 395 pmix_net_get_port(const struct sockaddr *addr)
 396 {
 397     switch (addr->sa_family) {
 398     case AF_INET:
 399         return ntohs(((struct sockaddr_in*) addr)->sin_port);
 400         break;
 401 
 402     case AF_INET6:
 403         return ntohs(((struct sockaddr_in6*) addr)->sin6_port);
 404         break;
 405     }
 406 
 407     return -1;
 408 }
 409 
 410 
 411 #else 
 412 
 413 int
 414 pmix_net_init()
 415 {
 416     return PMIX_SUCCESS;
 417 }
 418 
 419 
 420 int
 421 pmix_net_finalize()
 422 {
 423     return PMIX_SUCCESS;
 424 }
 425 
 426 
 427 uint32_t
 428 pmix_net_prefix2netmask(uint32_t prefixlen)
 429 {
 430     return 0;
 431 }
 432 
 433 
 434 bool
 435 pmix_net_islocalhost(const struct sockaddr *addr)
 436 {
 437     return false;
 438 }
 439 
 440 
 441 bool
 442 pmix_net_samenetwork(const struct sockaddr *addr1,
 443                      const struct sockaddr *addr2,
 444                      uint32_t prefixlen)
 445 {
 446     return false;
 447 }
 448 
 449 
 450 bool
 451 pmix_net_addr_isipv4public(const struct sockaddr *addr)
 452 {
 453     return false;
 454 }
 455 
 456 
 457 char*
 458 pmix_net_get_hostname(const struct sockaddr *addr)
 459 {
 460     return NULL;
 461 }
 462 
 463 
 464 int
 465 pmix_net_get_port(const struct sockaddr *addr)
 466 {
 467     return -1;
 468 }
 469 
 470 #endif