nixio:
Added binding for getifaddrs(): List network interfaces, their flags, addresses and statistics Cleanups
This commit is contained in:
parent
a8da3a09a3
commit
d81b3548a9
7 changed files with 244 additions and 7 deletions
|
@ -20,6 +20,23 @@ module "nixio"
|
||||||
-- @param ipaddr IPv4 or IPv6-Address
|
-- @param ipaddr IPv4 or IPv6-Address
|
||||||
-- @return FQDN
|
-- @return FQDN
|
||||||
|
|
||||||
|
--- (Linux, BSD) Get a list of available network interfaces and their addresses.
|
||||||
|
-- @class function
|
||||||
|
-- @name nixio.getifaddrs
|
||||||
|
-- @return Table containing one or more tables containing: <ul>
|
||||||
|
-- <li>name = Interface Name</li>
|
||||||
|
-- <li>family = ["inet", "inet6", "packet"]</li>
|
||||||
|
-- <li>addr = Interface Address (IPv4, IPv6, MAC, ...)</li>
|
||||||
|
-- <li>broadaddr = Broadcast Address</li>
|
||||||
|
-- <li>dstaddr = Destination Address (Point-to-Point)</li>
|
||||||
|
-- <li>netmask = Netmask (if available)</li>
|
||||||
|
-- <li>prefix = Prefix (if available)</li>
|
||||||
|
-- <li>flags = Table of interface flags (up, multicast, loopback, ...)</li>
|
||||||
|
-- <li>data = Statistics (Linux, "packet"-family)</li>
|
||||||
|
-- <li>hatype = Hardware Type Identifier (Linix, "packet"-family)</li>
|
||||||
|
-- <li>ifindex = Interface Index (Linux, "packet"-family)</li>
|
||||||
|
-- </ul>
|
||||||
|
|
||||||
--- Create a new socket and bind it to a network address.
|
--- Create a new socket and bind it to a network address.
|
||||||
-- This function is a shortcut for calling nixio.socket and then bind()
|
-- This function is a shortcut for calling nixio.socket and then bind()
|
||||||
-- on the socket object.
|
-- on the socket object.
|
||||||
|
|
|
@ -21,6 +21,40 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
/* struct net_device_stats is buggy on amd64, redefine it */
|
||||||
|
struct nixio__nds {
|
||||||
|
uint32_t rx_packets;
|
||||||
|
uint32_t tx_packets;
|
||||||
|
uint32_t rx_bytes;
|
||||||
|
uint32_t tx_bytes;
|
||||||
|
uint32_t rx_errors;
|
||||||
|
uint32_t tx_errors;
|
||||||
|
uint32_t rx_dropped;
|
||||||
|
uint32_t tx_dropped;
|
||||||
|
uint32_t multicast;
|
||||||
|
uint32_t collisions;
|
||||||
|
|
||||||
|
uint32_t rx_length_errors;
|
||||||
|
uint32_t rx_over_errors;
|
||||||
|
uint32_t rx_crc_errors;
|
||||||
|
uint32_t rx_frame_errors;
|
||||||
|
uint32_t rx_fifo_errors;
|
||||||
|
uint32_t rx_missed_errors;
|
||||||
|
|
||||||
|
uint32_t tx_aborted_errors;
|
||||||
|
uint32_t tx_carrier_errors;
|
||||||
|
uint32_t tx_fifo_errors;
|
||||||
|
uint32_t tx_heartbeat_errors;
|
||||||
|
uint32_t tx_window_errors;
|
||||||
|
|
||||||
|
uint32_t rx_compressed;
|
||||||
|
uint32_t tx_compressed;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NI_MAXHOST
|
#ifndef NI_MAXHOST
|
||||||
#define NI_MAXHOST 1025
|
#define NI_MAXHOST 1025
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,6 +74,20 @@ int nixio__addr_parse(nixio_addr *addr, struct sockaddr *saddr) {
|
||||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)saddr;
|
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)saddr;
|
||||||
addr->port = ntohs(inet6addr->sin6_port);
|
addr->port = ntohs(inet6addr->sin6_port);
|
||||||
baddr = &inet6addr->sin6_addr;
|
baddr = &inet6addr->sin6_addr;
|
||||||
|
#ifdef AF_PACKET
|
||||||
|
} else if (saddr->sa_family == AF_PACKET) {
|
||||||
|
struct sockaddr_ll *etheradddr = (struct sockaddr_ll*)saddr;
|
||||||
|
addr->prefix = etheradddr->sll_hatype;
|
||||||
|
addr->port = etheradddr->sll_ifindex;
|
||||||
|
char *c = addr->host;
|
||||||
|
for (size_t i = 0; i < etheradddr->sll_halen; i++) {
|
||||||
|
*c++ = nixio__bin2hex[(etheradddr->sll_addr[i] & 0xf0) >> 4];
|
||||||
|
*c++ = nixio__bin2hex[(etheradddr->sll_addr[i] & 0x0f)];
|
||||||
|
*c++ = ':';
|
||||||
|
}
|
||||||
|
*(c-1) = 0;
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
errno = EAFNOSUPPORT;
|
errno = EAFNOSUPPORT;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -91,6 +139,39 @@ int nixio__addr_write(nixio_addr *addr, struct sockaddr *saddr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netmask to prefix helper
|
||||||
|
*/
|
||||||
|
int nixio__addr_prefix(struct sockaddr *saddr) {
|
||||||
|
int prefix = 0;
|
||||||
|
size_t len;
|
||||||
|
uint8_t *addr;
|
||||||
|
|
||||||
|
if (saddr->sa_family == AF_INET) {
|
||||||
|
addr = (uint8_t*)(&((struct sockaddr_in*)saddr)->sin_addr);
|
||||||
|
len = 4;
|
||||||
|
} else if (saddr->sa_family == AF_INET6) {
|
||||||
|
addr = (uint8_t*)(&((struct sockaddr_in6*)saddr)->sin6_addr);
|
||||||
|
len = 16;
|
||||||
|
} else {
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
if (addr[i] == 0xff) {
|
||||||
|
prefix += 8;
|
||||||
|
} else if (addr[i] == 0x00) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
for (uint8_t c = addr[i]; c; c <<= 1) {
|
||||||
|
prefix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getaddrinfo(host, family, port)
|
* getaddrinfo(host, family, port)
|
||||||
|
@ -264,9 +345,146 @@ static int nixio_sock_getpeername(lua_State *L) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(BSD)
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
static int nixio_getifaddrs(lua_State *L) {
|
||||||
|
nixio_addr addr;
|
||||||
|
struct ifaddrs *ifaddr, *c;
|
||||||
|
if (getifaddrs(&ifaddr) == -1) {
|
||||||
|
return nixio__perror(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
unsigned int i = 1;
|
||||||
|
|
||||||
|
for (c = ifaddr; c; c = c->ifa_next) {
|
||||||
|
lua_newtable(L);
|
||||||
|
|
||||||
|
lua_pushstring(L, c->ifa_name);
|
||||||
|
lua_setfield(L, -2, "name");
|
||||||
|
|
||||||
|
lua_createtable(L, 0, 7);
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_UP);
|
||||||
|
lua_setfield(L, -2, "up");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_BROADCAST);
|
||||||
|
lua_setfield(L, -2, "broadcast");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_LOOPBACK);
|
||||||
|
lua_setfield(L, -2, "loopback");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_POINTOPOINT);
|
||||||
|
lua_setfield(L, -2, "pointtopoint");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_NOARP);
|
||||||
|
lua_setfield(L, -2, "noarp");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_PROMISC);
|
||||||
|
lua_setfield(L, -2, "promisc");
|
||||||
|
|
||||||
|
lua_pushboolean(L, c->ifa_flags & IFF_MULTICAST);
|
||||||
|
lua_setfield(L, -2, "multicast");
|
||||||
|
lua_setfield(L, -2, "flags");
|
||||||
|
|
||||||
|
if (c->ifa_addr && !nixio__addr_parse(&addr, c->ifa_addr)) {
|
||||||
|
lua_pushstring(L, addr.host);
|
||||||
|
lua_setfield(L, -2, "addr");
|
||||||
|
|
||||||
|
if (c->ifa_addr->sa_family == AF_INET) {
|
||||||
|
lua_pushliteral(L, "inet");
|
||||||
|
} else if (c->ifa_addr->sa_family == AF_INET6) {
|
||||||
|
lua_pushliteral(L, "inet6");
|
||||||
|
#ifdef AF_PACKET
|
||||||
|
} else if (c->ifa_addr->sa_family == AF_PACKET) {
|
||||||
|
lua_pushliteral(L, "packet");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
lua_pushliteral(L, "unknown");
|
||||||
|
}
|
||||||
|
lua_setfield(L, -2, "family");
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
if (c->ifa_addr->sa_family == AF_PACKET) {
|
||||||
|
lua_pushinteger(L, addr.port);
|
||||||
|
lua_setfield(L, -2, "ifindex");
|
||||||
|
|
||||||
|
lua_pushinteger(L, addr.prefix);
|
||||||
|
lua_setfield(L, -2, "hatype");
|
||||||
|
|
||||||
|
if (c->ifa_data) {
|
||||||
|
lua_createtable(L, 0, 10);
|
||||||
|
struct nixio__nds *stats = c->ifa_data;
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->rx_packets);
|
||||||
|
lua_setfield(L, -2, "rx_packets");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->tx_packets);
|
||||||
|
lua_setfield(L, -2, "tx_packets");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->rx_bytes);
|
||||||
|
lua_setfield(L, -2, "rx_bytes");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->tx_bytes);
|
||||||
|
lua_setfield(L, -2, "tx_bytes");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->rx_errors);
|
||||||
|
lua_setfield(L, -2, "rx_errors");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->tx_errors);
|
||||||
|
lua_setfield(L, -2, "tx_errors");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->rx_dropped);
|
||||||
|
lua_setfield(L, -2, "rx_dropped");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->tx_dropped);
|
||||||
|
lua_setfield(L, -2, "tx_dropped");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->multicast);
|
||||||
|
lua_setfield(L, -2, "multicast");
|
||||||
|
|
||||||
|
lua_pushnumber(L, stats->collisions);
|
||||||
|
lua_setfield(L, -2, "collisions");
|
||||||
|
} else {
|
||||||
|
lua_newtable(L);
|
||||||
|
}
|
||||||
|
lua_setfield(L, -2, "data");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ifa_netmask && !nixio__addr_parse(&addr, c->ifa_netmask)) {
|
||||||
|
lua_pushstring(L, addr.host);
|
||||||
|
lua_setfield(L, -2, "netmask");
|
||||||
|
|
||||||
|
lua_pushinteger(L, nixio__addr_prefix(c->ifa_netmask));
|
||||||
|
lua_setfield(L, -2, "prefix");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ifa_broadaddr && !nixio__addr_parse(&addr, c->ifa_broadaddr)) {
|
||||||
|
lua_pushstring(L, addr.host);
|
||||||
|
lua_setfield(L, -2, "broadaddr");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ifa_dstaddr && !nixio__addr_parse(&addr, c->ifa_dstaddr)) {
|
||||||
|
lua_pushstring(L, addr.host);
|
||||||
|
lua_setfield(L, -2, "dstaddr");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawseti(L, -2, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifaddr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* module table */
|
/* module table */
|
||||||
static const luaL_reg R[] = {
|
static const luaL_reg R[] = {
|
||||||
|
#if defined(__linux__) || defined(BSD)
|
||||||
|
{"getifaddrs", nixio_getifaddrs},
|
||||||
|
#endif
|
||||||
{"getaddrinfo", nixio_getaddrinfo},
|
{"getaddrinfo", nixio_getaddrinfo},
|
||||||
{"getnameinfo", nixio_getnameinfo},
|
{"getnameinfo", nixio_getnameinfo},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "nixio.h"
|
#include "nixio.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static char nixio__bin2hex[] = {
|
const char nixio__bin2hex[16] = {
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#define VERSION 0.2
|
#define VERSION 0.3
|
||||||
|
|
||||||
|
|
||||||
/* pushes nil, error number and errstring on the stack */
|
/* pushes nil, error number and errstring on the stack */
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef struct nixio_address {
|
||||||
int family;
|
int family;
|
||||||
char host[128];
|
char host[128];
|
||||||
int port;
|
int port;
|
||||||
|
int prefix;
|
||||||
} nixio_addr;
|
} nixio_addr;
|
||||||
|
|
||||||
int nixio__perror(lua_State *L);
|
int nixio__perror(lua_State *L);
|
||||||
|
@ -47,7 +48,6 @@ int nixio__pstatus(lua_State *L, int condition);
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
@ -90,6 +90,8 @@ int nixio__mode_write(int mode, char *modestr);
|
||||||
|
|
||||||
int nixio__push_stat(lua_State *L, nixio_stat_t *buf);
|
int nixio__push_stat(lua_State *L, nixio_stat_t *buf);
|
||||||
|
|
||||||
|
const char nixio__bin2hex[16];
|
||||||
|
|
||||||
/* Module functions */
|
/* Module functions */
|
||||||
void nixio_open_file(lua_State *L);
|
void nixio_open_file(lua_State *L);
|
||||||
void nixio_open_socket(lua_State *L);
|
void nixio_open_socket(lua_State *L);
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
|
|
||||||
#include "nixio.h"
|
#include "nixio.h"
|
||||||
|
|
||||||
|
#ifndef __WINNT__
|
||||||
|
#include <net/if.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static char nixio__bin2hex[] = {
|
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
|
||||||
};
|
|
||||||
|
|
||||||
static int nixio_crypto_hash__init(lua_State *L, int hmac) {
|
static int nixio_crypto_hash__init(lua_State *L, int hmac) {
|
||||||
const char *type = luaL_checkstring(L, 1);
|
const char *type = luaL_checkstring(L, 1);
|
||||||
nixio_hash *hash = lua_newuserdata(L, sizeof(nixio_hash));
|
nixio_hash *hash = lua_newuserdata(L, sizeof(nixio_hash));
|
||||||
|
|
Loading…
Reference in a new issue