diff --git a/src/Connection.cpp b/src/Connection.cpp index 7d159a9..d9d4c77 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -30,6 +30,7 @@ #include "Settings.h" #include "Streamer.h" #include "Log.h" +#include "Toolkit/NetworkToolkit.h" #include "Connection.h" @@ -219,9 +220,13 @@ void Connection::ask() // loop infinitely while(Connection::manager().asking_) { - // broadcast on several ports - for(int i=HANDSHAKE_PORT; i bcasts = NetworkToolkit::broadcast_ips(); + for(int i=HANDSHAKE_PORT; i NetworkToolkit::host_ips() return ipstrings_; } +std::vector NetworkToolkit::broadcast_ips() +{ + std::vector broadcasts; + + char buf[16384]; + int fd = socket(PF_INET, SOCK_DGRAM, 0); + if (fd < 0) + return broadcasts; + + struct ifconf ifconf; + ifconf.ifc_len = sizeof buf; + ifconf.ifc_buf = buf; + if (ioctl(fd, SIOCGIFCONF, &ifconf) == 0) { + struct ifreq *ifreq = ifconf.ifc_req; + for (int i = 0; i < ifconf.ifc_len; ) { + size_t len; +#ifndef linux + len = IFNAMSIZ + ifreq->ifr_addr.sa_len; +#else + len = sizeof *ifreq; +#endif + // only consider IPv4 interfaces + struct ifreq req; + memset(&req, 0, sizeof req); + strncpy(req.ifr_name, ifreq->ifr_name, IFNAMSIZ); + if (ioctl(fd, SIOCGIFADDR, &req) == 0 && + req.ifr_addr.sa_family == AF_INET) { + // get broadcast address for this interface + if (ioctl(fd, SIOCGIFBRDADDR, &req) == 0) { + char host[128]; + getnameinfo(&req.ifr_broadaddr, sizeof req.ifr_broadaddr, + host, sizeof host, 0, 0, NI_NUMERICHOST); + std::string bcast(host); + // exclude loopback broadcast and duplicates + if (bcast != "0.0.0.0" && bcast != "255.255.255.255" && + std::find(broadcasts.begin(), broadcasts.end(), bcast) == broadcasts.end()) + broadcasts.push_back(bcast); + } + } + ifreq = (struct ifreq *)((char *)ifreq + len); + i += len; + } + } + close(fd); + return broadcasts; +} bool NetworkToolkit::is_host_ip(const std::string &ip) { diff --git a/src/Toolkit/NetworkToolkit.h b/src/Toolkit/NetworkToolkit.h index 4ec1674..6bef30c 100644 --- a/src/Toolkit/NetworkToolkit.h +++ b/src/Toolkit/NetworkToolkit.h @@ -61,6 +61,7 @@ struct StreamConfig { std::string hostname(); std::vector host_ips(); +std::vector broadcast_ips(); bool is_host_ip(const std::string &ip); std::string closest_host_ip(const std::string &ip);