VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gaddress_ipv4.cpp
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gaddress_ipv4.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "gaddress.h"
24 #include "gaddress4.h"
25 #include <algorithm>
26 #include <cstring>
27 
28 namespace
29 {
30  void check( GNet::Address::Family f )
31  {
32  if( !GNet::Address::supports(f) )
33  throw GNet::Address::BadFamily() ;
34  }
35 }
36 
38 {
39  return f == Family::ipv4() ;
40 }
41 
43 {
44  return Address( Family::ipv4() , 0U ) ;
45 }
46 
47 GNet::Address::Address( Family f , unsigned int port ) :
48  m_4imp( new Address4(port) )
49 {
50  check( f ) ;
51 }
52 
54  m_4imp( new Address4(storage.p(),storage.n()) )
55 {
56 }
57 
58 GNet::Address::Address( const sockaddr * addr , socklen_t len ) :
59  m_4imp( new Address4(addr,len) )
60 {
61 }
62 
63 GNet::Address::Address( const std::string & s ) :
64  m_4imp( new Address4(s) )
65 {
66 }
67 
68 GNet::Address::Address( const std::string & s , unsigned int port ) :
69  m_4imp( new Address4(s,port) )
70 {
71 }
72 
73 GNet::Address::Address( const Address & other ) :
74  m_4imp( new Address4(*other.m_4imp) )
75 {
76 }
77 
78 GNet::Address::Address( Family f , unsigned int port , int loopback_overload ) :
79  m_4imp( new Address4(port,loopback_overload) )
80 {
81  check( f ) ;
82 }
83 
85 {
86  return Address( f , port , 1 ) ;
87 }
88 
89 void GNet::Address::operator=( const Address & addr )
90 {
91  Address temp( addr ) ;
92  std::swap( m_4imp , temp.m_4imp ) ;
93 }
94 
96 {
97  delete m_4imp ;
98 }
99 
100 void GNet::Address::setPort( unsigned int port )
101 {
102  m_4imp->setPort( port ) ;
103 }
104 
106 {
107  return m_4imp->isLoopback() ;
108 }
109 
110 bool GNet::Address::isLocal( std::string & reason ) const
111 {
112  return m_4imp->isLocal( reason ) ;
113 }
114 
115 bool GNet::Address::operator==( const Address & other ) const
116 {
117  return m_4imp->same(*other.m_4imp) ;
118 }
119 
120 bool GNet::Address::operator!=( const Address & other ) const
121 {
122  return !( *this == other ) ;
123 }
124 
125 bool GNet::Address::sameHostPart( const Address & other ) const
126 {
127  return m_4imp->sameHostPart(*other.m_4imp) ;
128 }
129 
130 std::string GNet::Address::displayString() const
131 {
132  return m_4imp->displayString() ;
133 }
134 
135 std::string GNet::Address::hostPartString() const
136 {
137  return m_4imp->hostPartString() ;
138 }
139 
140 bool GNet::Address::validString( const std::string & s , std::string * reason_p )
141 {
142  return Address4::validString( s , reason_p ) ;
143 }
144 
145 bool GNet::Address::validStrings( const std::string & s1 , const std::string & s2 , std::string * reason_p )
146 {
147  return Address4::validStrings( s1 , s2 , reason_p ) ;
148 }
149 
151 {
152  return m_4imp->address() ;
153 }
154 
155 const sockaddr * GNet::Address::address() const
156 {
157  return m_4imp->address() ;
158 }
159 
160 socklen_t GNet::Address::length() const
161 {
162  return Address4::length() ;
163 }
164 
165 unsigned int GNet::Address::port() const
166 {
167  return m_4imp->port() ;
168 }
169 
170 unsigned long GNet::Address::scopeId( unsigned long default_ ) const
171 {
172  return default_ ;
173 }
174 
175 bool GNet::Address::validPort( unsigned int port )
176 {
177  return Address4::validPort( port ) ;
178 }
179 
180 bool GNet::Address::validData( const sockaddr * addr , socklen_t len )
181 {
182  return Address4::validData( addr , len ) ;
183 }
184 
186 {
187  return Address4::domain() ;
188 }
189 
191 {
192  return Family::ipv4() ;
193 }
194 
196 {
197  return m_4imp->wildcards() ;
198 }
199 
200 // ==
201 
202 /// \class GNet::AddressStorageImp
203 /// A pimple-pattern implementation class used by GNet::AddressStorage.
204 ///
206 {
207 public:
209  socklen_t n ;
210 } ;
211 
212 // ==
213 
215  m_imp(new AddressStorageImp)
216 {
217  m_imp->n = sizeof(Address4::union_type) ;
218 }
219 
221 {
222  delete m_imp ;
223 }
224 
226 {
227  return &(m_imp->u.general) ;
228 }
229 
231 {
232  return &m_imp->n ;
233 }
234 
235 const sockaddr * GNet::AddressStorage::p() const
236 {
237  return &m_imp->u.general ;
238 }
239 
240 socklen_t GNet::AddressStorage::n() const
241 {
242  return m_imp->n ;
243 }
244 
245 // ==
246 
247 #if ! GCONFIG_HAVE_INET_PTON
248 // fallback implementation for inet_pton() -- see gdef.h
249 int GNet::inet_pton_imp( int f , const char * p , void * result )
250 {
251  if( p == nullptr || result == nullptr )
252  {
253  return 0 ; // just in case
254  }
255  else if( f == AF_INET )
256  {
257  static sockaddr_in sa_zero ;
258  sockaddr_in sa = sa_zero ;
259  sa.sin_family = AF_INET ;
260  sa.sin_addr.s_addr = inet_addr( p ) ;
261  *reinterpret_cast<struct in_addr*>(result) = sa.sin_addr ;
262  return 1 ;
263  }
264  else
265  {
266  return -1 ;
267  }
268 }
269 #endif
270 
271 #if ! GCONFIG_HAVE_INET_NTOP
272 // fallback implementation for inet_ntop() -- see gdef.h
273 const char * GNet::inet_ntop_imp( int f , void * ap , char * buffer , size_t n )
274 {
275  if( f == AF_INET )
276  {
277  std::ostringstream ss ;
278  struct in_addr a = *reinterpret_cast<struct in_addr*>(ap) ;
279  ss << inet_ntoa( a ) ; // ignore warnings - this is not used if inet_ntop is available
280  if( n <= ss.str().length() ) return nullptr ;
281  std::strncpy( buffer , ss.str().c_str() , n ) ;
282  return buffer ;
283  }
284  else
285  {
286  return nullptr ;
287  }
288 }
289 #endif
290 
static Address loopback(Family, unsigned int port=0U)
Returns a loopback address.
Used by GNet::Address4 to cast between sockaddr and sockaddr_in.
Definition: gaddress4.h:44
Family family() const
Returns the address family.
static bool validData(const sockaddr *, socklen_t len)
Returns true if the sockaddr data is valid.
and hiding the definition of sockaddr_storage.
Definition: gaddress.h:200
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:55
bool isLoopback() const
Returns true if this is a loopback address.
static bool validStrings(const std::string &ip, const std::string &port_string, std::string *reason=nullptr)
Returns true if the combined ip address string and port string is valid.
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into.
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into.
A pimple-pattern implementation class used by GNet::AddressStorage.
const sockaddr * address() const
Returns the sockaddr address.
bool sameHostPart(const Address &other) const
Returns true if the two addresses have the same host part (ie.
unsigned int port() const
Returns port part of the address.
bool operator==(const Address &) const
Comparison operator.
const sockaddr * p() const
Returns the pointer.
A 'sockaddr' wrapper class for IPv4 addresses.
Definition: gaddress4.h:38
AddressStorage()
Default constructor.
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
G::StringArray wildcards() const
Returns an ordered list of wildcard strings that match this address.
socklen_t length() const
Returns the size of the sockaddr address. See address().
std::string hostPartString() const
Returns a string which represents the network address for debugging and diagnostics purposes...
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
static bool validString(const std::string &display_string, std::string *reason=nullptr)
Returns true if the display string is valid.
int domain() const
Returns the address 'domain', eg. PF_INET.
~Address()
Destructor.
~AddressStorage()
Destructor.
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
A type-safe enumerator for IP address family.
Definition: gaddress.h:58
bool isLocal(std::string &reason) const
Returns true if this seems to be a local address.
void operator=(const Address &addr)
Assignment operator.
Address(const Address &)
Copy constructor.
This file is formatted for side-by-side comparison with gaddress6.h.
void setPort(unsigned int port)
Sets the port number.
socklen_t n() const
Returns the length.
static bool supports(Family)
Returns true if the implementation supports the given address family.
bool operator!=(const Address &) const
Comparison operator.
std::string displayString() const
Returns a string which represents the transport address for debugging and diagnostics purposes...