root/opal/mca/if/bsdx_ipv4/if_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$
   5  *
   6  * Additional copyrights may follow
   7  *
   8  * $HEADER$
   9  */
  10 
  11 #include "opal_config.h"
  12 
  13 #include <stdlib.h>
  14 #include <string.h>
  15 
  16 #include "opal/constants.h"
  17 #include "opal/util/output.h"
  18 #include "opal/util/string_copy.h"
  19 #include "opal/mca/if/if.h"
  20 
  21 static int if_bsdx_open(void);
  22 
  23 /* Supports specific flavors of BSD:
  24  * NetBSD
  25  * FreeBSD
  26  * OpenBSD
  27  * DragonFly
  28  */
  29 opal_if_base_component_t mca_if_bsdx_ipv4_component = {
  30     /* First, the mca_component_t struct containing meta information
  31        about the component itself */
  32     {
  33         OPAL_IF_BASE_VERSION_2_0_0,
  34 
  35         /* Component name and version */
  36         "bsdx_ipv4",
  37         OPAL_MAJOR_VERSION,
  38         OPAL_MINOR_VERSION,
  39         OPAL_RELEASE_VERSION,
  40 
  41         /* Component open and close functions */
  42         if_bsdx_open,
  43         NULL
  44     },
  45     {
  46         /* This component is checkpointable */
  47         MCA_BASE_METADATA_PARAM_CHECKPOINT
  48     },
  49 };
  50 
  51 /* convert a netmask (in network byte order) to CIDR notation */
  52 static int prefix (uint32_t netmask)
  53 {
  54     uint32_t mask = ntohl(netmask);
  55     int plen = 0;
  56 
  57     if (0 == mask) {
  58         plen = 32;
  59     } else {
  60         while ((mask % 2) == 0) {
  61             plen += 1;
  62             mask /= 2;
  63         }
  64     }
  65 
  66     return (32 - plen);
  67 }
  68 
  69 /* configure using getifaddrs(3) */
  70 static int if_bsdx_open(void)
  71 {
  72     struct ifaddrs **ifadd_list;
  73     struct ifaddrs *cur_ifaddrs;
  74     struct sockaddr_in* sin_addr;
  75 
  76     /*
  77      * the manpage claims that getifaddrs() allocates the memory,
  78      * and freeifaddrs() is later used to release the allocated memory.
  79      * however, without this malloc the call to getifaddrs() segfaults
  80      */
  81     ifadd_list = (struct ifaddrs **) malloc(sizeof(struct ifaddrs*));
  82 
  83     /* create the linked list of ifaddrs structs */
  84     if (getifaddrs(ifadd_list) < 0) {
  85         opal_output(0, "opal_ifinit: getifaddrs() failed with error=%d\n",
  86                     errno);
  87         return OPAL_ERROR;
  88     }
  89 
  90     for (cur_ifaddrs = *ifadd_list; NULL != cur_ifaddrs;
  91          cur_ifaddrs = cur_ifaddrs->ifa_next) {
  92         opal_if_t *intf;
  93         struct in_addr a4;
  94 
  95         /* skip non- af_inet interface addresses */
  96         if (AF_INET != cur_ifaddrs->ifa_addr->sa_family) {
  97             continue;
  98         }
  99 
 100         /* skip interface if it is down (IFF_UP not set) */
 101         if (0 == (cur_ifaddrs->ifa_flags & IFF_UP)) {
 102             continue;
 103         }
 104 
 105         /* skip interface if it is a loopback device (IFF_LOOPBACK set) */
 106         if (!opal_if_retain_loopback && 0 != (cur_ifaddrs->ifa_flags & IFF_LOOPBACK)) {
 107             continue;
 108         }
 109 
 110         /* or if it is a point-to-point interface */
 111         /* TODO: do we really skip p2p? */
 112         if (0 != (cur_ifaddrs->ifa_flags & IFF_POINTOPOINT)) {
 113             continue;
 114         }
 115 
 116         sin_addr = (struct sockaddr_in *) cur_ifaddrs->ifa_addr;
 117 
 118         intf = OBJ_NEW(opal_if_t);
 119         if (NULL == intf) {
 120             opal_output(0, "opal_ifinit: unable to allocate %d bytes\n",
 121                         (int) sizeof(opal_if_t));
 122             return OPAL_ERR_OUT_OF_RESOURCE;
 123         }
 124         intf->af_family = AF_INET;
 125 
 126         /* fill values into the opal_if_t */
 127         memcpy(&a4, &(sin_addr->sin_addr), sizeof(struct in_addr));
 128 
 129         opal_string_copy(intf->if_name, cur_ifaddrs->ifa_name, IF_NAMESIZE);
 130         intf->if_index = opal_list_get_size(&opal_if_list) + 1;
 131         ((struct sockaddr_in*) &intf->if_addr)->sin_addr = a4;
 132         ((struct sockaddr_in*) &intf->if_addr)->sin_family = AF_INET;
 133         ((struct sockaddr_in*) &intf->if_addr)->sin_len =  cur_ifaddrs->ifa_addr->sa_len;
 134 
 135         intf->if_mask = prefix( sin_addr->sin_addr.s_addr);
 136         intf->if_flags = cur_ifaddrs->ifa_flags;
 137 
 138         intf->if_kernel_index =
 139             (uint16_t) if_nametoindex(cur_ifaddrs->ifa_name);
 140 
 141         opal_list_append(&opal_if_list, &(intf->super));
 142     }   /*  of for loop over ifaddrs list */
 143 
 144     return OPAL_SUCCESS;
 145 }
 146 
 147 

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