This source file includes following definitions.
- prefix
- if_posix_open
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 #include "pmix_config.h"
  16 #include "pmix_common.h"
  17 
  18 #include <string.h>
  19 #ifdef HAVE_UNISTD_H
  20 #include <unistd.h>
  21 #endif
  22 #include <errno.h>
  23 #ifdef HAVE_SYS_TYPES_H
  24 #include <sys/types.h>
  25 #endif
  26 #ifdef HAVE_SYS_SOCKET_H
  27 #include <sys/socket.h>
  28 #endif
  29 #ifdef HAVE_SYS_SOCKIO_H
  30 #include <sys/sockio.h>
  31 #endif
  32 #ifdef HAVE_SYS_IOCTL_H
  33 #include <sys/ioctl.h>
  34 #endif
  35 #ifdef HAVE_NETINET_IN_H
  36 #include <netinet/in.h>
  37 #endif
  38 #ifdef HAVE_ARPA_INET_H
  39 #include <arpa/inet.h>
  40 #endif
  41 #ifdef HAVE_NET_IF_H
  42 #include <net/if.h>
  43 #endif
  44 #ifdef HAVE_NETDB_H
  45 #include <netdb.h>
  46 #endif
  47 #ifdef HAVE_IFADDRS_H
  48 #include <ifaddrs.h>
  49 #endif
  50 
  51 #include "src/util/output.h"
  52 #include "src/util/pif.h"
  53 #include "src/mca/pif/pif.h"
  54 #include "src/mca/pif/base/base.h"
  55 
  56 static int if_posix_open(void);
  57 
  58 
  59 
  60 
  61 pmix_pif_base_component_t mca_pif_posix_ipv4_component = {
  62     
  63 
  64     .base = {
  65         PMIX_PIF_BASE_VERSION_2_0_0,
  66 
  67         
  68         "posix_ipv4",
  69         PMIX_MAJOR_VERSION,
  70         PMIX_MINOR_VERSION,
  71         PMIX_RELEASE_VERSION,
  72 
  73         
  74         if_posix_open,
  75         NULL
  76     },
  77     .data = {
  78         
  79         PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT
  80     },
  81 };
  82 
  83 
  84 static int prefix (uint32_t netmask)
  85 {
  86     uint32_t mask = ntohl(netmask);
  87     int plen = 0;
  88 
  89     if (0 == mask) {
  90         plen = 32;
  91     } else {
  92         while ((mask % 2) == 0) {
  93             plen += 1;
  94             mask /= 2;
  95         }
  96     }
  97 
  98     return (32 - plen);
  99 }
 100 
 101 
 102 static int if_posix_open(void)
 103 {
 104     int sd;
 105     int lastlen, rem;
 106     char *ptr;
 107     struct ifconf ifconf;
 108     int ifc_len;
 109     bool successful_locate = false;
 110 
 111     
 112 
 113 
 114     if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 115         pmix_output(0, "pmix_ifinit: socket() failed with errno=%d\n",
 116                     errno);
 117         return PMIX_ERROR;
 118     }
 119 
 120     
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 
 136 
 137     lastlen = 0;
 138     ifc_len = sizeof(struct ifreq) * DEFAULT_NUMBER_INTERFACES;
 139     do {
 140         ifconf.ifc_len = ifc_len;
 141         ifconf.ifc_req = malloc(ifc_len);
 142         if (NULL == ifconf.ifc_req) {
 143             close(sd);
 144             return PMIX_ERROR;
 145         }
 146 
 147         
 148 
 149 
 150 
 151         memset(ifconf.ifc_req, 0, ifconf.ifc_len);
 152 
 153         if (ioctl(sd, SIOCGIFCONF, &ifconf) < 0) {
 154             
 155 
 156 
 157             if (errno != EINVAL && lastlen != 0) {
 158                 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFCONF) \
 159                             failed with errno=%d",
 160                             errno);
 161                 free(ifconf.ifc_req);
 162                 close(sd);
 163                 return PMIX_ERROR;
 164             }
 165         } else {
 166             
 167 
 168 
 169             if (ifconf.ifc_len == lastlen && ifconf.ifc_len > 0) {
 170                 
 171                 successful_locate = true;
 172                 break;
 173             }
 174             lastlen = ifconf.ifc_len;
 175         }
 176 
 177         
 178 
 179         free(ifconf.ifc_req);
 180         ifc_len = (ifc_len == 0) ? 1 : ifc_len * 2;
 181     } while (ifc_len < MAX_PIFCONF_SIZE);
 182     if (!successful_locate) {
 183         pmix_output(0, "pmix_ifinit: unable to find network interfaces.");
 184         close(sd);
 185         return PMIX_ERROR;
 186     }
 187 
 188     
 189 
 190 
 191     ptr = (char*) ifconf.ifc_req;
 192     rem = ifconf.ifc_len;
 193 
 194     
 195     while (rem > 0) {
 196         struct ifreq* ifr = (struct ifreq*) ptr;
 197         pmix_pif_t *intf;
 198         int length;
 199 
 200         
 201 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 202         length = sizeof(struct sockaddr);
 203 
 204         if (ifr->ifr_addr.sa_len > length) {
 205             length = ifr->ifr_addr.sa_len;
 206         }
 207 
 208         length += sizeof(ifr->ifr_name);
 209 #else
 210         length = sizeof(struct ifreq);
 211 #endif
 212 
 213         rem -= length;
 214         ptr += length;
 215 
 216         
 217         if (AF_INET != ifr->ifr_addr.sa_family) {
 218             continue;
 219         }
 220 
 221         if (ioctl(sd, SIOCGIFFLAGS, ifr) < 0) {
 222             pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFFLAGS) failed with errno=%d", errno);
 223             continue;
 224         }
 225         if ((ifr->ifr_flags & IFF_UP) == 0) {
 226             continue;
 227         }
 228 #ifdef IFF_SLAVE
 229         
 230 
 231         if ((ifr->ifr_flags & IFF_SLAVE) != 0) {
 232             continue;
 233         }
 234 #endif
 235 #if 0
 236         if (!pmix_if_retain_loopback && (ifr->ifr_flags & IFF_LOOPBACK) != 0) {
 237             continue;
 238         }
 239 #endif
 240 
 241         intf = PMIX_NEW(pmix_pif_t);
 242         if (NULL == intf) {
 243             pmix_output(0, "pmix_ifinit: unable to allocated %lu bytes\n", (unsigned long)sizeof(pmix_pif_t));
 244             free(ifconf.ifc_req);
 245             close(sd);
 246             return PMIX_ERR_OUT_OF_RESOURCE;
 247         }
 248         intf->af_family = AF_INET;
 249 
 250         
 251         memset(intf->if_name, 0, sizeof(intf->if_name));
 252         pmix_strncpy(intf->if_name, ifr->ifr_name, sizeof(intf->if_name) - 1);
 253         intf->if_flags = ifr->ifr_flags;
 254 
 255         
 256         intf->if_index = pmix_list_get_size(&pmix_if_list)+1;
 257 
 258         pmix_output_verbose(1, pmix_pif_base_framework.framework_output,
 259                             "found interface %s", intf->if_name);
 260 
 261         
 262 #ifndef SIOCGIFINDEX
 263         intf->if_kernel_index = intf->if_index;
 264 #else
 265         if (ioctl(sd, SIOCGIFINDEX, ifr) < 0) {
 266             pmix_output(0,"pmix_ifinit: ioctl(SIOCGIFINDEX) failed with errno=%d", errno);
 267             PMIX_RELEASE(intf);
 268             continue;
 269         }
 270 #if defined(ifr_ifindex)
 271         intf->if_kernel_index = ifr->ifr_ifindex;
 272 #elif defined(ifr_index)
 273         intf->if_kernel_index = ifr->ifr_index;
 274 #else
 275         intf->if_kernel_index = -1;
 276 #endif
 277 #endif 
 278 
 279         
 280 
 281         if (ioctl(sd, SIOCGIFADDR, ifr) < 0) {
 282             pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFADDR) failed with errno=%d", errno);
 283             PMIX_RELEASE(intf);
 284             break;
 285         }
 286         if (AF_INET != ifr->ifr_addr.sa_family) {
 287             PMIX_RELEASE(intf);
 288             continue;
 289         }
 290 
 291         
 292         memcpy(&intf->if_addr, &ifr->ifr_addr, sizeof(struct sockaddr_in));
 293 
 294         if (ioctl(sd, SIOCGIFNETMASK, ifr) < 0) {
 295             pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFNETMASK) failed with errno=%d", errno);
 296             PMIX_RELEASE(intf);
 297             continue;
 298         }
 299 
 300         
 301         intf->if_mask = prefix(((struct sockaddr_in*) &ifr->ifr_addr)->sin_addr.s_addr);
 302 
 303 #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
 304         
 305         if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0) {
 306             pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFHWADDR) failed with errno=%d", errno);
 307             break;
 308         }
 309         memcpy(intf->if_mac, ifr->ifr_hwaddr.sa_data, 6);
 310 #endif
 311 
 312 #if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)
 313         
 314         if (ioctl(sd, SIOCGIFMTU, ifr) < 0) {
 315             pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFMTU) failed with errno=%d", errno);
 316             break;
 317         }
 318         intf->ifmtu = ifr->ifr_mtu;
 319 #endif
 320         pmix_output_verbose(1, pmix_pif_base_framework.framework_output,
 321                             "adding interface %s", intf->if_name);
 322         pmix_list_append(&pmix_if_list, &(intf->super));
 323     }
 324     free(ifconf.ifc_req);
 325     close(sd);
 326 
 327     return PMIX_SUCCESS;
 328 }