]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: Add function to compare an address to a network address
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 26 Feb 2021 08:12:50 +0000 (09:12 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 26 Feb 2021 12:52:06 +0000 (13:52 +0100)
ipcmp2net() function may be used to compare an addres (struct
sockaddr_storage) to a network address (struct net_addr). Among other
things, this function will be used to add support of IPv6 for "except"
parameter of "forwardfor" and "originalto" options.

include/haproxy/tools.h
src/tools.c

index 4e3e4af9809034811c4917dbb8f4298ede5ad281..46fef67c5d15c6e1a83e066e99b8b96663f2994a 100644 (file)
@@ -740,6 +740,13 @@ extern int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr);
  */
 int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2);
 
+/* compare a struct sockaddr_storage to a struct net_addr and return :
+ *  0 (true)  if <addr> is matching <net>
+ *  1 (false) if <addr> is not matching <net>
+ *  -1 (unable) if <addr> or <net> is not AF_INET*
+ */
+int ipcmp2net(const struct sockaddr_storage *addr, const struct net_addr *net);
+
 /* copy ip from <source> into <dest>
  * the caller must clear <dest> before calling.
  * Returns a pointer to the destination
index 4db3e1898f5e802027385885ee3c4f8542f2ca57..82e1063944bfc686da9a638531a00eda31a4b9ef 100644 (file)
@@ -46,6 +46,7 @@
 #include <haproxy/hlua.h>
 #include <haproxy/listener.h>
 #include <haproxy/namespace.h>
+#include <haproxy/net_helper.h>
 #include <haproxy/protocol.h>
 #include <haproxy/resolvers.h>
 #include <haproxy/sock.h>
@@ -3110,6 +3111,40 @@ int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
        return 1;
 }
 
+/* compare a struct sockaddr_storage to a struct net_addr and return :
+ *  0 (true)  if <addr> is matching <net>
+ *  1 (false) if <addr> is not matching <net>
+ *  -1 (unable) if <addr> or <net> is not AF_INET*
+ */
+int ipcmp2net(const struct sockaddr_storage *addr, const struct net_addr *net)
+{
+       if ((addr->ss_family != AF_INET) && (addr->ss_family != AF_INET6))
+               return -1;
+
+       if ((net->family != AF_INET) && (net->family != AF_INET6))
+               return -1;
+
+       if (addr->ss_family != net->family)
+               return 1;
+
+       if (addr->ss_family == AF_INET &&
+           (((struct sockaddr_in *)addr)->sin_addr.s_addr & net->addr.v4.mask.s_addr) == net->addr.v4.ip.s_addr)
+               return 0;
+       else {
+               const struct in6_addr *addr6  = &(((const struct sockaddr_in6*)addr)->sin6_addr);
+               const struct in6_addr *nip6   = &net->addr.v6.ip;
+               const struct in6_addr *nmask6 = &net->addr.v6.mask;
+
+               if ((read_u32(&addr6->s6_addr[0]) & read_u32(&nmask6->s6_addr[0])) == read_u32(&nip6->s6_addr[0]) &&
+                   (read_u32(&addr6->s6_addr[4]) & read_u32(&nmask6->s6_addr[4])) == read_u32(&nip6->s6_addr[4]) &&
+                   (read_u32(&addr6->s6_addr[8]) & read_u32(&nmask6->s6_addr[8])) == read_u32(&nip6->s6_addr[8]) &&
+                   (read_u32(&addr6->s6_addr[12]) & read_u32(&nmask6->s6_addr[12])) == read_u32(&nip6->s6_addr[12]))
+                       return 0;
+       }
+
+       return 1;
+}
+
 /* copy IP address from <source> into <dest>
  * The caller must allocate and clear <dest> before calling.
  * The source must be in either AF_INET or AF_INET6 family, or the destination