INet4Address.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "INet4Address.hh"
18 //#include "INet4Address.ih"
19 
20 // Custom includes
21 #include <arpa/inet.h>
22 #include <netdb.h>
23 #include <sys/socket.h>
24 #include <boost/lexical_cast.hpp>
25 #if defined(_REENTRANT) && !defined(__GLIBC__)
26 #include <boost/thread/mutex.hpp>
27 #endif
28 
29 //#include "INet4Address.mpp"
30 #define prefix_
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34 // senf::INet4Address::INet4Address
35 
37 {
38  iref() = htonl(value);
39 }
40 
42 {
43  struct in_addr ina;
44  if (::inet_pton(AF_INET,s.c_str(),&ina) > 0)
45  return INet4Address::from_inaddr(ina.s_addr);
46 
47  if (s.empty())
48  throw AddressSyntaxException() << ": empty string";
49 
50  // If available, we use the reentrant GNU variant. This has the additional advantage, that we
51  // can explicitly ask for IPv4 addresses
52 
53 # ifdef __GLIBC__
54 
55  struct hostent entbuf;
56  char buffer[4096];
57  struct hostent * ent (0);
58  int herr (0);
59  ::gethostbyname2_r(s.c_str(), AF_INET, &entbuf, buffer, sizeof(buffer), &ent, &herr);
60 
61 # else // ! __GLIBC__
62 
63 # ifdef _REENTRANT
64  static boost::mutex mutex;
65  boost::mutex::scoped_lock lock(mutex);
66 # endif
67  struct hostent * ent (::gethostbyname(s.c_str()));
68 # endif // __GLIBC__
69 
70  if (!ent)
71  throw UnknownHostnameException(s);
72  if (ent->h_addrtype != AF_INET)
73  throw UnknownHostnameException(s);
74 
75  // We are only interested in the first address ...
77  reinterpret_cast<in_addr*>(*(ent->h_addr_list))->s_addr);
78 }
79 
81  const
82 {
83  address_type l (address());
84  return
85  (l & 0xFF000000u) == 0x0A000000u ||
86  (l & 0xFFF00000u) == 0xAC100000u ||
87  (l & 0xFFFF0000u) == 0xA9FE0000u ||
88  (l & 0xFFFF0000u) == 0xC0A80000u;
89 }
90 
92  const
93 {
94  return (address() & 0xFF000000u) == 0x7F000000u;
95 }
96 
98  const
99 {
100  return (address() & 0xF0000000u) == 0xE0000000u;
101 }
102 
104  const
105 {
106  return ntohl(iref());
107 }
108 
112 
113 //-/////////////////////////////////////////////////////////////////////////////////////////////////
114 // senf::INet4Network
115 
117 {
118  std::string::size_type i (s.find('/'));
119  if (i == std::string::npos)
120  throw AddressSyntaxException(s);
121  try {
122  prefix_len_ = prefix_len_checked(boost::lexical_cast<unsigned>(std::string(s,i+1)));
123  } catch (boost::bad_lexical_cast const &) {
124  throw AddressSyntaxException(s);
125  }
126  address_ = INet4Address(INet4Address::from_string(std::string(s, 0, i)).address() & mask());
127 }
128 
129 //-/////////////////////////////////////////////////////////////////////////////////////////////////
130 // namespace members
131 
132 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & addr)
133 {
134  ::in_addr ina;
135  char buffer[16];
136  ina.s_addr = addr.inaddr();
137  ::inet_ntop(AF_INET,&ina,buffer,16);
138  buffer[15] = 0;
139  os << buffer;
140  return os;
141 }
142 
143 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
144 {
145  std::string s;
146  if (!(is >> s))
147  return is;
148  try {
149  addr = INet4Address::from_string(s);
150  }
151  catch (AddressException &) {
152  is.setstate(std::ios::failbit);
153  }
154  return is;
155 }
156 
157 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Network & addr)
158 {
159  std::string s;
160  if (!(is >> s))
161  return is;
162  try {
163  addr = INet4Network(s);
164  }
165  catch (AddressException &) {
166  is.setstate(std::ios::failbit);
167  }
168  return is;
169 }
170 
171 //-/////////////////////////////////////////////////////////////////////////////////////////////////
172 #undef prefix_
173 //#include "INet4Address.mpp"
174 
175 
176 // Local Variables:
177 // mode: c++
178 // fill-column: 100
179 // comment-column: 40
180 // c-file-style: "senf"
181 // indent-tabs-mode: nil
182 // ispell-local-dictionary: "american"
183 // compile-command: "scons -u test"
184 // End:
static INet4Address const Broadcast
Definition: INet4Address.hh:91
address_type address() const
Return address represented as integer number.
bool local() const
true, if address is locally administered
Definition: INet4Address.cc:80
std::ostream & operator<<(std::ostream &os, Packet const &packet)
__u32 mask
std::istream & operator>>(std::istream &is, INet4SocketAddress &addr)
static INet4Address const None
The empty (0) address.
Definition: INet4Address.hh:89
INet4Address public header.
static INet4Address from_inaddr(inaddr_type v)
Construct address from integer in network byte order.
bool multicast() const
true, if address is a multicast address
Definition: INet4Address.cc:97
static INet4Address from_string(std::string const &s)
Convert string to address.
Definition: INet4Address.cc:41
#define prefix_
Definition: INet4Address.cc:30
bool loopback() const
true, if address is within the loopback network
Definition: INet4Address.cc:91
uint32_t address_type
Address representation as number in host byte order.
Definition: INet4Address.hh:86
inaddr_type inaddr() const
Return the raw network byte order address.
static INet4Address const Loopback
The loopback (127.0.0.1) address.
Definition: INet4Address.hh:90
IPv4 Internet address.
Definition: INet4Address.hh:78
IPv4 network prefix.
Base-class for Address exceptions.
INet4Address()
Construct an empty address.
Invalid address syntax.
INet4Network()
Construct empty (0.0.0.0/0) network.