static int daemonMain(int argc, char *argv[]) { try { std::string macAddressString = g_macAddress->val(); replace(macAddressString, "-", ""); if (macAddressString.size() != 12u) { std::cerr << "MAC address must be 12 characters" << std::endl; return -1; } std::string macAddress = dataFromHexstring(macAddressString); std::set<Address::ptr> blacklistedAddresses; std::vector<std::string> blacklistedAddressesString = split( g_blacklist->val(), ";, "); for(std::vector<std::string>::const_iterator it( blacklistedAddressesString.begin()); it != blacklistedAddressesString.end(); ++it) { if(it->empty()) continue; blacklistedAddresses.insert(IPAddress::create(it->c_str())); } std::vector<std::pair<Address::ptr, unsigned int> > addresses = Address::getInterfaceAddresses(g_interface->val(), AF_INET); if (addresses.empty()) { std::cerr << "Couldn't find interface " << g_interface->val() << std::endl; return -1; } IPAddress::ptr localAddress = boost::static_pointer_cast<IPAddress>( addresses.front().first); IPAddress::ptr broadcastAddress = localAddress->broadcastAddress( addresses.front().second); broadcastAddress->port(9u); IPv4Address multicastAddress("239.255.255.250", 1900); IOManager ioManager; Socket::ptr broadcastSocket(broadcastAddress->createSocket(ioManager, SOCK_DGRAM)); broadcastSocket->setOption(SOL_SOCKET, SO_BROADCAST, 1); broadcastSocket->connect(broadcastAddress); Socket::ptr listenSocket(multicastAddress.createSocket(ioManager, SOCK_DGRAM)); listenSocket->setOption(SOL_SOCKET, SO_REUSEADDR, 1); listenSocket->bind(IPv4Address(0u, 1900u)); // TODO: listenSocket->joinGroup(multicastAddress, addresses.front().first); struct ip_mreq multicastGroup; memcpy(&multicastGroup.imr_multiaddr, &((sockaddr_in *)multicastAddress.name())->sin_addr, sizeof(struct in_addr)); memcpy(&multicastGroup.imr_interface, &((sockaddr_in *)addresses.front().first->name())->sin_addr, sizeof(struct in_addr)); listenSocket->setOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, multicastGroup); Daemon::onTerminate.connect(boost::bind(&Socket::cancelReceive, listenSocket)); try { IPv4Address sender; char buffer[4096]; size_t size; while((size = listenSocket->receiveFrom(buffer, 4096, sender))) { IPAddress::ptr senderDuplicate = sender.clone(); senderDuplicate->port(0u); if (blacklistedAddresses.find(senderDuplicate) != blacklistedAddresses.end()) { MORDOR_LOG_VERBOSE(Log::root()) << "Skipping broadcast from " << sender; continue; } HTTP::Request request; HTTP::RequestParser parser(request); parser.run(buffer, size); if (parser.complete() && !parser.error()) { if (request.requestLine.method == "M-SEARCH") { MORDOR_LOG_INFO(Log::root()) << "Relaying M-SEARCH to WOL from " << sender; wol(broadcastSocket, macAddress); } } else { MORDOR_LOG_WARNING(Log::root()) << "Unable to parse HTTP request from " << sender << ": " << charslice(buffer, size); } } } catch (OperationAbortedException &) { } catch (...) { MORDOR_LOG_FATAL(Log::root()) << boost::current_exception_diagnostic_information(); return -1; } } catch (...) { std::cerr << boost::current_exception_diagnostic_information() << std::endl; return -1; } return 0; }