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);