Skip to content

Commit

Permalink
include, misc: Add net interface API.
Browse files Browse the repository at this point in the history
Adds `uv_network_interface_t` structure and a new API for retrieving
network interfaces, `uv_network_interfaces`.  This new API intends to
eventually replace `uv_interface_addresses`, adding new capabilities,
such as:

 * Not filtering out interfaces without addresses;
 * Marking missing addresses as `AF_UNSPEC`;
 * Including all common cross-platform flags;
 * Including link-layer addresses for interfaces;
 * Supporting 8-byte Firewire link-layer addresses;
 * Including broadcast/point-to-point addresses

The interface is added and documented, and returns `UV_ENOTSUP` on
all platforms.  Once the individual platform support is merged, the
test driver will no longer accept the `UV_ENOTSUP` return and the
existing `uv_interface_addresses` function will be changed to be
implemented on top of this new API.
  • Loading branch information
apaprocki committed Sep 3, 2019
1 parent 43c74a6 commit f8f55c8
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 2 deletions.
87 changes: 85 additions & 2 deletions docs/src/misc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,70 @@ Data types
} netmask;
} uv_interface_address_t;

.. c:type:: uv_network_interface_t
Data type for network interfaces.

::

typedef struct uv_network_interface_s {
char* name;
uint32_t flags;
char phys_addr[16];
uint32_t phys_addr_len;
union {
struct sockaddr_in address4;
struct sockaddr_in6 address6;
} address;
struct sockaddr_in broadcast4;
uint32_t prefix;
} uv_network_interface_t;


.. c:macro:: UV_NETIF_IS_UP
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface is up and running.


.. c:macro:: UV_NETIF_IS_LOOPBACK
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface is a loopback
interface.


.. c:macro:: UV_NETIF_IS_PTP
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface is a point-to-point
interface.


.. c:macro:: UV_NETIF_IS_PROMISCUOUS
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface is in promiscuous
mode.


.. c:macro:: UV_NETIF_HAS_BROADCAST
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface has the broadcast
flag set. Currently, only IPv4 interface records have an
IPv4 broadcast address, but the flag can be set on all
interface records that share the same name.


.. c:macro:: UV_NETIF_HAS_MULTICAST
Macro that takes an `uv_network_interface_t` and returns
1 or 0 indicating whether the interface has the multicast
flag set. The flag can be set on all interface records
that share the same name.


.. c:type:: uv_passwd_t
Data type for password file information.
Expand Down Expand Up @@ -295,14 +359,33 @@ API
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
Gets address information about the network interfaces on the system. An
array of `count` elements is allocated and returned in `addresses`. It must
be freed by the user, calling :c:func:`uv_free_interface_addresses`.
array of `count` elements is allocated and returned in `addresses`. Only
includes interfaces with `INET` or `INET6` addresses. It must be freed by
the user, calling :c:func:`uv_free_interface_addresses`.
.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count)
Free an array of :c:type:`uv_interface_address_t` which was returned by
:c:func:`uv_interface_addresses`.
.. c:function:: int uv_network_interfaces(uv_network_interface_t** interfaces, int* count)
Gets information about internet network interfaces on the system. An array
of `count` elements is allocated and returned in `interfaces`. Includes up,
down, unattached interfaces and interfaces without addresses. Missing
addresses are marked with a family of `AF_UNSPEC` and their contents are
unspecified. At least one link-layer record is returned for each interface.
It must be freed by the user, calling :c:func:`uv_free_network_interfaces`.
.. note::
This interface will return `UV_ENOTSUP` until individual platform support
has been implemented for each supported platform.
.. c:function:: void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count)
Free an array of :c:type:`uv_network_interface_t` which was returned by
:c:func:`uv_network_interfaces`.
.. c:function:: void uv_loadavg(double avg[3])
Gets the load average. See: `<http://en.wikipedia.org/wiki/Load_(computing)>`_
Expand Down
44 changes: 44 additions & 0 deletions include/uv.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ typedef struct uv_work_s uv_work_t;
typedef struct uv_env_item_s uv_env_item_t;
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_network_interface_s uv_network_interface_t;
typedef struct uv_dirent_s uv_dirent_t;
typedef struct uv_passwd_s uv_passwd_t;
typedef struct uv_utsname_s uv_utsname_t;
Expand Down Expand Up @@ -1061,6 +1062,45 @@ struct uv_interface_address_s {
} netmask;
};

/*
* These are the flags that are present in the uv_network_interface_t.flags
* field.
*/
enum uv_netif_flags {
/* Indicates the interface is up and running. */
UV_NETIF_UP = (1 << 0),
/* Indicates the interface is a loopback interface. */
UV_NETIF_LOOPBACK = (1 << 1),
/* Indicates the interface is a point-to-point interface. */
UV_NETIF_PTP = (1 << 2),
/* Indicates the interface is running in promiscuous mode. */
UV_NETIF_PROMISCUOUS = (1 << 3),
/* Indicates the interface broadcast address field is populated. */
UV_NETIF_BROADCAST = (1 << 4),
/* Indicates the interface is enabled for multicast packets. */
UV_NETIF_MULTICAST = (1 << 5)
};

#define UV_NETIF_IS_UP(netif) (!!(netif.flags & UV_NETIF_UP))
#define UV_NETIF_IS_LOOPBACK(netif) (!!(netif.flags & UV_NETIF_LOOPBACK))
#define UV_NETIF_IS_PTP(netif) (!!(netif.flags & UV_NETIF_PTP))
#define UV_NETIF_IS_PROMISCUOUS(netif) (!!(netif.flags & UV_NETIF_PROMISCUOUS))
#define UV_NETIF_HAS_BROADCAST(netif) (!!(netif.flags & UV_NETIF_BROADCAST))
#define UV_NETIF_HAS_MULTICAST(netif) (!!(netif.flags & UV_NETIF_MULTICAST))

typedef struct uv_network_interface_s {
char* name;
uint32_t flags; /* uv_netif_flags */
char phys_addr[16];
uint32_t phys_addr_len;
union {
struct sockaddr_in address4;
struct sockaddr_in6 address6;
} address;
struct sockaddr_in broadcast4;
uint32_t prefix; /* CIDR prefix for both IPv4 and IPv6 */
} uv_network_interface_s;

struct uv_passwd_s {
char* username;
long uid;
Expand Down Expand Up @@ -1196,6 +1236,10 @@ UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);

UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);

UV_EXTERN int uv_network_interfaces(uv_network_interface_t** interfaces,
int* count);
UV_EXTERN void uv_free_network_interfaces(uv_network_interface_t* interfaces,
int count);

typedef enum {
UV_FS_UNKNOWN = -1,
Expand Down
16 changes: 16 additions & 0 deletions src/unix/aix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,22 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}


int uv_network_interfaces(uv_network_interface_t** interfaces, int* count) {
return UV_ENOTSUP;
}


void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count) {
int i;

for (i = 0; i < count; i++) {
uv__free(interfaces[i].name);
}

uv__free(interfaces);
}


void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct pollfd* events;
uintptr_t i;
Expand Down
16 changes: 16 additions & 0 deletions src/unix/bsd-ifaddrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,19 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,

uv__free(addresses);
}


int uv_network_interfaces(uv_network_interface_t** interfaces, int* count) {
return UV_ENOTSUP;
}


void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count) {
int i;

for (i = 0; i < count; i++) {
uv__free(interfaces[i].name);
}

uv__free(interfaces);
}
16 changes: 16 additions & 0 deletions src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,22 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
}


int uv_network_interfaces(uv_network_interface_t** interfaces, int* count) {
return UV_ENOTSUP;
}


void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count) {
int i;

for (i = 0; i < count; i++) {
uv__free(interfaces[i].name);
}

uv__free(interfaces);
}


void uv__set_process_title(const char* title) {
#if defined(PR_SET_NAME)
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
Expand Down
17 changes: 17 additions & 0 deletions src/unix/sunos.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
#endif /* SUNOS_NO_IFADDRS */


void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
int i;
Expand All @@ -834,3 +835,19 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,

uv__free(addresses);
}


int uv_network_interfaces(uv_network_interface_t** interfaces, int* count) {
return UV_ENOTSUP;
}


void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count) {
int i;

for (i = 0; i < count; i++) {
uv__free(interfaces[i].name);
}

uv__free(interfaces);
}
16 changes: 16 additions & 0 deletions src/win/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,22 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
}


int uv_network_interfaces(uv_network_interface_t** interfaces, int* count) {
return UV_ENOTSUP;
}


void uv_free_network_interfaces(uv_network_interface_t* interfaces, int count) {
int i;

for (i = 0; i < count; i++) {
uv__free(interfaces[i].name);
}

uv__free(interfaces);
}


int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME createTime, exitTime, kernelTime, userTime;
SYSTEMTIME kernelSystemTime, userSystemTime;
Expand Down
Loading

0 comments on commit f8f55c8

Please sign in to comment.