INetAddressing.cc
Go to the documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "INetAddressing.hh"
00028
00029
00030
00031 #include <sstream>
00032 #include <string.h>
00033 #include <sys/socket.h>
00034 #include <net/if.h>
00035 #include <boost/lexical_cast.hpp>
00036 #include <boost/regex.hpp>
00037 #include <senf/Utils/senfassert.hh>
00038 #include <senf/Socket/Protocols/AddressExceptions.hh>
00039
00040
00041 #define prefix_
00042
00043
00044
00045
00046
00047 prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
00048 : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
00049 {
00050 std::string::size_type portIx = addr.find(':');
00051 try {
00052 port( boost::lexical_cast< ::u_int16_t >(portIx == std::string::npos
00053 ? addr : std::string(addr,portIx+1)) );
00054 }
00055 catch (boost::bad_lexical_cast const &) {
00056 throw AddressSyntaxException(addr) << ": invalid port number";
00057 }
00058 if (portIx != std::string::npos)
00059 address( INet4Address::from_string(std::string(addr,0,portIx)) );
00060 }
00061
00062 prefix_ senf::INet4SocketAddress::INet4SocketAddress(INet4Address const & addr, unsigned p)
00063 : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
00064 {
00065 address(addr);
00066 port(p);
00067 }
00068
00069 prefix_ senf::INet4SocketAddress::INet4SocketAddress(unsigned p)
00070 : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
00071 {
00072 port(p);
00073 }
00074
00075 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
00076 {
00077 os << addr.address() << ":" << addr.port();
00078 return os;
00079 }
00080
00081 prefix_ std::istream & senf::operator>>(std::istream & is, INet4SocketAddress & addr)
00082 {
00083 std::string s;
00084 if (!(is >> s))
00085 return is;
00086 try {
00087 addr = INet4SocketAddress(s);
00088 }
00089 catch (AddressException &) {
00090 is.setstate(std::ios::failbit);
00091 }
00092 return is;
00093 }
00094
00095
00096
00097
00098 prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
00099 INet6Address::Resolve_t resolve)
00100 : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
00101 {
00102
00103
00104
00105
00106 static boost::regex const addressRx ("(?:(?:\\[([^%]+)(?:%(.+))?\\]|(.+)):)?([0-9]+)");
00107
00108 enum { Address = 1,
00109 ZoneId = 2,
00110 Hostname = 3,
00111 Port = 4 };
00112
00113 boost::smatch match;
00114 if (! regex_match(addr, match, addressRx))
00115 throw AddressSyntaxException(addr);
00116
00117 if (match[ZoneId].matched)
00118 assignIface(match[ZoneId]);
00119
00120 sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port]));
00121
00122 if (match[Address].matched || match[Hostname].matched) {
00123 INet6Address a (INet6Address::from_string(
00124 match[Address].matched ? match[Address] : match[Hostname],
00125 resolve));
00126 std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]);
00127 }
00128 }
00129
00130 prefix_ std::string senf::INet6SocketAddress::iface()
00131 const
00132 {
00133 if (sockaddr_.sin6_scope_id == 0)
00134 return "";
00135 char buffer[IFNAMSIZ];
00136 SENF_ASSERT_EXPRESSION(if_indextoname(sockaddr_.sin6_scope_id,buffer),
00137 "Internal failure: Invalid interface index (how does it get here?)");
00138 return std::string(buffer);
00139 }
00140
00141 prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
00142 {
00143 if (iface.empty())
00144 sockaddr_.sin6_scope_id = 0;
00145 else {
00146 sockaddr_.sin6_scope_id = if_nametoindex(iface.c_str());
00147 if (sockaddr_.sin6_scope_id == 0)
00148 throw AddressSyntaxException(iface);
00149 }
00150 }
00151
00152 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr)
00153 {
00154 os << '[' << addr.address();
00155 std::string iface (addr.iface());
00156 if (! iface.empty())
00157 os << '%' << iface;
00158 os << "]:" << addr.port();
00159 return os;
00160 }
00161
00162 prefix_ std::istream & senf::operator>>(std::istream & is, INet6SocketAddress & addr)
00163 {
00164 std::string s;
00165 if (!(is >> s))
00166 return is;
00167 try {
00168 addr = INet6SocketAddress(s);
00169 }
00170 catch (AddressException &) {
00171 is.setstate(std::ios::failbit);
00172 }
00173 return is;
00174 }
00175
00176
00177 #undef prefix_
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189