2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2005-11-05 22:57:48 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
2007-04-25 05:55:40 +04:00
|
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
2005-11-05 22:57:48 +03:00
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2009-07-02 18:44:41 +04:00
|
|
|
* Copyright (c) 2004-2009 High Performance Computing Center Stuttgart,
|
2004-11-28 23:09:25 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2008-11-05 21:45:42 +03:00
|
|
|
* Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved.
|
2010-03-23 23:37:06 +03:00
|
|
|
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-01-15 02:24:15 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal_config.h"
|
2007-05-17 05:17:59 +04:00
|
|
|
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <string.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <unistd.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <errno.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <sys/types.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <sys/socket.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
2005-03-28 15:55:57 +04:00
|
|
|
#ifdef HAVE_SYS_SOCKIO_H
|
|
|
|
#include <sys/sockio.h>
|
|
|
|
#endif
|
2004-10-20 05:03:09 +04:00
|
|
|
#ifdef HAVE_SYS_IOCTL_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <sys/ioctl.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <netinet/in.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_ARPA_INET_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <arpa/inet.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NET_IF_H
|
2007-01-24 20:31:49 +03:00
|
|
|
#if defined(__APPLE__) && defined(_LP64)
|
|
|
|
/* Apple engineering suggested using options align=power as a
|
|
|
|
workaround for a bug in OS X 10.4 (Tiger) that prevented ioctl(...,
|
|
|
|
SIOCGIFCONF, ...) from working properly in 64 bit mode on Power PC.
|
|
|
|
It turns out that the underlying issue is the size of struct
|
|
|
|
ifconf, which the kernel expects to be 12 and natural 64 bit
|
|
|
|
alignment would make 16. The same bug appears in 64 bit mode on
|
|
|
|
Intel macs, but align=power is a no-op there, so instead, use the
|
|
|
|
pack pragma to instruct the compiler to pack on 4 byte words, which
|
|
|
|
has the same effect as align=power for our needs and works on both
|
|
|
|
Intel and Power PC Macs. */
|
|
|
|
#pragma pack(push,4)
|
2005-08-02 19:14:41 +04:00
|
|
|
#endif
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <net/if.h>
|
2007-01-24 20:31:49 +03:00
|
|
|
#if defined(__APPLE__) && defined(_LP64)
|
|
|
|
#pragma pack(pop)
|
2005-08-02 19:14:41 +04:00
|
|
|
#endif
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NETDB_H
|
2004-01-14 21:24:30 +03:00
|
|
|
#include <netdb.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
2007-04-25 05:55:40 +04:00
|
|
|
#ifdef HAVE_IFADDRS_H
|
|
|
|
#include <ifaddrs.h>
|
|
|
|
#endif
|
2011-06-05 23:16:42 +04:00
|
|
|
#include <ctype.h>
|
2007-04-25 05:55:40 +04:00
|
|
|
|
2005-07-03 20:22:16 +04:00
|
|
|
#include "opal/class/opal_list.h"
|
2005-07-04 05:36:20 +04:00
|
|
|
#include "opal/util/if.h"
|
2005-07-04 03:31:27 +04:00
|
|
|
#include "opal/util/output.h"
|
2009-10-09 19:24:41 +04:00
|
|
|
#include "opal/util/argv.h"
|
2011-06-05 23:16:42 +04:00
|
|
|
#include "opal/util/show_help.h"
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal/constants.h"
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
#include "opal/mca/if/base/base.h"
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-13 17:35:21 +04:00
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN
|
2005-07-13 08:16:03 +04:00
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
#ifndef MIN
|
|
|
|
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
|
|
#endif
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
|
|
|
* Look for interface by name and returns its address
|
|
|
|
* as a dotted decimal formatted string.
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2007-05-17 05:17:59 +04:00
|
|
|
int opal_ifnametoaddr(const char* if_name, struct sockaddr* addr, int length)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (strcmp(intf->if_name, if_name) == 0) {
|
2004-01-15 03:57:33 +03:00
|
|
|
memcpy(addr, &intf->if_addr, length);
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
}
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERROR;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
|
2004-01-29 18:34:47 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Look for interface by name and returns its
|
2007-04-25 05:55:40 +04:00
|
|
|
* corresponding opal_list index.
|
2004-01-29 18:34:47 +03:00
|
|
|
*/
|
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifnametoindex(const char* if_name)
|
2004-01-29 18:34:47 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return -1;
|
|
|
|
}
|
2004-01-29 18:34:47 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (strcmp(intf->if_name, if_name) == 0) {
|
2004-01-29 18:34:47 +03:00
|
|
|
return intf->if_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2007-04-25 05:55:40 +04:00
|
|
|
* Look for interface by name and returns its
|
|
|
|
* corresponding kernel index.
|
|
|
|
*/
|
|
|
|
|
2009-04-02 22:35:09 +04:00
|
|
|
int16_t opal_ifnametokindex(const char* if_name)
|
2007-04-25 05:55:40 +04:00
|
|
|
{
|
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return -1;
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2007-04-25 05:55:40 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (strcmp(intf->if_name, if_name) == 0) {
|
2007-04-25 05:55:40 +04:00
|
|
|
return intf->if_kernel_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look for interface by opal_list index and returns its
|
|
|
|
* corresponding kernel index.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int opal_ifindextokindex(int if_index)
|
|
|
|
{
|
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return -1;
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2007-04-25 05:55:40 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (if_index == intf->if_index) {
|
2007-04-25 05:55:40 +04:00
|
|
|
return intf->if_kernel_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempt to resolve the adddress (given as either IPv4/IPv6 string
|
|
|
|
* or hostname) and lookup corresponding interface.
|
2004-01-15 02:24:15 +03:00
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifaddrtoname(const char* if_addr, char* if_name, int length)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* intf;
|
2007-04-25 05:55:40 +04:00
|
|
|
#if OPAL_WANT_IPV6
|
|
|
|
int error;
|
2008-01-17 15:29:12 +03:00
|
|
|
struct addrinfo hints, *res = NULL, *r;
|
2007-04-25 05:55:40 +04:00
|
|
|
#else
|
2005-12-13 01:01:51 +03:00
|
|
|
#ifndef __WINDOWS__
|
2004-10-22 20:06:05 +04:00
|
|
|
in_addr_t inaddr;
|
|
|
|
#else
|
|
|
|
unsigned long inaddr;
|
|
|
|
#endif
|
|
|
|
struct hostent *h;
|
2007-04-25 05:55:40 +04:00
|
|
|
#endif
|
2004-10-22 20:06:05 +04:00
|
|
|
|
2008-04-17 17:50:59 +04:00
|
|
|
/* if the user asked us not to resolve interfaces, then just return */
|
2010-09-22 05:11:40 +04:00
|
|
|
if (opal_if_do_not_resolve) {
|
2008-04-17 17:50:59 +04:00
|
|
|
/* return not found so ifislocal will declare
|
|
|
|
* the node to be non-local
|
|
|
|
*/
|
|
|
|
return OPAL_ERR_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2010-09-22 05:11:40 +04:00
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
#if OPAL_WANT_IPV6
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
error = getaddrinfo(if_addr, NULL, &hints, &res);
|
|
|
|
|
|
|
|
if (error) {
|
2008-01-17 13:01:52 +03:00
|
|
|
if (NULL != res) {
|
|
|
|
freeaddrinfo (res);
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
return OPAL_ERR_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (r = res; r != NULL; r = r->ai_next) {
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2007-04-25 05:55:40 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
|
|
|
|
|
|
|
if (AF_INET == r->ai_family) {
|
|
|
|
struct sockaddr_in ipv4;
|
|
|
|
struct sockaddr_in *inaddr;
|
|
|
|
|
|
|
|
inaddr = (struct sockaddr_in*) &intf->if_addr;
|
|
|
|
memcpy (&ipv4, r->ai_addr, r->ai_addrlen);
|
|
|
|
|
|
|
|
if (inaddr->sin_addr.s_addr == ipv4.sin_addr.s_addr) {
|
|
|
|
strncpy(if_name, intf->if_name, length);
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
} else {
|
2007-05-17 05:17:59 +04:00
|
|
|
if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*) &intf->if_addr)->sin6_addr,
|
2007-04-25 05:55:40 +04:00
|
|
|
&((struct sockaddr_in6*) r->ai_addr)->sin6_addr)) {
|
|
|
|
strncpy(if_name, intf->if_name, length);
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-01-17 15:29:12 +03:00
|
|
|
}
|
|
|
|
if (NULL != res) {
|
|
|
|
freeaddrinfo (res);
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
#else
|
|
|
|
inaddr = inet_addr(if_addr);
|
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
if (INADDR_NONE == inaddr) {
|
2004-10-22 20:06:05 +04:00
|
|
|
h = gethostbyname(if_addr);
|
2010-07-27 17:46:55 +04:00
|
|
|
if (0 == h) {
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_FOUND;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
memcpy(&inaddr, h->h_addr, sizeof(inaddr));
|
|
|
|
}
|
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (((struct sockaddr_in*) &intf->if_addr)->sin_addr.s_addr == inaddr) {
|
2004-01-14 21:24:30 +03:00
|
|
|
strncpy(if_name, intf->if_name, length);
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
#endif
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_FOUND;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
|
|
|
* Return the number of discovered interface.
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifcount(void)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2010-09-22 05:11:40 +04:00
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
return opal_list_get_size(&opal_if_list);
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2007-04-25 05:55:40 +04:00
|
|
|
* Return the opal_list interface index for the first
|
2004-01-15 02:24:15 +03:00
|
|
|
* interface in our list.
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifbegin(void)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t *intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2010-07-27 17:46:55 +04:00
|
|
|
if (NULL != intf)
|
2004-01-14 21:24:30 +03:00
|
|
|
return intf->if_index;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
|
|
|
* Located the current position in the list by if_index and
|
|
|
|
* return the interface index of the next element in our list
|
|
|
|
* (if it exists).
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifnext(int if_index)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t *intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return -1;
|
|
|
|
}
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2004-07-07 18:01:55 +04:00
|
|
|
do {
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* if_next = (opal_if_t*)opal_list_get_next(intf);
|
|
|
|
opal_if_t* if_end = (opal_if_t*)opal_list_get_end(&opal_if_list);
|
2004-07-07 20:28:01 +04:00
|
|
|
if (if_next == if_end) {
|
2004-07-07 18:01:55 +04:00
|
|
|
return -1;
|
2004-07-07 20:28:01 +04:00
|
|
|
}
|
|
|
|
intf = if_next;
|
2004-07-07 18:01:55 +04:00
|
|
|
} while(intf->if_index == if_index);
|
|
|
|
return intf->if_index;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2007-04-25 05:55:40 +04:00
|
|
|
* Lookup the interface by opal_list index and return the
|
2004-01-15 02:24:15 +03:00
|
|
|
* primary address assigned to the interface.
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2007-05-17 05:17:59 +04:00
|
|
|
int opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2007-04-25 05:55:40 +04:00
|
|
|
memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
}
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERROR;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-26 21:41:37 +03:00
|
|
|
/*
|
2007-04-25 05:55:40 +04:00
|
|
|
* Lookup the interface by opal_list index and return the
|
2004-01-26 21:41:37 +03:00
|
|
|
* network mask assigned to the interface.
|
|
|
|
*/
|
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
int opal_ifindextomask(int if_index, uint32_t* if_mask, int length)
|
2004-01-26 21:41:37 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2004-01-26 21:41:37 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2004-01-26 21:41:37 +03:00
|
|
|
memcpy(if_mask, &intf->if_mask, length);
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2004-01-26 21:41:37 +03:00
|
|
|
}
|
|
|
|
}
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERROR;
|
2004-01-26 21:41:37 +03:00
|
|
|
}
|
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
/*
|
|
|
|
* Lookup the interface by opal_list index and return the
|
|
|
|
* flags assigned to the interface.
|
|
|
|
*
|
|
|
|
* Bug: Make return type portable (compatible with Windows)
|
|
|
|
*/
|
|
|
|
|
|
|
|
int opal_ifindextoflags(int if_index, uint32_t* if_flags)
|
|
|
|
{
|
|
|
|
opal_if_t* intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2007-04-25 05:55:40 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2007-04-25 05:55:40 +04:00
|
|
|
memcpy(if_flags, &intf->if_flags, sizeof(uint32_t));
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2004-01-26 21:41:37 +03:00
|
|
|
|
|
|
|
|
2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2007-04-25 05:55:40 +04:00
|
|
|
* Lookup the interface by opal_list index and return
|
2004-01-15 02:24:15 +03:00
|
|
|
* the associated name.
|
|
|
|
*/
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2005-07-04 05:36:20 +04:00
|
|
|
int opal_ifindextoname(int if_index, char* if_name, int length)
|
2004-01-14 21:24:30 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_if_t *intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2004-01-14 21:24:30 +03:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2005-07-04 05:36:20 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2004-01-14 21:24:30 +03:00
|
|
|
strncpy(if_name, intf->if_name, length);
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
|
|
|
}
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERROR;
|
2004-01-14 21:24:30 +03:00
|
|
|
}
|
2004-10-31 22:01:53 +03:00
|
|
|
|
2006-07-12 00:54:49 +04:00
|
|
|
|
2007-04-25 05:55:40 +04:00
|
|
|
/*
|
|
|
|
* Lookup the interface by kernel index and return
|
|
|
|
* the associated name.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int opal_ifkindextoname(int if_kindex, char* if_name, int length)
|
|
|
|
{
|
|
|
|
opal_if_t *intf;
|
2010-09-22 05:11:40 +04:00
|
|
|
|
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2007-04-25 05:55:40 +04:00
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2007-04-25 05:55:40 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_kernel_index == if_kindex) {
|
2007-04-25 05:55:40 +04:00
|
|
|
strncpy(if_name, intf->if_name, length);
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2006-07-12 00:54:49 +04:00
|
|
|
|
2004-11-01 17:18:30 +03:00
|
|
|
#define ADDRLEN 100
|
2004-10-31 22:01:53 +03:00
|
|
|
bool
|
2007-07-22 23:19:01 +04:00
|
|
|
opal_ifislocal(const char *hostname)
|
2004-10-31 22:01:53 +03:00
|
|
|
{
|
2007-04-25 05:55:40 +04:00
|
|
|
#if OPAL_WANT_IPV6
|
|
|
|
char addrname[NI_MAXHOST]; /* should be larger than ADDRLEN, but I think
|
|
|
|
they really mean IFNAMESIZE */
|
|
|
|
#else
|
|
|
|
char addrname[ADDRLEN + 1];
|
|
|
|
#endif
|
2005-06-01 23:30:05 +04:00
|
|
|
|
2011-01-10 19:29:42 +03:00
|
|
|
if (OPAL_SUCCESS == opal_ifaddrtoname(hostname, addrname, ADDRLEN)) {
|
|
|
|
return true;
|
|
|
|
}
|
2004-10-31 22:01:53 +03:00
|
|
|
|
2011-01-10 19:29:42 +03:00
|
|
|
return false;
|
2004-10-31 22:01:53 +03:00
|
|
|
}
|
2005-07-13 08:16:03 +04:00
|
|
|
|
2011-05-04 01:59:51 +04:00
|
|
|
static uint32_t parse_dots(const char *addr)
|
2009-10-09 19:24:41 +04:00
|
|
|
{
|
|
|
|
char **tuple;
|
|
|
|
uint32_t n[]={0,0,0,0};
|
|
|
|
uint32_t net;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tuple = opal_argv_split(addr, '.');
|
|
|
|
/* now assemble the address */
|
|
|
|
for (i=0; NULL != tuple[i]; i++) {
|
|
|
|
n[i] = strtoul(tuple[i], NULL, 10);
|
|
|
|
}
|
|
|
|
net = OPAL_IF_ASSEMBLE_NETWORK(n[0], n[1], n[2], n[3]);
|
|
|
|
opal_argv_free(tuple);
|
|
|
|
return net;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2011-05-04 01:59:51 +04:00
|
|
|
opal_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
|
2009-10-09 19:24:41 +04:00
|
|
|
{
|
|
|
|
char **tuple;
|
|
|
|
int pval;
|
|
|
|
char *msk, *ptr;
|
|
|
|
|
|
|
|
/* if a mask was desired... */
|
|
|
|
if (NULL != mask) {
|
|
|
|
/* set default */
|
|
|
|
*mask = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
/* if entry includes mask, split that off */
|
|
|
|
msk = NULL;
|
2011-05-04 01:59:51 +04:00
|
|
|
if (NULL != (ptr = strchr(inaddr, '/'))) {
|
2009-10-09 19:24:41 +04:00
|
|
|
*ptr = '\0';
|
|
|
|
msk = ptr + 1;
|
|
|
|
/* is the mask a tuple? */
|
|
|
|
if (NULL != strchr(msk, '.')) {
|
|
|
|
/* yes - extract mask from it */
|
|
|
|
*mask = parse_dots(msk);
|
|
|
|
} else {
|
2011-05-04 01:59:51 +04:00
|
|
|
/* no - must be an int telling us how much of the addr to use: e.g., /16
|
|
|
|
* For more information please read http://en.wikipedia.org/wiki/Subnetwork.
|
2009-10-09 19:24:41 +04:00
|
|
|
*/
|
|
|
|
pval = strtol(msk, NULL, 10);
|
2011-05-04 01:59:51 +04:00
|
|
|
if ((pval > 31) || (pval < 1)) {
|
2009-10-09 19:24:41 +04:00
|
|
|
opal_output(0, "opal_iftupletoaddr: unknown mask");
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
2011-05-04 01:59:51 +04:00
|
|
|
*mask = 0xFFFFFFFF << (32 - pval);
|
2009-10-09 19:24:41 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* use the number of dots to determine it */
|
2011-05-04 01:59:51 +04:00
|
|
|
tuple = opal_argv_split(inaddr, '.');
|
2009-10-09 19:24:41 +04:00
|
|
|
pval = opal_argv_count(tuple);
|
|
|
|
/* if we have three dots, then we have four
|
|
|
|
* fields since it is a full address, so the
|
|
|
|
* default netmask is fine
|
|
|
|
*/
|
|
|
|
if (pval < 4) {
|
|
|
|
if (3 == pval) { /* 2 dots */
|
|
|
|
*mask = 0xFFFFFF00;
|
|
|
|
} else if (2 == pval) { /* 1 dot */
|
|
|
|
*mask = 0xFFFF0000;
|
|
|
|
} else if (1 == pval) { /* no dots */
|
|
|
|
*mask = 0xFF000000;
|
|
|
|
} else {
|
|
|
|
opal_output(0, "opal_iftupletoaddr: unknown mask");
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
opal_argv_free(tuple);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if network addr is desired... */
|
|
|
|
if (NULL != net) {
|
|
|
|
/* set default */
|
|
|
|
*net = 0;
|
|
|
|
|
|
|
|
/* if entry includes mask, split that off */
|
2011-05-04 01:59:51 +04:00
|
|
|
if (NULL != (ptr = strchr(inaddr, '/'))) {
|
2009-10-09 19:24:41 +04:00
|
|
|
*ptr = '\0';
|
|
|
|
}
|
|
|
|
/* now assemble the address */
|
2011-05-04 01:59:51 +04:00
|
|
|
*net = parse_dots(inaddr);
|
2009-10-09 19:24:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return OPAL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine if the specified interface is loopback
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool opal_ifisloopback(int if_index)
|
|
|
|
{
|
|
|
|
opal_if_t* intf;
|
2010-09-18 03:04:06 +04:00
|
|
|
|
2010-09-22 05:11:40 +04:00
|
|
|
if (OPAL_SUCCESS != opal_if_base_open()) {
|
|
|
|
return OPAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2010-07-27 17:46:55 +04:00
|
|
|
for (intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
|
2009-10-09 19:24:41 +04:00
|
|
|
intf != (opal_if_t*)opal_list_get_end(&opal_if_list);
|
|
|
|
intf = (opal_if_t*)opal_list_get_next(intf)) {
|
2010-07-27 17:46:55 +04:00
|
|
|
if (intf->if_index == if_index) {
|
2009-10-09 19:24:41 +04:00
|
|
|
if ((intf->if_flags & IFF_LOOPBACK) != 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-05 23:16:42 +04:00
|
|
|
/* Determine if an interface matches any entry in the given list, taking
|
|
|
|
* into account that the list entries could be given as named interfaces,
|
|
|
|
* IP addrs, or subnet+mask
|
|
|
|
*/
|
|
|
|
bool opal_ifmatches(int idx, char **nets)
|
|
|
|
{
|
|
|
|
bool named_if;
|
|
|
|
int i;
|
|
|
|
size_t j;
|
|
|
|
int index;
|
|
|
|
struct sockaddr_in inaddr;
|
|
|
|
uint32_t addr, netaddr, netmask;
|
|
|
|
|
|
|
|
/* get the address info for the given network in case we need it */
|
|
|
|
if (OPAL_SUCCESS != opal_ifindextoaddr(idx, (struct sockaddr*)&inaddr, sizeof(inaddr))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
addr = ntohl(inaddr.sin_addr.s_addr);
|
|
|
|
|
|
|
|
for (i=0; NULL != nets[i]; i++) {
|
|
|
|
/* if the specified interface contains letters in it, then it
|
|
|
|
* was given as an interface name and not an IP tuple
|
|
|
|
*/
|
|
|
|
named_if = false;
|
|
|
|
for (j=0; j < strlen(nets[i]); j++) {
|
|
|
|
if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
|
|
|
|
named_if = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (named_if) {
|
|
|
|
if (0 > (index = opal_ifnametoindex(nets[i]))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (index == idx) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (OPAL_SUCCESS != opal_iftupletoaddr(nets[i], &netaddr, &netmask)) {
|
|
|
|
opal_show_help("help-opal-util.txt", "invalid-net-mask", true, nets[i]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (netaddr == (addr & netmask)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* get here if not found */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-04-25 22:06:06 +04:00
|
|
|
|
2005-07-13 08:16:03 +04:00
|
|
|
#else /* HAVE_STRUCT_SOCKADDR_IN */
|
|
|
|
|
|
|
|
/* if we don't have struct sockaddr_in, we don't have traditional
|
2010-09-22 05:11:40 +04:00
|
|
|
ethernet devices. Just make everything a no-op error call */
|
2005-07-13 08:16:03 +04:00
|
|
|
|
|
|
|
int
|
|
|
|
opal_ifnametoaddr(const char* if_name,
|
2007-05-17 05:17:59 +04:00
|
|
|
struct sockaddr* if_addr, int size)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
opal_ifaddrtoname(const char* if_addr,
|
|
|
|
char* if_name, int size)
|
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-07-13 17:20:22 +04:00
|
|
|
opal_ifnametoindex(const char* if_name)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
2009-04-02 22:35:09 +04:00
|
|
|
int16_t
|
2007-04-25 05:55:40 +04:00
|
|
|
opal_ifnametokindex(const char* if_name)
|
|
|
|
{
|
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
opal_ifindextokindex(int if_index)
|
|
|
|
{
|
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
2005-07-13 08:16:03 +04:00
|
|
|
int
|
2005-07-13 17:20:22 +04:00
|
|
|
opal_ifcount(void)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-07-13 17:20:22 +04:00
|
|
|
opal_ifbegin(void)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-07-13 17:20:22 +04:00
|
|
|
opal_ifnext(int if_index)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-07-13 17:20:22 +04:00
|
|
|
opal_ifindextoname(int if_index, char* if_name, int length)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-04-25 05:55:40 +04:00
|
|
|
opal_ifkindextoname(int kif_index, char* if_name, int length)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-05-17 05:17:59 +04:00
|
|
|
opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
|
2007-04-25 05:55:40 +04:00
|
|
|
{
|
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-05-09 08:46:21 +04:00
|
|
|
opal_ifindextomask(int if_index, uint32_t* if_addr, int length)
|
2005-07-13 08:16:03 +04:00
|
|
|
{
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_ERR_NOT_SUPPORTED;
|
2005-07-13 08:16:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2007-07-22 23:19:01 +04:00
|
|
|
opal_ifislocal(const char *hostname)
|
2006-07-12 00:54:49 +04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-01-07 21:14:03 +03:00
|
|
|
int
|
|
|
|
opal_iftupletoaddr(char *inaddr, uint32_t *net, uint32_t *mask)
|
2009-10-09 19:24:41 +04:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2010-01-07 21:14:03 +03:00
|
|
|
|
2011-06-05 23:16:42 +04:00
|
|
|
bool opal_ifispresent(char *if)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-07-13 08:16:03 +04:00
|
|
|
#endif /* HAVE_STRUCT_SOCKADDR_IN */
|
2007-04-25 23:08:07 +04:00
|
|
|
|