//
// 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 .
// MIT License
//
#include
#include
#include "log.hpp"
using namespace boost::asio;
using namespace boost::asio::ip;
std::pair 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 {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 {0, ""};
}
close(fd);
struct sockaddr_in* sockaddr =
reinterpret_cast(&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 {addr, str_addr};
}
std::pair, std::string> get_interface_mac(
const std::string& interface_name) {
std::array 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 {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 {mac, ""};
}
close(fd);
uint8_t* sa = reinterpret_cast(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 {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;
}