diff --git a/asyncmsg/NameService.h b/asyncmsg/NameService.h
index 170abbba6973e85c4fe971105a4431a6e4be5ceb..a8a72790cee2766deb1b10f4c4a6740a5e2c09d8 100644
--- a/asyncmsg/NameService.h
+++ b/asyncmsg/NameService.h
@@ -2,15 +2,16 @@
 #ifndef ASYNCMSG_NAMESERVICE_H_
 #define ASYNCMSG_NAMESERVICE_H_
 
+#include "ipc/partition.h"
+#include "ers/Issue.h"
+
+#include "boost/asio.hpp"
+
 #include <vector>
 #include <string>
 #include <map>
-#include <tuple>
 #include <cstdint>
-#include "boost/asio.hpp"
-
-#include "ipc/partition.h"
-#include "ers/Issue.h"
+#include <variant>
 
 namespace daq {
 
@@ -144,10 +145,10 @@ namespace daq {
              */
             std::string lookup_multicast_address(const std::string& addr) const;
 
-            /** typedef for readability, a 2-tuple of IP addresses representing network/netmask. */
-            typedef std::tuple<boost::asio::ip::address,boost::asio::ip::address> Network;
+            /** typedef for readability, either a ipv4 or ipv6 network */
+            using Network = std::variant<boost::asio::ip::network_v4, boost::asio::ip::network_v6>;
 
-            /** \brief A helper method to parse a string of the form network/netmask.
+            /** \brief A helper method to parse a string of the form network/prefix.
              */
             static Network parse_address_network(const std::string& network);
 
@@ -157,7 +158,7 @@ namespace daq {
 
         private:
 
-            bool matches(const boost::asio::ip::address& addr, const boost::asio::ip::address& mask) const;
+            bool matches(const Network& addr_mask) const;
 
             IPCPartition         m_partition;
             std::string          m_is_server;
diff --git a/src/NameService.cxx b/src/NameService.cxx
index 9e67dd3a9435192e46928d588977dca96a5263c4..02c4ce10bb34b7a8b88b1bedd9ee1b2dabeeaccc 100644
--- a/src/NameService.cxx
+++ b/src/NameService.cxx
@@ -33,7 +33,6 @@
 #include <algorithm>
 #include <map>                           // for map, map<>::mapped_type
 #include <string>                        // for string, allocator, operator+
-#include <tuple>                         // for tie, get, tuple, make_tuple
 #include <vector>                        // for vector
 
 
@@ -99,33 +98,20 @@ namespace daq {
 
                 for(const auto& network : m_data_networks) {
 
-                    auto& addr = std::get<0>(network);
-                    auto& mask = std::get<1>(network);
+                    if((network.index() == 0) && (intf->family() == AF_INET)) {
 
-                    if(addr.is_v4() && intf->family() == AF_INET) {
-		        auto addr4(addr.to_v4());
-			auto mask4(mask.to_v4());
+		        auto addr(std::get<0>(network).network());
 
-                        if(htonl(addr4.to_ulong() & mask4.to_ulong()) == (intf->address() & htonl(mask4.to_ulong()))) {
-			    info.Addresses.push_back(intf->address_string() + '/' +  mask4.to_string());
+                        if(htonl(addr.to_ulong()) == intf->network()) {
+			    info.Addresses.push_back(intf->address_string() + '/' +  std::to_string(std::get<0>(network).prefix_length()));
                         }
 
-                    } else if(addr.is_v6() && intf->family() == AF_INET6) {
-                        auto addr6(addr.to_v6().to_bytes());
-                        auto mask6(mask.to_v6().to_bytes());
+                    } else if((network.index() == 1) && (intf->family() == AF_INET6)) {
+                        auto addr(std::get<1>(network).network().to_bytes());
 
                         auto local_network = intf->network_v6();
-
-                        bool matches = true;
-                        for(size_t i = 0; i < addr6.size(); i++) {
-                            if((addr6[i] & mask6[i]) != local_network.s6_addr[i]) {
-                                matches = false;
-                                break;
-                            }
-                        }
-                        
-                        if(matches) {
-                            info.Addresses.push_back(intf->address_string() + '/' + intf->netmask_string());
+                        if(memcmp(&addr[0], &local_network.s6_addr[0], addr.size()) == 0) {
+                            info.Addresses.push_back(intf->address_string() + '/' + std::to_string(std::get<1>(network).prefix_length()));
                         }
                     } 
                 }
@@ -171,39 +157,32 @@ namespace daq {
                    throw InvalidISServer(ERS_HERE, servers.name(), reason);
                 }
             }
-
         }
 
-        bool NameService::matches(const boost::asio::ip::address& addr, const boost::asio::ip::address& mask) const
+        bool NameService::matches(const Network& addr_mask) const
         {
             for(const auto intf : daq::asyncmsg::Interface::interfaces()) {
 
                 // ignore these
-                if(!intf->has_flag(IFF_UP) || intf->has_flag(IFF_LOOPBACK) || intf->address() == 0) {
+                if(!intf->has_flag(IFF_UP) || intf->has_flag(IFF_LOOPBACK)) {
                     continue;
                 }
-                
+
                 // compare IPV4 address
-                if(addr.is_v4() && intf->family() == AF_INET) {
-		    if(htonl(addr.to_v4().to_ulong() & mask.to_v4().to_ulong()) == (intf->network() & htonl(mask.to_v4().to_ulong()))) {
-                        // found one, first match will be used
+                if(addr_mask.index() == 0 && intf->family() == AF_INET && intf->address() != 0) {
+                    auto addr(std::get<0>(addr_mask).network().to_bytes());
+                    auto local_network = intf->network();
+
+                    if(memcmp(&addr[0], &local_network, addr.size()) == 0) {
                         return true;
                     }
-                } else if (addr.is_v6() && intf->family() == AF_INET6) {
-                    auto addr6(addr.to_v6().to_bytes());
-                    auto mask6(mask.to_v6().to_bytes());
-
+                } else if (addr_mask.index() == 1 && intf->family() == AF_INET6) {
+                    auto addr(std::get<1>(addr_mask).network().to_bytes());
                     auto local_network = intf->network_v6();
 
-                    bool matches = true;
-                    for(size_t i = 0; i < addr6.size(); i++) {
-                        if((addr6[i] & mask6[i]) != local_network.s6_addr[i]) {
-                            matches = false;
-                            break;
-                        }
+                    if(memcmp(&addr[0], &local_network.s6_addr[0], addr.size()) == 0) {
+                        return true;
                     }
-
-                    return matches;
                 }
             }
             
@@ -229,10 +208,14 @@ namespace daq {
                 // match my local interfaces against the list
                 for(auto& addr_netmask : info.Addresses) {
                     boost::asio::ip::address addr, mask;
-                    std::tie(addr, mask) = parse_address_network(addr_netmask);
-
-                    if(matches(addr, mask)) {
-                        results.push_back(boost::asio::ip::tcp::endpoint(addr, info.Port));
+                    Network addr_mask = parse_address_network(addr_netmask);
+                    if(matches(addr_mask)) {
+                        // retrieve address part only
+                        if(addr_mask.index() == 0) {
+                            results.push_back(boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port));
+                        } else {
+                            results.push_back(boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port));
+                        }
                         break;
                     }
                 }
@@ -259,10 +242,14 @@ namespace daq {
                 // match my local interfaces against the list
                 for(auto& addr_netmask : info.Addresses) {
                     boost::asio::ip::address addr, mask;
-                    std::tie(addr, mask) = parse_address_network(addr_netmask);
+                    Network addr_mask = parse_address_network(addr_netmask);
 
-                    if(matches(addr, mask)) {
-                        results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(addr, info.Port);
+                    if(matches(addr_mask)) {
+                        if(addr_mask.index() == 0) {
+                            results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port);
+                        } else {
+                            results[name.substr(m_is_server.size() + 5)] = boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port);
+                        }
                         break;
                     }
                 }
@@ -288,11 +275,14 @@ namespace daq {
 
                 // match my local interfaces against the list
                 for(auto& addr_netmask : info.Addresses) {
-                    boost::asio::ip::address addr, mask;
-                    std::tie(addr, mask) = parse_address_network(addr_netmask);
+                    Network addr_mask = parse_address_network(addr_netmask);
 
-                    if(matches(addr, mask)) {
-                        results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(addr, info.Port));
+                    if(matches(addr_mask)) {
+                        if(addr_mask.index() == 0) {
+                            results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port));
+                        } else {
+                            results[name.substr(m_is_server.size() + 5)].push_back(boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port));
+                        }
                     }
                 }
             }
@@ -311,11 +301,14 @@ namespace daq {
             d.getValue(m_is_server + ".MSG_" + name, info);
 
             for(auto& addr_netmask : info.Addresses) {
-                boost::asio::ip::address addr, mask;
-                std::tie(addr, mask) = parse_address_network(addr_netmask);
-                
-                if(matches(addr, mask)) {
-                    return boost::asio::ip::tcp::endpoint(addr, info.Port);                    
+                Network addr_mask = parse_address_network(addr_netmask);
+
+                if(matches(addr_mask)) {
+                    if(addr_mask.index() == 0) {
+                        return boost::asio::ip::tcp::endpoint(std::get<0>(addr_mask).address(), info.Port);
+                    } else {
+                        return boost::asio::ip::tcp::endpoint(std::get<1>(addr_mask).address(), info.Port);
+                    }
                 }
             }
 
@@ -326,15 +319,14 @@ namespace daq {
         NameService::Network 
         NameService::parse_address_network(const std::string& network)
         {
-            size_t slash = network.find('/');
-            std::string address = network.substr(0, slash);
-            std::string netmask = "255.255.255.255";
-            if(slash != std::string::npos) {
-                netmask = network.substr(slash+1);
-            }
+            boost::system::error_code ec;
 
-            return std::make_tuple(boost::asio::ip::address::from_string(address),
-                                   boost::asio::ip::address::from_string(netmask));
+            // Try v4 first
+            Network result{boost::asio::ip::make_network_v4(network, ec)};
+            if(!ec.failed()) {
+                return result;
+            }
+            return Network{boost::asio::ip::make_network_v6(network)};
         }
 
         boost::asio::ip::address NameService::find_interface(const std::string& netmask)
diff --git a/test/test_namesvc.cxx b/test/test_namesvc.cxx
index 83b4b13ca87b343bccc4dd0a5503f01269b30a70..0f5f8529c167f09a5bfab5519f85bbdf46d16460 100644
--- a/test/test_namesvc.cxx
+++ b/test/test_namesvc.cxx
@@ -37,12 +37,8 @@ int main(int argc, char *argv[])
     //  DFParameters.DefaultDataNetworks 
     // 
     // CERN GPN
-    // Testbed B.4 pub, internal
     //
-    std::vector<std::string> data_networks{"137.138.0.0/255.255.0.0", 
-            "188.184.2.64/255.255.255.192",
-            "10.193.128.0/255.255.254.0",
-            "10.193.64.0/255.255.254.0"};
+    std::vector<std::string> data_networks{"137.138.0.0/16"};
 
     argv += 3;
     argc -= 3;