/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pva = pvxs; using pvxs::impl::SB; namespace { DEFINE_LOGGER(out, "pvxvct"); // parse hostname, IP, or IP+netmask std::pair parsePeer(const char *optarg) { // nameorip // nameorip/## // nameorip/###.###.###.### // static is safe as we only use from main() thread static std::regex netname("([^/:]*)(?:/([0-9.]+))?"); std::cmatch match; if(!std::regex_match(optarg, match, netname)) { throw std::runtime_error(pva::SB()<<"Expected host name or IP range. not "<>nbit).good() || nbit>32) { throw std::runtime_error(pva::SB()<<"Expected number of bits. not "<[:port] Listen on the given interface(s). May be repeated.\n" " -B [,ttl#][@iface][:port]\n" " -H host Show only message sent from this peer. May be repeated.\n" " -P pvname Show only searches for this PV name. May be repeated.\n" <> peers; std::set pvnames; bool allowPeer(const pva::SockAddr& peer) { if(peers.empty()) return true; if(peer.family()!=AF_INET) return false; for(auto& pair : peers) { if((peer->in.sin_addr.s_addr & pair.second) == pair.first) { return true; } } return false; } } opts; std::vector bindaddrs; { int opt; while ((opt = getopt(argc, argv, "hVvCSH:B:P:")) != -1) { switch(opt) { case 'h': usage(argv[0]); return 0; case 'V': std::cout<, std::unique_ptr>> listeners; listeners.reserve(bindaddrs.size()); for(auto& baddr : bindaddrs) { auto manager = pva::UDPManager::instance(); listeners.emplace_back(manager.onSearch(baddr, searchCB), manager.onBeacon(baddr, beaconCB)); listeners.back().first->start(); listeners.back().second->start(); log_debug_printf(out, "Bind: %s\n", (SB()<