aes67-daemon/daemon/interface.cpp
Andrea Bondavalli 0f8b9e714e Revised Avahi client integration in mDNS client:
- aligned state handling with avahi-browse tool: browser is started in client callback
- browsing is limited to IPv4 services discovered on the specific daemon network interface only
Additional minor changes.
2020-04-03 09:55:01 -07:00

112 lines
3.6 KiB
C++

//
// interface.cpp
//
// Copyright (c) 2019 2020 Andrea Bondavalli. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// MIT License
//
#include <utility>
#include <boost/asio.hpp>
#include "log.hpp"
using namespace boost::asio;
using namespace boost::asio::ip;
std::pair<uint32_t, std::string> get_interface_ip(
const std::string& interface_name) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve IP address for interface " << interface_name;
return std::make_pair(0, "");
}
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, interface_name.c_str(), IFNAMSIZ - 1);
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
close(fd);
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve IP address for interface " << interface_name;
return std::make_pair(0, "");
}
close(fd);
struct sockaddr_in* sockaddr =
reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr);
uint32_t addr = ntohl(sockaddr->sin_addr.s_addr);
std::string str_addr(ip::address_v4(addr).to_string());
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
<< " IP address " << str_addr;*/
return std::make_pair(addr, str_addr);
}
std::pair<std::array<uint8_t, 6>, std::string> get_interface_mac(
const std::string& interface_name) {
std::array<uint8_t, 6> mac{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve MAC address for interface " << interface_name;
return std::make_pair(mac, "");
}
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, interface_name.c_str(), IFNAMSIZ - 1);
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
close(fd);
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve MAC address for interface " << interface_name;
return std::make_pair(mac, "");
}
close(fd);
uint8_t* sa = reinterpret_cast<uint8_t*>(ifr.ifr_hwaddr.sa_data);
std::copy(sa, sa + 8, std::begin(mac));
char str_mac[18];
sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
<< " MAC address " << str_mac;*/
return std::make_pair(mac, str_mac);
}
int get_interface_index(const std::string& interface_name) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve index for interface " << interface_name;
return -1;
}
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, interface_name.c_str(), IFNAMSIZ - 1);
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
close(fd);
BOOST_LOG_TRIVIAL(error)
<< "Cannot retrieve index for interface " << interface_name;
return -1;
}
close(fd);
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
<< " index " << ifr.ifr_ifindex;*/
return ifr.ifr_ifindex;
}