X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FINetAddressing.cc;h=2fbbd7e70297e18a32f60ad3a204e7f4ceb3078b;hb=9a988902090d28007578e93bffd809f6bd913155;hp=013704d73bc2dc2e53dd71ab981eea2ad20b774f;hpb=9ff0a749115d3424608d7b077037258481c0086c;p=senf.git diff --git a/Socket/INetAddressing.cc b/Socket/INetAddressing.cc index 013704d..2fbbd7e 100644 --- a/Socket/INetAddressing.cc +++ b/Socket/INetAddressing.cc @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2006 +// Copyright (C) 2006 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) // Kompetenzzentrum fuer Satelitenkommunikation (SatCom) // Stefan Bund @@ -20,7 +20,9 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Definition of non-inline non-template functions +/** \file + \brief INet[46]Address and INet[46]AddressingPolicy non-inline non-template implementation + */ #include "INetAddressing.hh" //#include "INetAddressing.ih" @@ -29,22 +31,28 @@ #include #include #include +#include #include +#include +#include //#include "INetAddressing.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ satcom::lib::INet4Address::INet4Address(std::string host, unsigned port) +/////////////////////////////////////////////////////////////////////////// +// senf::INet4Address + +prefix_ senf::INet4Address::INet4Address(std::string host, unsigned port) { clear(); - // TODO: gethostbyname einbauen + /** \todo gethostbyname support */ if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0) throw InvalidINetAddressException(); addr_.sin_port = htons(port); } -prefix_ std::string satcom::lib::INet4Address::str() +prefix_ std::string senf::INet4Address::str() const { std::stringstream s; @@ -52,27 +60,163 @@ prefix_ std::string satcom::lib::INet4Address::str() return s.str(); } -prefix_ void satcom::lib::INet4Address::clear() +prefix_ void senf::INet4Address::clear() { ::memset(&addr_,0,sizeof(addr_)); addr_.sin_family = AF_INET; } -prefix_ void satcom::lib::INet4Address::assignString(std::string address) +prefix_ void senf::INet4Address::assignString(std::string address) { clear(); - // TODO: gethostbyname einbauen unsigned i = address.find(':'); if (i == std::string::npos) throw InvalidINetAddressException(); + // The temporary string in the next expr is guaranteed to live + // until end-of-statement if (::inet_aton(std::string(address,0,i).c_str(), &addr_.sin_addr) == 0) throw InvalidINetAddressException(); try { // Replace lexical_cast with strtoul ? addr_.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1))); - } - catch (boost::bad_lexical_cast const & ex) { + } + catch (boost::bad_lexical_cast const &) { + throw InvalidINetAddressException(); + } +} + +/////////////////////////////////////////////////////////////////////////// +// senf::INet6Address + +prefix_ senf::INet6Address::INet6Address(std::string const & addr) +{ + if (inet_pton(AF_INET6,addr.c_str(),&addr_) <= 0) throw InvalidINetAddressException(); +} + +prefix_ senf::INet6Address::INet6Address(char const * addr) +{ + if (inet_pton(AF_INET6,addr,&addr_) <= 0) + throw InvalidINetAddressException(); +} + +prefix_ void senf::INet6Address::clear() +{ + ::memset(&addr_,0,sizeof(addr_)); +} + +prefix_ std::string senf::INet6Address::address() + const +{ + char buffer[8*5]; + BOOST_ASSERT( inet_ntop(AF_INET6, &addr_, buffer, sizeof(buffer)) ); + return std::string(buffer); +} + +prefix_ bool senf::INet6Address::operator==(INet6Address const & other) + const +{ + return ::memcmp(&addr_,&other.addr_,sizeof(addr_))==0; +} + +prefix_ bool senf::INet6Address::operator!=(INet6Address const & other) + const +{ + return !operator==(other); +} + +/////////////////////////////////////////////////////////////////////////// +// senf::INet6SocketAddress + +prefix_ bool senf::INet6SocketAddress::operator==(INet6SocketAddress const & other) + const +{ + return ::memcmp(&sockaddr_.sin6_addr, &other.sockaddr_.sin6_addr, sizeof(sockaddr_.sin6_addr))==0 && + sockaddr_.sin6_port == other.sockaddr_.sin6_port && + sockaddr_.sin6_scope_id == other.sockaddr_.sin6_scope_id; +} + +prefix_ bool senf::INet6SocketAddress::operator!=(INet6SocketAddress const & other) + const +{ + return ! operator==(other); +} + +prefix_ void senf::INet6SocketAddress::clear() +{ + ::memset(&sockaddr_,0,sizeof(sockaddr_)); + sockaddr_.sin6_family = AF_INET6; +} + +prefix_ std::string senf::INet6SocketAddress::address() + const +{ + std::stringstream ss; + ss << '[' << host(); + if (sockaddr_.sin6_scope_id != 0) + ss << '@' << iface() + << "]:" << port(); + return ss.str(); +} + +prefix_ std::string senf::INet6SocketAddress::iface() + const +{ + if (sockaddr_.sin6_scope_id == 0) + return ""; + char buffer[IFNAMSIZ]; + BOOST_ASSERT( if_indextoname(sockaddr_.sin6_scope_id,buffer) ); + return std::string(buffer); +} + +prefix_ void senf::INet6SocketAddress::assignAddr(std::string const & addr) +{ + // Format of addr: "[" address [ "@" interface ] "]" ":" port + typedef boost::char_separator separator; + typedef boost::tokenizer tokenizer; + // we don't add ':' to the list of separators since that would give as the IPv6 address + // as a list of tokens. We just strip the : from the port number manually + separator sep ("", "@[]"); + tokenizer tokens (addr, sep); + tokenizer::iterator token (tokens.begin()); + if (token == tokens.end() + || *token != "[" + || ++token == tokens.end() + || inet_pton(AF_INET6, std::string(boost::begin(*token),boost::end(*token)).c_str(), + &sockaddr_.sin6_addr) <= 0 + || ++token == tokens.end()) + throw InvalidINetAddressException(); + if (*token == "@") { + if (++token == tokens.end()) + throw InvalidINetAddressException(); + assignIface(std::string(boost::begin(*token),boost::end(*token))); + if (++token == tokens.end() + || *token != "]") + throw InvalidINetAddressException(); + } else if (*token != "]") + throw InvalidINetAddressException(); + if (++token == tokens.end() + || *boost::begin(*token) != ':') + throw InvalidINetAddressException(); + try { + sockaddr_.sin6_port = htons( + boost::lexical_cast(std::string(boost::next(boost::begin(*token)), + boost::end(*token)))); + } catch(boost::bad_lexical_cast const &) { + throw InvalidINetAddressException(); + } + if (++token != tokens.end()) + throw InvalidINetAddressException(); +} + +prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface) +{ + if (iface.empty()) + sockaddr_.sin6_scope_id = 0; + else { + sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str()); + if (sockaddr_.sin6_scope_id == 0) + throw InvalidINetAddressException(); } } @@ -83,5 +227,8 @@ prefix_ void satcom::lib::INet4Address::assignString(std::string address) // Local Variables: // mode: c++ -// c-file-style: "satcom" +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" // End: