1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4  *                         University Research and Technology
5  *                         Corporation.  All rights reserved.
6  * Copyright (c) 2004-2005 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2004-2009 High Performance Computing Center Stuttgart,
10  *                         University of Stuttgart.  All rights reserved.
11  * Copyright (c) 2004-2005 The Regents of the University of California.
12  *                         All rights reserved.
13  * Copyright (c) 2008      Sun Microsystems, Inc.  All rights reserved.
14  * Copyright (c) 2010-2015 Cisco Systems, Inc.  All rights reserved.
15  * Copyright (c) 2014-2017 Los Alamos National Security, LLC. All rights
16  *                         reserved.
17  * Copyright (c) 2015-2016 Research Organization for Information Science
18  *                         and Technology (RIST). All rights reserved.
19  * $COPYRIGHT$
20  *
21  * Additional copyrights may follow
22  *
23  * $HEADER$
24  */
25 
26 #include "opal_config.h"
27 
28 #include <string.h>
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #include <errno.h>
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
38 #endif
39 #ifdef HAVE_SYS_SOCKIO_H
40 #include <sys/sockio.h>
41 #endif
42 #ifdef HAVE_SYS_IOCTL_H
43 #include <sys/ioctl.h>
44 #endif
45 #ifdef HAVE_NETINET_IN_H
46 #include <netinet/in.h>
47 #endif
48 #ifdef HAVE_ARPA_INET_H
49 #include <arpa/inet.h>
50 #endif
51 #ifdef HAVE_NET_IF_H
52 #if defined(__APPLE__) && defined(_LP64)
53 /* Apple engineering suggested using options align=power as a
54    workaround for a bug in OS X 10.4 (Tiger) that prevented ioctl(...,
55    SIOCGIFCONF, ...) from working properly in 64 bit mode on Power PC.
56    It turns out that the underlying issue is the size of struct
57    ifconf, which the kernel expects to be 12 and natural 64 bit
58    alignment would make 16.  The same bug appears in 64 bit mode on
59    Intel macs, but align=power is a no-op there, so instead, use the
60    pack pragma to instruct the compiler to pack on 4 byte words, which
61    has the same effect as align=power for our needs and works on both
62    Intel and Power PC Macs. */
63 #pragma pack(push,4)
64 #endif
65 #include <net/if.h>
66 #if defined(__APPLE__) && defined(_LP64)
67 #pragma pack(pop)
68 #endif
69 #endif
70 #ifdef HAVE_NETDB_H
71 #include <netdb.h>
72 #endif
73 #ifdef HAVE_IFADDRS_H
74 #include <ifaddrs.h>
75 #endif
76 #include <ctype.h>
77 
78 #include "opal/class/opal_list.h"
79 #include "opal/util/if.h"
80 #include "opal/util/net.h"
81 #include "opal/util/output.h"
82 #include "opal/util/argv.h"
83 #include "opal/util/show_help.h"
84 #include "opal/constants.h"
85 
86 #include "opal/mca/if/base/base.h"
87 
88 #ifdef HAVE_STRUCT_SOCKADDR_IN
89 
90 #ifndef MIN
91 #  define MIN(a,b)                ((a) < (b) ? (a) : (b))
92 #endif
93 
94 /*
95  *  Look for interface by name and returns its address
96  *  as a dotted decimal formatted string.
97  */
98 
opal_ifnametoaddr(const char * if_name,struct sockaddr * addr,int length)99 int opal_ifnametoaddr(const char* if_name, struct sockaddr* addr, int length)
100 {
101     opal_if_t* intf;
102 
103     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
104         if (strcmp(intf->if_name, if_name) == 0) {
105             memcpy(addr, &intf->if_addr, length);
106             return OPAL_SUCCESS;
107         }
108     }
109     return OPAL_ERROR;
110 }
111 
112 
113 /*
114  *  Look for interface by name and returns its
115  *  corresponding opal_list index.
116  */
117 
opal_ifnametoindex(const char * if_name)118 int opal_ifnametoindex(const char* if_name)
119 {
120     opal_if_t* intf;
121 
122     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
123         if (strcmp(intf->if_name, if_name) == 0) {
124             return intf->if_index;
125         }
126     }
127     return -1;
128 }
129 
130 
131 /*
132  *  Look for interface by name and returns its
133  *  corresponding kernel index.
134  */
135 
opal_ifnametokindex(const char * if_name)136 int opal_ifnametokindex(const char* if_name)
137 {
138     opal_if_t* intf;
139 
140     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
141         if (strcmp(intf->if_name, if_name) == 0) {
142             return intf->if_kernel_index;
143         }
144     }
145     return -1;
146 }
147 
148 
149 /*
150  *  Look for interface by opal_list index and returns its
151  *  corresponding kernel index.
152  */
153 
opal_ifindextokindex(int if_index)154 int opal_ifindextokindex(int if_index)
155 {
156     opal_if_t* intf;
157 
158     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
159         if (if_index == intf->if_index) {
160             return intf->if_kernel_index;
161         }
162     }
163     return -1;
164 }
165 
166 
167 /*
168  *  Attempt to resolve the adddress (given as either IPv4/IPv6 string
169  *  or hostname) and lookup corresponding interface.
170  */
171 
opal_ifaddrtoname(const char * if_addr,char * if_name,int length)172 int opal_ifaddrtoname(const char* if_addr, char* if_name, int length)
173 {
174     opal_if_t* intf;
175     int error;
176     struct addrinfo hints, *res = NULL, *r;
177 
178     /* if the user asked us not to resolve interfaces, then just return */
179     if (opal_if_do_not_resolve) {
180         /* return not found so ifislocal will declare
181          * the node to be non-local
182          */
183         return OPAL_ERR_NOT_FOUND;
184     }
185 
186     memset(&hints, 0, sizeof(hints));
187     hints.ai_family = PF_UNSPEC;
188     hints.ai_socktype = SOCK_STREAM;
189     error = getaddrinfo(if_addr, NULL, &hints, &res);
190 
191     if (error) {
192         if (NULL != res) {
193             freeaddrinfo (res);
194         }
195         return OPAL_ERR_NOT_FOUND;
196     }
197 
198     for (r = res; r != NULL; r = r->ai_next) {
199         OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
200             if (AF_INET == r->ai_family) {
201                 struct sockaddr_in ipv4;
202                 struct sockaddr_in *inaddr;
203 
204                 inaddr = (struct sockaddr_in*) &intf->if_addr;
205                 memcpy (&ipv4, r->ai_addr, r->ai_addrlen);
206 
207                 if (inaddr->sin_addr.s_addr == ipv4.sin_addr.s_addr) {
208                     strncpy(if_name, intf->if_name, length);
209                     freeaddrinfo (res);
210                     return OPAL_SUCCESS;
211                 }
212             }
213 #if OPAL_ENABLE_IPV6
214             else {
215                 if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*) &intf->if_addr)->sin6_addr,
216                     &((struct sockaddr_in6*) r->ai_addr)->sin6_addr)) {
217                     strncpy(if_name, intf->if_name, length);
218                     freeaddrinfo (res);
219                     return OPAL_SUCCESS;
220                 }
221             }
222 #endif
223         }
224     }
225     if (NULL != res) {
226         freeaddrinfo (res);
227     }
228 
229     /* if we get here, it wasn't found */
230     return OPAL_ERR_NOT_FOUND;
231 }
232 
233 /*
234  *  Attempt to resolve the address (given as either IPv4/IPv6 string
235  *  or hostname) and return the kernel index of the interface
236  *  on the same network as the specified address
237  */
opal_ifaddrtokindex(const char * if_addr)238 int opal_ifaddrtokindex(const char* if_addr)
239 {
240     opal_if_t* intf;
241     int error;
242     struct addrinfo hints, *res = NULL, *r;
243     int if_kernel_index;
244     size_t len;
245 
246     memset(&hints, 0, sizeof(hints));
247     hints.ai_family = PF_UNSPEC;
248     hints.ai_socktype = SOCK_STREAM;
249     error = getaddrinfo(if_addr, NULL, &hints, &res);
250 
251     if (error) {
252         if (NULL != res) {
253             freeaddrinfo (res);
254         }
255         return OPAL_ERR_NOT_FOUND;
256     }
257 
258     for (r = res; r != NULL; r = r->ai_next) {
259         OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
260             if (AF_INET == r->ai_family && AF_INET == intf->af_family) {
261                 struct sockaddr_in ipv4;
262                 len = (r->ai_addrlen < sizeof(struct sockaddr_in)) ? r->ai_addrlen : sizeof(struct sockaddr_in);
263                 memcpy(&ipv4, r->ai_addr, len);
264                 if (opal_net_samenetwork((struct sockaddr*)&ipv4, (struct sockaddr*)&intf->if_addr, intf->if_mask)) {
265                     if_kernel_index = intf->if_kernel_index;
266                     freeaddrinfo (res);
267                     return if_kernel_index;
268                 }
269             }
270 #if OPAL_ENABLE_IPV6
271             else if (AF_INET6 == r->ai_family && AF_INET6 == intf->af_family) {
272                 struct sockaddr_in6 ipv6;
273                 len = (r->ai_addrlen < sizeof(struct sockaddr_in6)) ? r->ai_addrlen : sizeof(struct sockaddr_in6);
274                 memcpy(&ipv6, r->ai_addr, len);
275                 if (opal_net_samenetwork((struct sockaddr*)((struct sockaddr_in6*)&intf->if_addr),
276                                          (struct sockaddr*)&ipv6, intf->if_mask)) {
277                     if_kernel_index = intf->if_kernel_index;
278                     freeaddrinfo (res);
279                     return if_kernel_index;
280                 }
281             }
282 #endif
283         }
284     }
285     if (NULL != res) {
286         freeaddrinfo (res);
287     }
288     return OPAL_ERR_NOT_FOUND;
289 }
290 
291 /*
292  *  Return the number of discovered interface.
293  */
294 
opal_ifcount(void)295 int opal_ifcount(void)
296 {
297     return opal_list_get_size(&opal_if_list);
298 }
299 
300 
301 /*
302  *  Return the opal_list interface index for the first
303  *  interface in our list.
304  */
305 
opal_ifbegin(void)306 int opal_ifbegin(void)
307 {
308     opal_if_t *intf;
309 
310     intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
311     if (NULL != intf)
312         return intf->if_index;
313     return (-1);
314 }
315 
316 
317 /*
318  *  Located the current position in the list by if_index and
319  *  return the interface index of the next element in our list
320  *  (if it exists).
321  */
322 
opal_ifnext(int if_index)323 int opal_ifnext(int if_index)
324 {
325     opal_if_t *intf;
326 
327     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
328         if (intf->if_index == if_index) {
329             do {
330                 opal_if_t* if_next = (opal_if_t*)opal_list_get_next(intf);
331                 opal_if_t* if_end =  (opal_if_t*)opal_list_get_end(&opal_if_list);
332                 if (if_next == if_end) {
333                     return -1;
334                 }
335                 intf = if_next;
336             } while(intf->if_index == if_index);
337             return intf->if_index;
338         }
339     }
340     return (-1);
341 }
342 
343 
344 /*
345  *  Lookup the interface by opal_list index and return the
346  *  primary address assigned to the interface.
347  */
348 
opal_ifindextoaddr(int if_index,struct sockaddr * if_addr,unsigned int length)349 int opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
350 {
351     opal_if_t* intf;
352 
353     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
354         if (intf->if_index == if_index) {
355             memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
356             return OPAL_SUCCESS;
357         }
358     }
359     return OPAL_ERROR;
360 }
361 
362 
363 /*
364  *  Lookup the interface by opal_list kindex and return the
365  *  primary address assigned to the interface.
366  */
opal_ifkindextoaddr(int if_kindex,struct sockaddr * if_addr,unsigned int length)367 int opal_ifkindextoaddr(int if_kindex, struct sockaddr* if_addr, unsigned int length)
368 {
369     opal_if_t* intf;
370 
371     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
372         if (intf->if_kernel_index == if_kindex) {
373             memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
374             return OPAL_SUCCESS;
375         }
376     }
377     return OPAL_ERROR;
378 }
379 
380 
381 /*
382  *  Lookup the interface by opal_list index and return the
383  *  network mask assigned to the interface.
384  */
385 
opal_ifindextomask(int if_index,uint32_t * if_mask,int length)386 int opal_ifindextomask(int if_index, uint32_t* if_mask, int length)
387 {
388     opal_if_t* intf;
389 
390     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
391         if (intf->if_index == if_index) {
392             memcpy(if_mask, &intf->if_mask, length);
393             return OPAL_SUCCESS;
394         }
395     }
396     return OPAL_ERROR;
397 }
398 
399 /*
400  *  Lookup the interface by opal_list index and return the
401  *  MAC assigned to the interface.
402  */
403 
opal_ifindextomac(int if_index,uint8_t mac[6])404 int opal_ifindextomac(int if_index, uint8_t mac[6])
405 {
406     opal_if_t* intf;
407 
408     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
409         if (intf->if_index == if_index) {
410             memcpy(mac, &intf->if_mac, 6);
411             return OPAL_SUCCESS;
412         }
413     }
414     return OPAL_ERROR;
415 }
416 
417 /*
418  *  Lookup the interface by opal_list index and return the
419  *  MTU assigned to the interface.
420  */
421 
opal_ifindextomtu(int if_index,int * mtu)422 int opal_ifindextomtu(int if_index, int *mtu)
423 {
424     opal_if_t* intf;
425 
426     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
427         if (intf->if_index == if_index) {
428             *mtu = intf->ifmtu;
429             return OPAL_SUCCESS;
430         }
431     }
432     return OPAL_ERROR;
433 }
434 
435 /*
436  *  Lookup the interface by opal_list index and return the
437  *  flags assigned to the interface.
438  */
439 
opal_ifindextoflags(int if_index,uint32_t * if_flags)440 int opal_ifindextoflags(int if_index, uint32_t* if_flags)
441 {
442     opal_if_t* intf;
443 
444     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
445         if (intf->if_index == if_index) {
446             memcpy(if_flags, &intf->if_flags, sizeof(uint32_t));
447             return OPAL_SUCCESS;
448         }
449     }
450     return OPAL_ERROR;
451 }
452 
453 
454 
455 /*
456  *  Lookup the interface by opal_list index and return
457  *  the associated name.
458  */
459 
opal_ifindextoname(int if_index,char * if_name,int length)460 int opal_ifindextoname(int if_index, char* if_name, int length)
461 {
462     opal_if_t *intf;
463 
464     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
465         if (intf->if_index == if_index) {
466             strncpy(if_name, intf->if_name, length);
467             return OPAL_SUCCESS;
468         }
469     }
470     return OPAL_ERROR;
471 }
472 
473 
474 /*
475  *  Lookup the interface by kernel index and return
476  *  the associated name.
477  */
478 
opal_ifkindextoname(int if_kindex,char * if_name,int length)479 int opal_ifkindextoname(int if_kindex, char* if_name, int length)
480 {
481     opal_if_t *intf;
482 
483     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
484         if (intf->if_kernel_index == if_kindex) {
485             strncpy(if_name, intf->if_name, length);
486             return OPAL_SUCCESS;
487         }
488     }
489     return OPAL_ERROR;
490 }
491 
492 
493 #define ADDRLEN 100
494 bool
opal_ifislocal(const char * hostname)495 opal_ifislocal(const char *hostname)
496 {
497 #if OPAL_ENABLE_IPV6
498     char addrname[NI_MAXHOST]; /* should be larger than ADDRLEN, but I think
499                                   they really mean IFNAMESIZE */
500 #else
501     char addrname[ADDRLEN + 1];
502 #endif
503 
504     if (OPAL_SUCCESS == opal_ifaddrtoname(hostname, addrname, ADDRLEN)) {
505         return true;
506     }
507 
508     return false;
509 }
510 
parse_ipv4_dots(const char * addr,uint32_t * net,int * dots)511 static int parse_ipv4_dots(const char *addr, uint32_t* net, int* dots)
512 {
513     const char *start = addr, *end;
514     uint32_t n[]={0,0,0,0};
515     int i;
516 
517     /* now assemble the address */
518     for( i = 0; i < 4; i++ ) {
519         n[i] = strtoul(start, (char**)&end, 10);
520         if( end == start ) {
521             /* this is not an error, but indicates that
522              * we were given a partial address - e.g.,
523              * 192.168 - usually indicating an IP range
524              * in CIDR notation. So just return what we have
525              */
526             break;
527         }
528         /* did we read something sensible? */
529         if( n[i] > 255 ) {
530             return OPAL_ERR_NETWORK_NOT_PARSEABLE;
531         }
532         /* skip all the . */
533         for( start = end; '\0' != *start; start++ )
534             if( '.' != *start ) break;
535     }
536     *dots = i;
537     *net = OPAL_IF_ASSEMBLE_NETWORK(n[0], n[1], n[2], n[3]);
538     return OPAL_SUCCESS;
539 }
540 
541 int
opal_iftupletoaddr(const char * inaddr,uint32_t * net,uint32_t * mask)542 opal_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
543 {
544     int pval, dots, rc = OPAL_SUCCESS;
545     const char *ptr;
546 
547     /* if a mask was desired... */
548     if (NULL != mask) {
549         /* set default */
550         *mask = 0xFFFFFFFF;
551 
552         /* if entry includes mask, split that off */
553         if (NULL != (ptr = strchr(inaddr, '/'))) {
554             ptr = ptr + 1;  /* skip the / */
555             /* is the mask a tuple? */
556             if (NULL != strchr(ptr, '.')) {
557                 /* yes - extract mask from it */
558                 rc = parse_ipv4_dots(ptr, mask, &dots);
559             } else {
560                 /* no - must be an int telling us how much of the addr to use: e.g., /16
561                  * For more information please read http://en.wikipedia.org/wiki/Subnetwork.
562                  */
563                 pval = strtol(ptr, NULL, 10);
564                 if ((pval > 31) || (pval < 1)) {
565                     opal_output(0, "opal_iftupletoaddr: unknown mask");
566                     return OPAL_ERR_NETWORK_NOT_PARSEABLE;
567                 }
568                 *mask = 0xFFFFFFFF << (32 - pval);
569             }
570         } else {
571             /* use the number of dots to determine it */
572             for (ptr = inaddr, pval = 0; '\0'!= *ptr; ptr++) {
573                 if ('.' == *ptr) {
574                     pval++;
575                 }
576             }
577             /* if we have three dots, then we have four
578              * fields since it is a full address, so the
579              * default netmask is fine
580              */
581             if (3 == pval) {
582                 *mask = 0xFFFFFFFF;
583             } else if (2 == pval) {         /* 2 dots */
584                 *mask = 0xFFFFFF00;
585             } else if (1 == pval) {  /* 1 dot */
586                 *mask = 0xFFFF0000;
587             } else if (0 == pval) {  /* no dots */
588                 *mask = 0xFF000000;
589             } else {
590                 opal_output(0, "opal_iftupletoaddr: unknown mask");
591                 return OPAL_ERR_NETWORK_NOT_PARSEABLE;
592             }
593         }
594     }
595 
596     /* if network addr is desired... */
597     if (NULL != net) {
598         /* now assemble the address */
599         rc = parse_ipv4_dots(inaddr, net, &dots);
600     }
601 
602     return rc;
603 }
604 
605 /*
606  *  Determine if the specified interface is loopback
607  */
608 
opal_ifisloopback(int if_index)609 bool opal_ifisloopback(int if_index)
610 {
611     opal_if_t* intf;
612 
613     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
614         if (intf->if_index == if_index) {
615             if ((intf->if_flags & IFF_LOOPBACK) != 0) {
616                 return true;
617             }
618         }
619     }
620     return false;
621 }
622 
623 /* Determine if an interface matches any entry in the given list, taking
624  * into account that the list entries could be given as named interfaces,
625  * IP addrs, or subnet+mask
626  */
opal_ifmatches(int kidx,char ** nets)627 int opal_ifmatches(int kidx, char **nets)
628 {
629     bool named_if;
630     int i, rc;
631     size_t j;
632     int kindex;
633     struct sockaddr_in inaddr;
634     uint32_t addr, netaddr, netmask;
635 
636     /* get the address info for the given network in case we need it */
637     if (OPAL_SUCCESS != (rc = opal_ifkindextoaddr(kidx, (struct sockaddr*)&inaddr, sizeof(inaddr)))) {
638         return rc;
639     }
640     addr = ntohl(inaddr.sin_addr.s_addr);
641 
642     for (i=0; NULL != nets[i]; i++) {
643         /* if the specified interface contains letters in it, then it
644          * was given as an interface name and not an IP tuple
645          */
646         named_if = false;
647         for (j=0; j < strlen(nets[i]); j++) {
648             if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
649                 named_if = true;
650                 break;
651             }
652         }
653         if (named_if) {
654             if (0 > (kindex = opal_ifnametokindex(nets[i]))) {
655                 continue;
656             }
657             if (kindex == kidx) {
658                 return OPAL_SUCCESS;
659             }
660         } else {
661             if (OPAL_SUCCESS != (rc = opal_iftupletoaddr(nets[i], &netaddr, &netmask))) {
662                 opal_show_help("help-opal-util.txt", "invalid-net-mask", true, nets[i]);
663                 return rc;
664             }
665             if (netaddr == (addr & netmask)) {
666                 return OPAL_SUCCESS;
667             }
668         }
669     }
670     /* get here if not found */
671     return OPAL_ERR_NOT_FOUND;
672 }
673 
opal_ifgetaliases(char *** aliases)674 void opal_ifgetaliases(char ***aliases)
675 {
676     opal_if_t* intf;
677     char ipv4[INET_ADDRSTRLEN];
678     struct sockaddr_in *addr;
679 #if OPAL_ENABLE_IPV6
680     char ipv6[INET6_ADDRSTRLEN];
681     struct sockaddr_in6 *addr6;
682 #endif
683 
684     /* set default answer */
685     *aliases = NULL;
686 
687     OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
688         addr = (struct sockaddr_in*) &intf->if_addr;
689         /* ignore purely loopback interfaces */
690         if ((intf->if_flags & IFF_LOOPBACK) != 0) {
691             continue;
692         }
693         if (addr->sin_family == AF_INET) {
694             inet_ntop(AF_INET, &(addr->sin_addr.s_addr), ipv4, INET_ADDRSTRLEN);
695             opal_argv_append_nosize(aliases, ipv4);
696         }
697 #if OPAL_ENABLE_IPV6
698         else {
699             addr6 = (struct sockaddr_in6*) &intf->if_addr;
700             inet_ntop(AF_INET6, &(addr6->sin6_addr), ipv6, INET6_ADDRSTRLEN);
701             opal_argv_append_nosize(aliases, ipv6);
702         }
703 #endif
704     }
705 }
706 
707 #else /* HAVE_STRUCT_SOCKADDR_IN */
708 
709 /* if we don't have struct sockaddr_in, we don't have traditional
710    ethernet devices.  Just make everything a no-op error call */
711 
712 int
opal_ifnametoaddr(const char * if_name,struct sockaddr * if_addr,int size)713 opal_ifnametoaddr(const char* if_name,
714                   struct sockaddr* if_addr, int size)
715 {
716     return OPAL_ERR_NOT_SUPPORTED;
717 }
718 
719 int
opal_ifaddrtoname(const char * if_addr,char * if_name,int size)720 opal_ifaddrtoname(const char* if_addr,
721                   char* if_name, int size)
722 {
723     return OPAL_ERR_NOT_SUPPORTED;
724 }
725 
726 int
opal_ifnametoindex(const char * if_name)727 opal_ifnametoindex(const char* if_name)
728 {
729     return OPAL_ERR_NOT_SUPPORTED;
730 }
731 
732 int
opal_ifnametokindex(const char * if_name)733 opal_ifnametokindex(const char* if_name)
734 {
735     return OPAL_ERR_NOT_SUPPORTED;
736 }
737 
738 int
opal_ifindextokindex(int if_index)739 opal_ifindextokindex(int if_index)
740 {
741     return OPAL_ERR_NOT_SUPPORTED;
742 }
743 
744 int
opal_ifcount(void)745 opal_ifcount(void)
746 {
747     return OPAL_ERR_NOT_SUPPORTED;
748 }
749 
750 int
opal_ifbegin(void)751 opal_ifbegin(void)
752 {
753     return OPAL_ERR_NOT_SUPPORTED;
754 }
755 
756 int
opal_ifnext(int if_index)757 opal_ifnext(int if_index)
758 {
759     return OPAL_ERR_NOT_SUPPORTED;
760 }
761 
762 int
opal_ifindextoname(int if_index,char * if_name,int length)763 opal_ifindextoname(int if_index, char* if_name, int length)
764 {
765     return OPAL_ERR_NOT_SUPPORTED;
766 }
767 
768 int
opal_ifkindextoname(int kif_index,char * if_name,int length)769 opal_ifkindextoname(int kif_index, char* if_name, int length)
770 {
771     return OPAL_ERR_NOT_SUPPORTED;
772 }
773 
774 int
opal_ifindextoaddr(int if_index,struct sockaddr * if_addr,unsigned int length)775 opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
776 {
777     return OPAL_ERR_NOT_SUPPORTED;
778 }
779 
780 int
opal_ifindextomask(int if_index,uint32_t * if_addr,int length)781 opal_ifindextomask(int if_index, uint32_t* if_addr, int length)
782 {
783     return OPAL_ERR_NOT_SUPPORTED;
784 }
785 
786 bool
opal_ifislocal(const char * hostname)787 opal_ifislocal(const char *hostname)
788 {
789     return false;
790 }
791 
792 int
opal_iftupletoaddr(const char * inaddr,uint32_t * net,uint32_t * mask)793 opal_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
794 {
795     return 0;
796 }
797 
opal_ifmatches(int idx,char ** nets)798 int opal_ifmatches(int idx, char **nets)
799 {
800     return OPAL_ERR_NOT_SUPPORTED;
801 }
802 
opal_ifgetaliases(char *** aliases)803 void opal_ifgetaliases(char ***aliases)
804 {
805     /* set default answer */
806     *aliases = NULL;
807 }
808 
809 #endif /* HAVE_STRUCT_SOCKADDR_IN */
810 
811