network-interface.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2021 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  *
21  * @author Davide Pesavento <davide.pesavento@lip6.fr>
22  */
23 
25 #include "ndn-cxx/net/impl/linux-if-constants.hpp"
26 #include "ndn-cxx/util/logger.hpp"
28 
29 #include <net/if.h>
30 
31 NDN_LOG_INIT(ndn.NetworkMonitor);
32 
33 namespace ndn {
34 namespace net {
35 
36 NetworkInterface::NetworkInterface()
37  : m_index(0)
38  , m_type(InterfaceType::UNKNOWN)
39  , m_flags(0)
40  , m_state(InterfaceState::UNKNOWN)
41  , m_mtu(0)
42 {
43 }
44 
45 bool
46 NetworkInterface::addNetworkAddress(const NetworkAddress& address)
47 {
48  if (!address.getIp().is_unspecified()) {
49  // need to erase the existing address before inserting
50  // because the address flags may have changed
51  bool isNew = m_netAddresses.erase(address) == 0;
52  m_netAddresses.insert(address);
53  if (isNew) {
54  NDN_LOG_DEBUG("added address " << address << " to " << m_name);
55  onAddressAdded(address);
56  return true;
57  }
58  }
59  return false;
60 }
61 
62 bool
63 NetworkInterface::removeNetworkAddress(const NetworkAddress& address)
64 {
65  if (m_netAddresses.erase(address) > 0) {
66  NDN_LOG_DEBUG("removed address " << address << " from " << m_name);
67  onAddressRemoved(address);
68  return true;
69  }
70  return false;
71 }
72 
73 void
74 NetworkInterface::setIndex(int index)
75 {
76  m_index = index;
77 }
78 
79 void
80 NetworkInterface::setName(const std::string& name)
81 {
82  BOOST_ASSERT(!name.empty());
83  m_name = name;
84 }
85 
86 void
87 NetworkInterface::setType(InterfaceType type)
88 {
89  m_type = type;
90 }
91 
92 void
93 NetworkInterface::setFlags(uint32_t flags)
94 {
95  m_flags = flags;
96 }
97 
98 void
99 NetworkInterface::setState(InterfaceState state)
100 {
101  if (m_state != state) {
102  std::swap(m_state, state);
103  onStateChanged(state, m_state);
104  }
105 }
106 
107 void
108 NetworkInterface::setMtu(uint32_t mtu)
109 {
110  if (m_mtu != mtu) {
111  std::swap(m_mtu, mtu);
112  onMtuChanged(mtu, m_mtu);
113  }
114 }
115 
116 void
117 NetworkInterface::setEthernetAddress(const ethernet::Address& address)
118 {
119  m_etherAddress = address;
120 }
121 
122 void
123 NetworkInterface::setEthernetBroadcastAddress(const ethernet::Address& address)
124 {
125  m_etherBrdAddress = address;
126 }
127 
128 std::ostream&
129 operator<<(std::ostream& os, InterfaceType type)
130 {
131  switch (type) {
132  case InterfaceType::UNKNOWN:
133  return os << "unknown";
134  case InterfaceType::LOOPBACK:
135  return os << "loopback";
136  case InterfaceType::ETHERNET:
137  return os << "ether";
138  }
139  return os;
140 }
141 
142 std::ostream&
143 operator<<(std::ostream& os, InterfaceState state)
144 {
145  switch (state) {
146  case InterfaceState::UNKNOWN:
147  return os << "unknown";
148  case InterfaceState::DOWN:
149  return os << "down";
150  case InterfaceState::NO_CARRIER:
151  return os << "no-carrier";
152  case InterfaceState::DORMANT:
153  return os << "dormant";
154  case InterfaceState::RUNNING:
155  return os << "running";
156  }
157  return os;
158 }
159 
160 static void
161 printFlag(std::ostream& os, uint32_t& flags, uint32_t flagVal, const char* flagStr)
162 {
163  if (flags & flagVal) {
164  flags &= ~flagVal;
165  os << flagStr << (flags ? "," : "");
166  }
167 }
168 
169 std::ostream&
170 operator<<(std::ostream& os, const NetworkInterface& netif)
171 {
172  os << netif.getIndex() << ": " << netif.getName() << ": ";
173 
174  auto flags = netif.getFlags();
175  os << "<";
176 #define PRINT_IFF(flag) printFlag(os, flags, IFF_##flag, #flag)
177  PRINT_IFF(UP);
178  PRINT_IFF(BROADCAST);
179  PRINT_IFF(DEBUG);
181  PRINT_IFF(POINTOPOINT);
182 #if defined(IFF_NOTRAILERS)
183  PRINT_IFF(NOTRAILERS);
184 #endif
186  PRINT_IFF(NOARP);
187  PRINT_IFF(PROMISC);
188  PRINT_IFF(ALLMULTI);
189  PRINT_IFF(MULTICAST);
190 #if defined(__linux__)
191  PRINT_IFF(MASTER);
192  PRINT_IFF(SLAVE);
193  PRINT_IFF(PORTSEL);
194  PRINT_IFF(AUTOMEDIA);
195  PRINT_IFF(DYNAMIC);
196 #elif defined(__APPLE__) || defined(__FreeBSD__)
197  PRINT_IFF(OACTIVE);
198  PRINT_IFF(SIMPLEX);
199  PRINT_IFF(LINK0);
200  PRINT_IFF(LINK1);
201  PRINT_IFF(LINK2);
202 #endif
203 #if defined(__FreeBSD__)
204  PRINT_IFF(CANTCONFIG);
205  PRINT_IFF(PPROMISC);
206  PRINT_IFF(MONITOR);
207  PRINT_IFF(STATICARP);
208  PRINT_IFF(DYING);
209  PRINT_IFF(RENAMING);
210 #endif
211 #undef PRINT_IFF
212 #if defined(__linux__)
213 #define PRINT_IF_FLAG(flag) printFlag(os, flags, linux_if::FLAG_##flag, #flag)
214  PRINT_IF_FLAG(LOWER_UP);
215  PRINT_IF_FLAG(DORMANT);
216  PRINT_IF_FLAG(ECHO);
217 #undef PRINT_IF_FLAG
218 #endif
219  if (flags) {
220  // print unknown flags in hex
221  os << AsHex{flags};
222  }
223  os << ">";
224 
225  os << " state " << netif.getState() << " mtu " << netif.getMtu() << "\n"
226  << " link/" << netif.getType() << " " << netif.getEthernetAddress()
227  << " brd " << netif.getEthernetBroadcastAddress() << "\n";
228 
229  for (const auto& addr : netif.getNetworkAddresses()) {
230  os << " " << (addr.getFamily() == AddressFamily::V4 ? "inet " : "inet6 ") << addr;
231  if (netif.canBroadcast() && !addr.getBroadcast().is_unspecified()) {
232  os << " brd " << addr.getBroadcast();
233  }
234  os << " scope " << addr.getScope();
235  if (addr.isDeprecated()) {
236  os << " deprecated";
237  }
238  os << "\n";
239  }
240 
241  return os;
242 }
243 
244 } // namespace net
245 } // namespace ndn
Helper class to convert a number to hexadecimal format, for use with stream insertion operators.
represents an Ethernet hardware address
Definition: ethernet.hpp:53
Stores one IP address supported by a network interface.
boost::asio::ip::address getIp() const
Returns the IP address (v4 or v6)
Represents one network interface attached to the host.
uint32_t getMtu() const
Returns the MTU (maximum transmission unit) of the interface.
const std::set< NetworkAddress > & getNetworkAddresses() const
Returns a list of all network-layer addresses present on the interface.
uint32_t getFlags() const
Returns a bitset of platform-specific flags enabled on the interface.
bool canBroadcast() const
Returns true if the interface supports broadcast communication.
InterfaceState getState() const
Returns the current state of the interface.
std::string getName() const
Returns the name of the interface, unique on the system.
ethernet::Address getEthernetAddress() const
Returns the link-layer (Ethernet) address of the interface.
ethernet::Address getEthernetBroadcastAddress() const
Returns the link-layer (Ethernet) broadcast address of the interface.
InterfaceType getType() const
Returns the hardware type of the interface.
int getIndex() const
Returns an opaque ID that uniquely identifies the interface on the system.
#define NDN_LOG_DEBUG(expression)
Log at DEBUG level.
Definition: logger.hpp:254
#define NDN_LOG_INIT(name)
Define a non-member log module.
Definition: logger.hpp:163
std::ostream & operator<<(std::ostream &os, const NetworkInterface &netif)
InterfaceType
Indicates the hardware type of a network interface.
InterfaceState
Indicates the state of a network interface.
@ RUNNING
interface can be used to send and receive packets
@ DORMANT
interface has a carrier but it cannot send or receive normal user traffic yet
Definition: data.cpp:25
#define PRINT_IFF(flag)