38 #include <sys/socket.h>
41 #include <sys/ioctl.h>
42 #include <linux/if_packet.h>
45 #include <sys/types.h>
55 using namespace scc::net;
59 std::vector<InetAddr> ret_vect;
61 addrinfo* ai =
nullptr;
63 memset(&hints, 0,
sizeof(addrinfo));
64 hints.ai_family = AF_INET6;
66 if (type == NetIf::SocketType::tcp_stream) hints.ai_socktype |= SOCK_STREAM;
67 if (type == NetIf::SocketType::udp_datagram) hints.ai_socktype |= SOCK_DGRAM;
69 hints.ai_flags = AI_V4MAPPED|AI_ADDRCONFIG;
71 int res = getaddrinfo(
name.c_str(),
nullptr, &hints, &ai);
82 ret_vect.emplace_back(cur->ai_addr);
102 return os.write(nad.
str().c_str(), nad.
str().size());
107 std::map<int, NetIf> xref;
113 ret = getifaddrs(&ifs);
115 while (ret == -1 && errno == EINTR);
119 throw std::system_error(errno, std::system_category(),
"getifaddrs()");
122 for (ifaddrs* ad = ifs; ad !=
nullptr; ad = ad->ifa_next)
124 sockaddr* sa = ad->ifa_addr;
128 if (sa->sa_family == AF_PACKET)
131 sockaddr_ll* x = (sockaddr_ll*)sa;
132 std::stringstream hwad;
133 for (
int i = 0; i < 6; i++)
135 hwad << std::setw(2) << std::setfill(
'0') << std::hex;
136 hwad << (int)x->sll_addr[i];
137 hwad << std::setw(0) << std::setfill(
' ') << std::dec;
142 NetIf nif(ad->ifa_name, hwad.str(), ad->ifa_flags);
143 xref[nif.
index()] = std::move(nif);
145 else if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
150 idx = if_nametoindex(ad->ifa_name);
152 while (idx == 0 && errno == EINTR);
154 assert(xref.find(idx) != xref.end());
158 xref[idx].m_addrs.push_back(na);
164 std::vector<NetIf> if_ret;
169 if_ret.push_back(std::move(i.second));
175 int NetIf::parse_flags(
unsigned flags)
196 NetIf::NetIf(
const std::string& name,
const std::string& hwaddr,
int flags)
197 : m_name(
name), m_hwaddr(hwaddr), m_index(find_index(
name)), m_speed(0), m_mtu(0), m_flags(parse_flags(flags))
201 std::string b(
"/sys/class/net/");
202 auto f = std::fstream(b+m_name+
"/mtu", std::ios_base::in);
207 f = std::fstream(b+m_name+
"/speed", std::ios_base::in);
216 int NetIf::find_index(
const std::string& name)
219 int sock = ::socket(AF_ROUTE, SOCK_RAW, 0);
224 strcpy(ifr.ifr_name,
name.c_str());
228 ret = ::ioctl(sock, SIOCGIFINDEX, &ifr);
230 while (ret == -1 && errno == EINTR);
232 return ifr.ifr_ifindex;
240 s <<
index() <<
" " <<
name() <<
" hwaddr: " <<
hw_addr() <<
" speed: " <<
speed() <<
" mtu: " <<
mtu() << std::endl;
243 if ((m_flags&
if_up)==
if_up) { s <<
"up"; sp =
true; }
250 if ((m_flags&
if_noarp)==
if_noarp) {
if (sp) s <<
" "; s <<
"noarp"; sp =
true; }
253 if ((m_flags&
if_echo)==
if_echo) {
if (sp) s <<
" "; s <<
"echo"; }
255 for (
auto& ad : m_addrs)
264 return os.write(nif.
str().c_str(), nif.
str().size());
virtual std::string str() const
Readable address string.
Named address within an interface.
std::string str() const
String representation of a network interface address.
const std::string & hw_addr() const
Hardware address for the interface.
const int index() const
The interface index.
std::string str() const
String representation of network interface.
const size_t speed() const
Link speed in bytes / second, 0 means loopback.
const size_t mtu() const
Maximum transmission unit.
static std::vector< NetIf > all_interfaces()
List network interfaces on the local system.
static std::vector< InetAddr > host_addrs(const std::string &name, SocketType=SocketType::any)
List addresses for the specified host (do a name lookup).
int flags() const
Flags for this interface.
const std::string & name() const
Name of the interface.
@ if_loopback
Interface is a loopback interface.
@ if_broadcast
Valid broadcast address set.
@ if_multicast
Supports multicast.
@ if_running
Resources allocated.
@ if_noarp
No arp protocol, L2 destination address not set.
@ if_dynamic
The addresses are lost when the interface goes down.
@ if_up
Interface is running.
@ if_pointtopoint
Interface is a point-to-point link.
@ if_allmulti
Receives all multicast packets.
@ if_promisc
Interface is in promiscuous mode.
@ if_echo
Echoes sent packets.
Internet tcp and udp networking.
std::ostream & operator<<(std::ostream &, const scc::net::InetAddr &)
Print the socket address details to an output stream.
Internet network interface utility.