- 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.
		
			
				
	
	
		
			112 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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;
 | 
						|
}
 |