MINOR: lua: add ip addresses and network manipulation function
Add two functions core.parse_addr() and core.match_addr() where are used
for matching networks.
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst
index 77c2266..32ef143 100644
--- a/doc/lua-api/index.rst
+++ b/doc/lua-api/index.rst
@@ -582,6 +582,28 @@
Give back the hand at the HAProxy scheduler. It is used when the LUA
processing consumes a lot of processing time.
+.. js:function:: core.parse_addr(address)
+
+ **context**: body, init, task, action, sample-fetch, converter
+
+ :param network: is a string describing an ipv4 or ipv6 address and optionally
+ its network length, like this: "127.0.0.1/8" or "aaaa::1234/32".
+ :returns: a userdata containing network or nil if an error occurs.
+
+ Parse ipv4 or ipv6 adresses and its facultative associated network.
+
+.. js:function:: core.match_addr(addr1, addr2)
+
+ **context**: body, init, task, action, sample-fetch, converter
+
+ :param addr1: is an address created with "core.parse_addr".
+ :param addr2: is an address created with "core.parse_addr".
+ :returns: boolean, true if the network of the addresses matche, else returns
+ false.
+
+ Match two networks. For example "127.0.0.1/32" matchs "127.0.0.0/8". The order
+ of network is not important.
+
.. _proxy_class:
Proxy class
diff --git a/include/types/hlua.h b/include/types/hlua.h
index 698786d..d2aaa4a 100644
--- a/include/types/hlua.h
+++ b/include/types/hlua.h
@@ -150,6 +150,20 @@
int len;
};
+struct hlua_addr {
+ union {
+ struct {
+ struct in_addr ip;
+ struct in_addr mask;
+ } v4;
+ struct {
+ struct in6_addr ip;
+ struct in6_addr mask;
+ } v6;
+ } addr;
+ int type;
+};
+
#else /* USE_LUA */
/* Empty struct for compilation compatibility */
diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c
index b9ce84c..a21065d 100644
--- a/src/hlua_fcn.c
+++ b/src/hlua_fcn.c
@@ -906,6 +906,77 @@
return 1;
}
+int hlua_parse_addr(lua_State *L)
+{
+ struct hlua_addr *addr;
+ const char *str = luaL_checkstring(L, 1);
+ unsigned char mask;
+
+ addr = lua_newuserdata(L, sizeof(struct hlua_addr));
+ if (!addr) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if (str2net(str, PAT_MF_NO_DNS, &addr->addr.v4.ip, &addr->addr.v4.mask)) {
+ addr->type = AF_INET;
+ return 1;
+ }
+
+ if (str62net(str, &addr->addr.v6.ip, &mask)) {
+ len2mask6(mask, &addr->addr.v6.mask);
+ addr->type = AF_INET6;
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ return 1;
+}
+
+int hlua_match_addr(lua_State *L)
+{
+ struct hlua_addr *addr1;
+ struct hlua_addr *addr2;
+
+ if (!lua_isuserdata(L, 1) ||
+ !lua_isuserdata(L, 2)) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+
+ addr1 = lua_touserdata(L, 1);
+ addr2 = lua_touserdata(L, 2);
+
+ if (addr1->type != addr2->type) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+
+ if (addr1->type == AF_INET) {
+ if ((addr1->addr.v4.ip.s_addr & addr2->addr.v4.mask.s_addr) ==
+ (addr2->addr.v4.ip.s_addr & addr1->addr.v4.mask.s_addr)) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ } else {
+ if (((addr1->addr.v6.ip.s6_addr32[0] & addr2->addr.v6.mask.s6_addr32[0]) ==
+ (addr2->addr.v6.ip.s6_addr32[0] & addr1->addr.v6.mask.s6_addr32[0])) &&
+ ((addr1->addr.v6.ip.s6_addr32[1] & addr2->addr.v6.mask.s6_addr32[1]) ==
+ (addr2->addr.v6.ip.s6_addr32[1] & addr1->addr.v6.mask.s6_addr32[1])) &&
+ ((addr1->addr.v6.ip.s6_addr32[2] & addr2->addr.v6.mask.s6_addr32[2]) ==
+ (addr2->addr.v6.ip.s6_addr32[2] & addr1->addr.v6.mask.s6_addr32[2])) &&
+ ((addr1->addr.v6.ip.s6_addr32[3] & addr2->addr.v6.mask.s6_addr32[3]) ==
+ (addr2->addr.v6.ip.s6_addr32[3] & addr1->addr.v6.mask.s6_addr32[3]))) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ }
+
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
int hlua_fcn_reg_core_fcn(lua_State *L)
{
if (!hlua_concat_init(L))
@@ -918,6 +989,8 @@
hlua_class_function(L, "asctime_date", hlua_asctime_date);
hlua_class_function(L, "concat", hlua_concat_new);
hlua_class_function(L, "get_info", hlua_get_info);
+ hlua_class_function(L, "parse_addr", hlua_parse_addr);
+ hlua_class_function(L, "match_addr", hlua_match_addr);
/* Create listener object. */
lua_newtable(L);