31 #include <sys/types.h>
53 AddressImp(
const hostent & h ,
const servent & s ) ;
54 AddressImp(
const sockaddr * addr ,
size_t len ) ;
57 const sockaddr *
raw()
const ;
60 unsigned int port()
const ;
63 static bool validString(
const std::string & s , std::string * reason_p = NULL ) ;
75 static unsigned short family() ;
76 void set(
const sockaddr * general ) ;
77 bool setAddress(
const std::string & display_string , std::string & reason ) ;
78 static bool validPart(
const std::string & s ) ;
79 static bool validPortNumber(
const std::string & s ) ;
80 static bool validNumber(
const std::string & s ) ;
81 void setHost(
const hostent & h ) ;
82 static bool sameAddr( const ::in_addr & a , const ::in_addr & b ) ;
83 static char portSeparator() ;
84 static void add(
G::Strings & ,
const std::string & ,
unsigned int ,
const char * ) ;
85 static void add(
G::Strings & ,
const std::string & ,
const char * ) ;
105 unsigned short GNet::AddressImp::family()
110 void GNet::AddressImp::init()
112 static address_type zero ;
113 m_inet.specific = zero ;
114 m_inet.specific.sin_family = family() ;
115 m_inet.specific.sin_port = 0 ;
121 m_inet.specific.sin_addr.s_addr = htonl(INADDR_ANY);
128 m_inet.specific.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
135 m_inet.specific.sin_addr.s_addr = htonl(INADDR_BROADCAST);
150 m_inet.specific.sin_port = s.s_port ;
156 m_inet.specific.sin_addr.s_addr = htonl(INADDR_ANY);
157 m_inet.specific.sin_port = s.s_port ;
165 throw Address::Error() ;
167 if( addr->sa_family != family() || len !=
sizeof(
address_type) )
168 throw Address::BadFamily() ;
175 m_inet = other.m_inet ;
183 if( ! setAddress( s + portSeparator() +
"0" , reason ) )
184 throw Address::BadString( reason +
": " + s ) ;
194 if( ! setAddress( s , reason ) )
195 throw Address::BadString( reason +
": " + s ) ;
198 bool GNet::AddressImp::setAddress(
const std::string & display_string , std::string & reason )
200 if( !validString(display_string,&reason) )
204 std::string host_part = display_string.substr(0U,pos) ;
205 std::string port_part = display_string.substr(pos+1U) ;
207 m_inet.specific.sin_family = family() ;
208 m_inet.specific.sin_addr.s_addr = ::inet_addr( host_part.c_str() ) ;
211 G_ASSERT( displayString() == display_string ) ;
217 if( ! validPort(port) )
218 throw Address::Error(
"invalid port number" ) ;
220 const g_port_t in_port =
static_cast<g_port_t
>(port) ;
221 m_inet.specific.sin_port = htons( in_port ) ;
224 void GNet::AddressImp::setHost(
const hostent & h )
226 if( h.h_addrtype != family() || h.h_addr_list[0] == NULL )
227 throw Address::BadFamily() ;
229 const char * first = h.h_addr_list[0U] ;
230 const in_addr * raw =
reinterpret_cast<const in_addr*
>(first) ;
231 m_inet.specific.sin_addr = *raw ;
236 std::ostringstream ss ;
238 ss << portSeparator() << port() ;
244 std::ostringstream ss ;
245 ss << ::inet_ntoa(m_inet.specific.sin_addr) ;
251 return port <= 0xFFFFU ;
257 if( reason_p == NULL ) reason_p = &buffer ;
258 std::string & reason = *reason_p ;
261 if( pos == std::string::npos )
263 reason =
"no port separator" ;
267 std::string port_part = s.substr(pos+1U) ;
268 if( !validPortNumber(port_part) )
270 reason = std::string() +
"invalid port number: [" + port_part +
"]" ;
274 std::string host_part = s.substr(0U,pos) ;
283 if( parts.size() != 4U )
285 reason =
"invalid number of dotted parts" ;
289 G::Strings::iterator p = parts.begin() ;
290 reason =
"invalid dotted part" ;
291 if( ! validPart(*p) )
return false ; p++ ;
292 if( ! validPart(*p) )
return false ; p++ ;
293 if( ! validPart(*p) )
return false ; p++ ;
294 if( ! validPart(*p) )
return false ;
300 bool GNet::AddressImp::validPortNumber(
const std::string & s )
305 bool GNet::AddressImp::validNumber(
const std::string & s )
310 bool GNet::AddressImp::validPart(
const std::string & s )
318 m_inet.specific.sin_family == other.m_inet.
specific.sin_family &&
319 m_inet.specific.sin_family == family() &&
320 sameAddr( m_inet.specific.sin_addr , other.m_inet.
specific.sin_addr ) &&
321 m_inet.specific.sin_port == other.m_inet.
specific.sin_port ;
327 m_inet.specific.sin_family == other.m_inet.
specific.sin_family &&
328 m_inet.specific.sin_family == family() &&
329 sameAddr( m_inet.specific.sin_addr , other.m_inet.
specific.sin_addr ) ;
332 bool GNet::AddressImp::sameAddr( const ::in_addr & a , const ::in_addr & b )
334 return a.s_addr == b.s_addr ;
339 return ntohs( m_inet.specific.sin_port ) ;
344 return & m_inet.general ;
349 return & m_inet.general ;
352 void GNet::AddressImp::set(
const sockaddr * general )
354 m_inet.general = *general ;
357 char GNet::AddressImp::portSeparator()
365 result.push_back( display_string ) ;
371 if( part.size() != 4U ||
385 std::string part_0_1_2 = part[0] ;
386 part_0_1_2.append( 1U ,
'.' ) ;
387 part_0_1_2.append( part[1] ) ;
388 part_0_1_2.append( 1U ,
'.' ) ;
389 part_0_1_2.append( part[2] ) ;
390 part_0_1_2.append( 1U ,
'.' ) ;
392 std::string part_0_1 = part[0] ;
393 part_0_1.append( 1U ,
'.' ) ;
394 part_0_1.append( part[1] ) ;
395 part_0_1.append( 1U ,
'.' ) ;
397 std::string part_0 = part[0] ;
398 part_0.append( 1U ,
'.' ) ;
400 const std::string empty ;
402 add( result , part_0_1_2 , n3 & 0xff ,
"/32" ) ;
403 add( result , part_0_1_2 , n3 & 0xfe ,
"/31" ) ;
404 add( result , part_0_1_2 , n3 & 0xfc ,
"/30" ) ;
405 add( result , part_0_1_2 , n3 & 0xf8 ,
"/29" ) ;
406 add( result , part_0_1_2 , n3 & 0xf0 ,
"/28" ) ;
407 add( result , part_0_1_2 , n3 & 0xe0 ,
"/27" ) ;
408 add( result , part_0_1_2 , n3 & 0xc0 ,
"/26" ) ;
409 add( result , part_0_1_2 , n3 & 0x80 ,
"/25" ) ;
410 add( result , part_0_1_2 , 0 ,
"/24" ) ;
411 add( result , part_0_1_2 ,
"*" ) ;
412 add( result , part_0_1 , n2 & 0xfe ,
".0/23" ) ;
413 add( result , part_0_1 , n2 & 0xfc ,
".0/22" ) ;
414 add( result , part_0_1 , n2 & 0xfc ,
".0/21" ) ;
415 add( result , part_0_1 , n2 & 0xf8 ,
".0/20" ) ;
416 add( result , part_0_1 , n2 & 0xf0 ,
".0/19" ) ;
417 add( result , part_0_1 , n2 & 0xe0 ,
".0/18" ) ;
418 add( result , part_0_1 , n2 & 0xc0 ,
".0/17" ) ;
419 add( result , part_0_1 , 0 ,
".0/16" ) ;
420 add( result , part_0_1 ,
"*.*" ) ;
421 add( result , part_0 , n1 & 0xfe ,
".0.0/15" ) ;
422 add( result , part_0 , n1 & 0xfc ,
".0.0/14" ) ;
423 add( result , part_0 , n1 & 0xf8 ,
".0.0/13" ) ;
424 add( result , part_0 , n1 & 0xf0 ,
".0.0/12" ) ;
425 add( result , part_0 , n1 & 0xe0 ,
".0.0/11" ) ;
426 add( result , part_0 , n1 & 0xc0 ,
".0.0/10" ) ;
427 add( result , part_0 , n1 & 0x80 ,
".0.0/9" ) ;
428 add( result , part_0 , 0 ,
".0.0/8" ) ;
429 add( result , part_0 ,
"*.*.*" ) ;
430 add( result , empty , n0 & 0xfe ,
".0.0.0/7" ) ;
431 add( result , empty , n0 & 0xfc ,
".0.0.0/6" ) ;
432 add( result , empty , n0 & 0xf8 ,
".0.0.0/5" ) ;
433 add( result , empty , n0 & 0xf0 ,
".0.0.0/4" ) ;
434 add( result , empty , n0 & 0xe0 ,
".0.0.0/3" ) ;
435 add( result , empty , n0 & 0xc0 ,
".0.0.0/2" ) ;
436 add( result , empty , n0 & 0x80 ,
".0.0.0/1" ) ;
437 add( result , empty , 0 ,
".0.0.0/0" ) ;
438 add( result , empty ,
"*.*.*.*" ) ;
443 void GNet::AddressImp::add(
G::Strings & result ,
const std::string & head ,
unsigned int n ,
const char * tail )
445 std::string s = head ;
448 result.push_back( s ) ;
451 void GNet::AddressImp::add(
G::Strings & result ,
const std::string & head ,
const char * tail )
453 result.push_back( head + tail ) ;
504 m_imp( new
AddressImp(storage.p(),storage.n()) )
531 std::swap( m_imp , temp.m_imp ) ;
541 m_imp->setPort( port ) ;
546 return m_imp->same(*other.m_imp) ;
551 if( sameHost(localhost()) )
554 std::ostringstream ss ;
555 ss << displayString(
false) <<
" is not " << localhost().displayString(
false) ;
563 if( sameHost(localhost()) || sameHost(local_hint) )
566 std::ostringstream ss ;
568 << displayString(
false) <<
" is not one of "
569 << localhost().displayString(
false) <<
","
578 return m_imp->sameHost(*other.m_imp) ;
583 return with_port ? m_imp->displayString() : m_imp->hostString() ;
588 return m_imp->hostString() ;
598 return m_imp->raw() ;
603 return m_imp->raw() ;
613 return m_imp->port() ;
633 return defaultDomain() ;
656 return &(m_imp->u.general) ;
666 return &m_imp->u.general ;
G::Strings wildcards() const
Returns an ordered list of wildcard strings that match this address.
A pimple-pattern implementation class for GNet::Address.
static Address broadcastAddress(unsigned int port)
Returns a broadcast address.
std::string displayString() const
static int defaultDomain()
Returns the default address 'domain', eg. PF_INET.
void setPort(unsigned int port)
static Address localhost(unsigned int port=0U)
Returns a localhost ("loopback") address.
static unsigned int toUInt(const std::string &s, bool limited=false)
Converts string 's' to an unsigned int.
std::list< std::string > Strings
A std::list of std::strings.
static void splitIntoFields(const std::string &in, Strings &out, const std::string &seperators, char escape= '\0', bool discard_bogus_escapes=true)
Splits the string into fields.
A helper class for calling getsockname() and getpeername() and hiding the definition of sockaddr_stor...
The Address class encapsulates an IP transport address.
std::vector< std::string > StringArray
A std::vector of std::strings.
socklen_t * p2()
Returns the length pointer for getsockname()/getpeername() to write into.
std::string::size_type size_type
A std::size_t type.
sockaddr * p1()
Returns the sockaddr pointer for getsockname()/getpeername() to write into.
static Address invalidAddress()
Returns an invalid address.
static bool isNumeric(const std::string &s, bool allow_minus_sign=false)
Returns true if every character is a decimal digit.
A pimple-pattern implementation class for GNet::AddressStorage.
const sockaddr * address() const
Returns the sockaddr address.
std::string hostString() const
Returns a string which represents the host part of the address for debugging and diagnostics purposes...
unsigned int port() const
Returns port part of address.
bool operator==(const Address &) const
Comparison operator.
std::string hostString() const
const sockaddr * p() const
Returns the pointer.
AddressImp(unsigned int port)
Address(const Address &addr)
Copy constructor.
static G::Strings wildcards(const std::string &display_string)
static std::string fromUInt(unsigned int ui)
Converts unsigned int 'ui' to a string.
AddressStorage()
Default constructor.
std::string displayString(bool with_port=true, bool with_scope_id=false) const
Returns a string which represents the address for debugging and diagnostics purposes.
Used by GNet::AddressImp to cast between sockaddr and sockaddr_in.
static bool validPort(unsigned int port)
socklen_t length() const
Returns the size of the sockaddr address.
bool sameHost(const AddressImp &other) const
bool sameHost(const Address &other) const
Returns true if the two addresses have the same host part (ie.
unsigned long scopeId(unsigned long default_=0UL) const
Returns the scope-id.
int domain() const
Returns the address 'domain', eg. PF_INET.
~AddressStorage()
Destructor.
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
bool isLocal(std::string &reason) const
Returns true if the address is definitely local.
static bool validString(const std::string &s, std::string *reason_p=NULL)
bool same(const AddressImp &other) const
An overload discriminator class for GNet::Address.
An overload discriminator class for GNet::Address.
void operator=(const Address &addr)
Assignment operator.
static bool validString(const std::string &display_string, std::string *reason=NULL)
Returns true if the display string is valid.
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
void setPort(unsigned int port)
Sets the port number.
socklen_t n() const
Returns the length.
const sockaddr * raw() const
unsigned int port() const