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