root/opal/mca/pmix/pmix4x/pmix/src/mca/pif/bsdx_ipv4/pif_bsdx.c

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

DEFINITIONS

This source file includes following definitions.
  1. prefix
  2. if_bsdx_open

   1 /*
   2  * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
   3  * Copyright (c) 2010      Oracle and/or its affiliates.  All rights reserved.
   4  * Copyright (c) 2018      Intel, Inc.  All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  */
  11 
  12 #include "pmix_config.h"
  13 #include "pmix_common.h"
  14 
  15 #include <string.h>
  16 #ifdef HAVE_UNISTD_H
  17 #include <unistd.h>
  18 #endif
  19 #include <errno.h>
  20 #ifdef HAVE_SYS_TYPES_H
  21 #include <sys/types.h>
  22 #endif
  23 #ifdef HAVE_SYS_SOCKET_H
  24 #include <sys/socket.h>
  25 #endif
  26 #ifdef HAVE_SYS_SOCKIO_H
  27 #include <sys/sockio.h>
  28 #endif
  29 #ifdef HAVE_SYS_IOCTL_H
  30 #include <sys/ioctl.h>
  31 #endif
  32 #ifdef HAVE_NETINET_IN_H
  33 #include <netinet/in.h>
  34 #endif
  35 #ifdef HAVE_ARPA_INET_H
  36 #include <arpa/inet.h>
  37 #endif
  38 #ifdef HAVE_NET_IF_H
  39 #include <net/if.h>
  40 #endif
  41 #ifdef HAVE_NETDB_H
  42 #include <netdb.h>
  43 #endif
  44 #ifdef HAVE_IFADDRS_H
  45 #include <ifaddrs.h>
  46 #endif
  47 
  48 #include "src/util/output.h"
  49 #include "src/util/pif.h"
  50 #include "src/mca/pif/pif.h"
  51 #include "src/mca/pif/base/base.h"
  52 
  53 static int if_bsdx_open(void);
  54 
  55 /* Supports specific flavors of BSD:
  56  * NetBSD
  57  * FreeBSD
  58  * OpenBSD
  59  * DragonFly
  60  */
  61 pmix_pif_base_component_t mca_pif_bsdx_ipv4_component = {
  62     /* First, the mca_component_t struct containing meta information
  63        about the component itself */
  64     .base = {
  65         PMIX_PIF_BASE_VERSION_2_0_0,
  66 
  67         /* Component name and version */
  68         "bsdx_ipv4",
  69         PMIX_MAJOR_VERSION,
  70         PMIX_MINOR_VERSION,
  71         PMIX_RELEASE_VERSION,
  72 
  73         /* Component open and close functions */
  74         if_bsdx_open,
  75         NULL
  76     },
  77     .data = {
  78         /* This component is checkpointable */
  79         PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT
  80     },
  81 };
  82 
  83 /* convert a netmask (in network byte order) to CIDR notation */
  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 /* configure using getifaddrs(3) */
 102 static int if_bsdx_open(void)
 103 {
 104     struct ifaddrs **ifadd_list;
 105     struct ifaddrs *cur_ifaddrs;
 106     struct sockaddr_in* sin_addr;
 107 
 108     /*
 109      * the manpage claims that getifaddrs() allocates the memory,
 110      * and freeifaddrs() is later used to release the allocated memory.
 111      * however, without this malloc the call to getifaddrs() segfaults
 112      */
 113     ifadd_list = (struct ifaddrs **) malloc(sizeof(struct ifaddrs*));
 114 
 115     /* create the linked list of ifaddrs structs */
 116     if (getifaddrs(ifadd_list) < 0) {
 117         pmix_output(0, "pmix_ifinit: getifaddrs() failed with error=%d\n",
 118                     errno);
 119         return PMIX_ERROR;
 120     }
 121 
 122     for (cur_ifaddrs = *ifadd_list; NULL != cur_ifaddrs;
 123          cur_ifaddrs = cur_ifaddrs->ifa_next) {
 124         pmix_pif_t *intf;
 125         struct in_addr a4;
 126 
 127         /* skip non- af_inet interface addresses */
 128         if (AF_INET != cur_ifaddrs->ifa_addr->sa_family) {
 129             continue;
 130         }
 131 
 132         /* skip interface if it is down (IFF_UP not set) */
 133         if (0 == (cur_ifaddrs->ifa_flags & IFF_UP)) {
 134             continue;
 135         }
 136 
 137         /* skip interface if it is a loopback device (IFF_LOOPBACK set) */
 138         if (!pmix_if_retain_loopback && 0 != (cur_ifaddrs->ifa_flags & IFF_LOOPBACK)) {
 139             continue;
 140         }
 141 
 142         /* or if it is a point-to-point interface */
 143         /* TODO: do we really skip p2p? */
 144         if (0 != (cur_ifaddrs->ifa_flags & IFF_POINTOPOINT)) {
 145             continue;
 146         }
 147 
 148         sin_addr = (struct sockaddr_in *) cur_ifaddrs->ifa_addr;
 149 
 150         intf = PMIX_NEW(pmix_pif_t);
 151         if (NULL == intf) {
 152             pmix_output(0, "pmix_ifinit: unable to allocate %d bytes\n",
 153                         (int) sizeof(pmix_pif_t));
 154             return PMIX_ERR_OUT_OF_RESOURCE;
 155         }
 156         intf->af_family = AF_INET;
 157 
 158         /* fill values into the pmix_pif_t */
 159         memcpy(&a4, &(sin_addr->sin_addr), sizeof(struct in_addr));
 160 
 161         pmix_strncpy(intf->if_name, cur_ifaddrs->ifa_name, IF_NAMESIZE-1);
 162         intf->if_index = pmix_list_get_size(&pmix_if_list) + 1;
 163         ((struct sockaddr_in*) &intf->if_addr)->sin_addr = a4;
 164         ((struct sockaddr_in*) &intf->if_addr)->sin_family = AF_INET;
 165         ((struct sockaddr_in*) &intf->if_addr)->sin_len =  cur_ifaddrs->ifa_addr->sa_len;
 166 
 167         intf->if_mask = prefix( sin_addr->sin_addr.s_addr);
 168         intf->if_flags = cur_ifaddrs->ifa_flags;
 169 
 170         intf->if_kernel_index =
 171             (uint16_t) if_nametoindex(cur_ifaddrs->ifa_name);
 172 
 173         pmix_list_append(&pmix_if_list, &(intf->super));
 174     }   /*  of for loop over ifaddrs list */
 175 
 176     return PMIX_SUCCESS;
 177 }

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