3 -- This project is MIT/X11 licensed. Please see the
4 -- COPYING file in the source package for more information.
6 -- Copyright (C) 2012 Paul Aurich
7 -- Copyright (C) 2013 Matthew Wild
8 -- Copyright (C) 2013 Florian Zeitz
17 #include <sys/ioctl.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
22 #include <arpa/inet.h>
23 #include <netinet/in.h>
29 #if (LUA_VERSION_NUM == 502)
30 #define luaL_register(L, N, R) luaL_setfuncs(L, R, 0)
33 /* Enumerate all locally configured IP addresses */
35 const char * const type_strings[] = {
42 static int lc_local_addresses(lua_State *L)
45 /* Link-local IPv4 addresses; see RFC 3927 and RFC 5735 */
46 const long ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */
47 const long ip4_mask = htonl(0xffff0000);
48 struct ifaddrs *addr = NULL, *a;
51 int type = luaL_checkoption(L, 1, "both", type_strings);
52 const char link_local = lua_toboolean(L, 2); /* defaults to 0 (false) */
53 const char ipv4 = (type == 0 || type == 1);
54 const char ipv6 = (type == 0 || type == 2);
57 if (getifaddrs(&addr) < 0) {
59 lua_pushfstring(L, "getifaddrs failed (%d): %s", errno,
67 for (a = addr; a; a = a->ifa_next) {
69 char ipaddr[INET6_ADDRSTRLEN];
70 const char *tmp = NULL;
72 if (a->ifa_addr == NULL || a->ifa_flags & IFF_LOOPBACK)
75 family = a->ifa_addr->sa_family;
77 if (ipv4 && family == AF_INET) {
78 struct sockaddr_in *sa = (struct sockaddr_in *)a->ifa_addr;
79 if (!link_local &&((sa->sin_addr.s_addr & ip4_mask) == ip4_linklocal))
81 tmp = inet_ntop(family, &sa->sin_addr, ipaddr, sizeof(ipaddr));
82 } else if (ipv6 && family == AF_INET6) {
83 struct sockaddr_in6 *sa = (struct sockaddr_in6 *)a->ifa_addr;
84 if (!link_local && IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr))
86 if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr) || IN6_IS_ADDR_V4COMPAT(&sa->sin6_addr))
88 tmp = inet_ntop(family, &sa->sin6_addr, ipaddr, sizeof(ipaddr));
92 lua_pushstring(L, tmp);
93 lua_rawseti(L, -2, n++);
95 /* TODO: Error reporting? */
101 lua_pushstring(L, "0.0.0.0");
102 lua_rawseti(L, -2, n++);
105 lua_pushstring(L, "::");
106 lua_rawseti(L, -2, n++);
112 int luaopen_util_net(lua_State* L)
114 luaL_Reg exports[] = {
115 { "local_addresses", lc_local_addresses },
120 luaL_register(L, NULL, exports);