NetAddress.h
Go to the documentation of this file.
00001 
00002 #ifndef CASTOR_NET_NETADDRESS_H
00003 #define CASTOR_NET_NETADDRESS_H 1
00004 
00005 #include <string>
00006 #include <vector>
00007 #include <asio.hpp>
00008 #include <boost/algorithm/string.hpp>
00009 #include <castor/Exception.h>
00010 
00011 /*
00012  * Spica addressing scheme
00013  *
00014  * Generic:                                                                                     <spica-specific>
00015  *   <protocol>://<address>:<explicit port>                     (0x00)
00016  *
00017  * Spica-specific:                                                                      <spica-specific>
00018  *   spica+<protocol>://<address>                                       (0x01)
00019  *   spica+<protocol>://<address>[:<spica port>]        (0x02)
00020  *   spica+<protocol>://<address>[/cidr]                        (0x03)
00021  *
00022  *
00023  * Layout:
00024  *
00025  *   <uchar:spica-specific><uchar:protocol><ushort:port><uchar:address-length><uchar*:address>
00026  *
00027  *   0x00 <uchar:protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00028  *   0x01 <uchar:protocol> <uchar:address-length> <uchar*:address>
00029  *   0x02 <uchar:protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00030  *   0x03 <uchar:protocol> <uchar:cidr> <uchar:address-length> <uchar*:address>
00031  *
00032  */
00033 
00034 namespace castor {
00035 
00036         namespace net {
00037 
00038                 class NetAddress;
00039 
00040                 typedef std::vector<unsigned char> Bytes;
00041                 typedef boost::shared_ptr<Bytes> BytesPtr;
00042                 typedef boost::shared_ptr<NetAddress> NetAddressPtr;
00043 
00044                 class NetAddress {
00045 
00046                         public:
00047 
00048                                 enum SpicaSpecific {
00049 
00050                                         ss_none         = 0x00,
00051                                         ss_plain        = 0x01,
00052                                         ss_host         = 0x02,
00053                                         ss_network      = 0x03,
00054                                         ss_undecided = 0x04,
00055                                 };
00056 
00057                         private:
00058 
00059                                 SpicaSpecific spicaSpecific;
00060                                 unsigned char protocol;
00061                                 unsigned short port;
00062                                 unsigned char cidr;
00063                                 asio::ip::address address;
00064 
00065                         protected:
00066 
00067                                 NetAddress() {
00068 
00069                                         this->spicaSpecific = ss_none;
00070 
00071                                         this->protocol = 0;
00072                                         this->port = 0;
00073                                         this->cidr = 0;
00074                                 }
00075 
00076                                 NetAddress(SpicaSpecific spicaSpecific, unsigned char protocol, asio::ip::address address, unsigned short port, unsigned char cidr) {
00077 
00078                                         this->spicaSpecific = spicaSpecific;
00079 
00080                                         this->address = address;
00081                                         this->protocol = protocol;
00082                                         this->port = port;
00083                                         this->cidr = cidr;
00084                                 }
00085 
00086                         public:
00087         
00088                                 static NetAddress create(const std::string spec) throw(Exception) {
00089 
00090                                         NetAddress result;
00091 
00092                                         std::string address = spec;
00093 
00094                                         boost::algorithm::trim_if(address, boost::is_any_of("/"));
00095 
00096                                         size_t pos = address.find("://");
00097 
00098                                         if (pos == std::string::npos) {
00099                                                 std::ostringstream ss;
00100                                                 ss << "NetAddress: invalid address specifier (" << spec << ")";
00101                                                 throw Exception(ss.str());
00102                                         }
00103 
00104                                         // process protocol part
00105                                         if (boost::istarts_with(address, "spica")) {
00106 
00107                                                 size_t plusPos = address.find("+");
00108 
00109                                                 if (plusPos != std::string::npos) {
00110 
00111                                                         result.spicaSpecific = ss_undecided;
00112                                                         result.protocol = NetAddress::string_to_protocol(address.substr(plusPos + 1, pos - plusPos - 1));
00113 
00114                                                 } else {
00115                                                         result.spicaSpecific = ss_plain;
00116                                                         result.protocol = 0;
00117                                                 }
00118 
00119                                         } else {
00120 
00121                                                 result.spicaSpecific = ss_none;
00122                                                 result.protocol = NetAddress::string_to_protocol(address.substr(0, pos));
00123                                         }
00124 
00125                                         address = address.substr(pos + 3, address.size() - pos - 3);
00126 
00127                                         // process the host
00128 
00129                                         size_t bracketStartPos = address.find("[");
00130                                         size_t bracketEndPos = address.find("[");
00131                                         size_t colonPos = address.rfind(":");
00132                                         size_t slashPos = address.rfind("/");
00133 
00134                                         if (bracketStartPos != std::string::npos) {
00135 
00136                                                 std::string specAddress = address.substr(bracketStartPos + 1, bracketEndPos - bracketStartPos - 1);
00137 
00138                                                 result.address = asio::ip::address::from_string(specAddress);
00139 
00140                                                 if ((colonPos != std::string::npos) && (colonPos > bracketEndPos)) {
00141 
00142                                                         std::string specPort = address.substr(colonPos + 1, address.size() - colonPos - 1);
00143 
00144                                                         result.port = atoi(specPort.c_str());
00145 
00146                                                         if (result.spicaSpecific == ss_plain) {
00147                                                                 throw Exception("NetAddress: a port may not be specified in spica plain address mode");
00148                                                         }
00149 
00150                                                         if (result.spicaSpecific == ss_undecided) {
00151                                                                 result.spicaSpecific = ss_host;
00152                                                         }
00153 
00154                                                 } else if ((slashPos != std::string::npos) && (slashPos > bracketEndPos)) {
00155 
00156                                                         std::string specCidr = address.substr(slashPos + 1, address.size() - slashPos - 1);
00157         
00158                                                         result.cidr = atoi(specCidr.c_str());
00159 
00160                                                         if (result.spicaSpecific != ss_undecided) {
00161                                                                 throw Exception("NetAddress: a network may not be specified in non-spica or spica plain address mode");
00162                                                         }
00163 
00164                                                         result.spicaSpecific = ss_network;
00165 
00166                                                 } else {
00167                                                         if (result.spicaSpecific == ss_undecided) {
00168                                                                 result.spicaSpecific = ss_plain;
00169                                                         }
00170                                                 }
00171 
00172                                         } else {
00173 
00174                                                 if (colonPos != std::string::npos) {
00175 
00176                                                         result.address = asio::ip::address::from_string(address.substr(0, colonPos));
00177                                                         result.port = atoi(address.substr(colonPos + 1, address.size() - colonPos - 1).c_str());
00178 
00179                                                         if (result.spicaSpecific == ss_plain) {
00180                                                                 throw Exception("NetAddress: a port may not be specified in spica plain address mode");
00181                                                         }
00182 
00183                                                         if (result.spicaSpecific == ss_undecided) {
00184                                                                 result.spicaSpecific = ss_host;
00185                                                         }
00186 
00187                                                 } else if (slashPos != std::string::npos) {
00188 
00189                                                         result.address = asio::ip::address::from_string(address.substr(0, slashPos));
00190                                                         result.cidr = atoi(address.substr(slashPos + 1, address.size() - slashPos - 1).c_str());
00191 
00192                                                         if (result.spicaSpecific != ss_undecided) {
00193                                                                 throw Exception("NetAddress: a network may not be specified in non-spica or spica plain address mode");
00194                                                         }
00195 
00196                                                         result.spicaSpecific = ss_network;
00197 
00198                                                 } else {
00199                                                         result.address = asio::ip::address::from_string(address);
00200 
00201                                                         if (result.spicaSpecific == ss_undecided) {
00202 
00203                                                                 if (result.protocol != 0) {
00204                                                                         result.spicaSpecific = ss_host;
00205                                                                 } else {
00206                                                                         result.spicaSpecific = ss_plain;
00207                                                                 }
00208                                                         }
00209                                                 }
00210                                         }
00211 
00212                                         return result;
00213                                 }
00214 
00215                                 static NetAddress create(unsigned char protocol, asio::ip::address address, unsigned short port) {
00216                                         return NetAddress(ss_none, protocol, address, port, 0);
00217                                 }
00218 
00219                                 static NetAddress createPlain(unsigned char protocol, asio::ip::address address) {
00220                                         return NetAddress(ss_plain, protocol, address, 0, 0);
00221                                 }
00222 
00223                                 static NetAddress createHost(unsigned char protocol, asio::ip::address address, unsigned short port) {
00224                                         return NetAddress(ss_host, protocol, address, port, 0);
00225                                 }
00226 
00227                                 static NetAddress createNetwork(unsigned char protocol, asio::ip::address address, unsigned char cidr) {
00228                                         return NetAddress(ss_network, protocol, address, 0, cidr);
00229                                 }
00230 
00231                                 static NetAddress create(const BytesPtr bytes) throw() {
00232                                         NetAddress result;
00233                                         result.parse(&(*bytes)[0], bytes->size());
00234                                         return result;
00235                                 }
00236 
00237                                 static NetAddress create(const unsigned char *data, size_t size) throw() {
00238                                         NetAddress result;
00239                                         result.parse(data, size);
00240                                         return result;
00241                                 }
00242 
00243                                 NetAddress(const NetAddress &other) {
00244 
00245                                         this->spicaSpecific = other.spicaSpecific;
00246 
00247                                         this->protocol = other.protocol;
00248                                         this->address = other.address;
00249                                         this->port = other.port;
00250                                         this->cidr = other.cidr;
00251                                 }
00252 
00253                                 bool isSpicaSpecific()  const { return this->spicaSpecific != ss_none; }
00254                                 bool isPlain()                  const { return this->spicaSpecific == ss_plain; }
00255                                 bool isHost()                   const { return this->spicaSpecific == ss_host; }
00256                                 bool isNetwork()                const { return this->spicaSpecific == ss_network; }
00257 
00258                                 unsigned char getProtocol() const { return this->protocol; }
00259 
00260                                 unsigned short getPort() const {
00261                                         if (this->spicaSpecific == ss_host) {
00262                                                 return this->port;
00263                                         }
00264                                         return 0;
00265                                 }
00266 
00267                                 unsigned char getCidr() const {
00268                                         if (this->spicaSpecific == ss_network) {
00269                                                 return this->cidr;
00270                                         }
00271                                         return 0;
00272                                 }
00273 
00274                                 const asio::ip::address &getAddress() const {
00275                                         return this->address;
00276                                 }
00277 
00278                                 void setAddress(asio::ip::address addr_) {
00279                                         this->address = addr_;
00280 
00281                                 }
00282 
00283                                 BytesPtr getBytes() const {
00284 
00285                                         BytesPtr result;
00286 
00287                                         size_t offset = 0;
00288                                         size_t length = (this->address.is_v4() ? 4 : 16);
00289 
00290                                         switch (this->spicaSpecific) {
00291 
00292                                                 case ss_none:   // generic address => 0x00 <uchar: protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00293                                                         {
00294 
00295                                                                 size_t size = 5 + length;
00296                                                                 unsigned short port = asio::detail::socket_ops::network_to_host_short(this->port);
00297 
00298                                                                 result = BytesPtr(new Bytes(size));
00299 
00300                                                                 (*result)[0] = (unsigned char)ss_none;
00301                                                                 (*result)[1] = (unsigned char)this->protocol;
00302                                                                 (*result)[2] = (unsigned char)((port & 0xff00) >> 8);
00303                                                                 (*result)[3] = (unsigned char)(port & 0x00ff);
00304                                                                 (*result)[4] = (unsigned char)length;
00305 
00306                                                                 offset = 5;
00307                                                         }
00308 
00309                                                         break;
00310 
00311                                                 case ss_plain:  // spica plain => 0x01 <uchar:protocol> <uchar:address-length> <uchar*:address>
00312                                                         {
00313 
00314                                                                 size_t size = 3 + length;
00315 
00316                                                                 result = BytesPtr(new Bytes(size));
00317 
00318                                                                 (*result)[0] = (unsigned char)ss_plain;
00319                                                                 (*result)[1] = (unsigned char)this->protocol;
00320                                                                 (*result)[2] = (unsigned char)length;
00321 
00322                                                                 offset = 3;
00323                                                         }
00324 
00325                                                         break;
00326 
00327                                                 case ss_host:   // spica host => 0x02 <uchar:protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00328                                                         {
00329 
00330                                                                 size_t size = 5 + length;
00331                                                                 unsigned short port = asio::detail::socket_ops::network_to_host_short(this->port);
00332 
00333                                                                 result = BytesPtr(new Bytes(size));
00334 
00335                                                                 (*result)[0] = (unsigned char)ss_host;
00336                                                                 (*result)[1] = (unsigned char)this->protocol;
00337                                                                 (*result)[2] = (unsigned char)((port & 0xff00) >> 8);
00338                                                                 (*result)[3] = (unsigned char)(port & 0x00ff);
00339                                                                 (*result)[4] = (unsigned char)length;
00340 
00341                                                                 offset = 5;
00342                                                         }
00343 
00344                                                         break;
00345 
00346                                                 case ss_network:        // spica network => 0x03 <uchar:protocol> <uchar:cidr> <uchar:address-length> <uchar*:address>
00347                                                         {
00348 
00349                                                                 size_t size = 4 + length;
00350 
00351                                                                 result = BytesPtr(new Bytes(size));
00352 
00353                                                                 (*result)[0] = (unsigned char)ss_network;
00354                                                                 (*result)[1] = (unsigned char)this->protocol;
00355                                                                 (*result)[2] = this->cidr;
00356                                                                 (*result)[3] = (unsigned char)length;
00357 
00358                                                                 offset = 4;
00359                                                         }
00360 
00361                                                         break;
00362 
00363                                                 default:
00364                                                         throw Exception("NetAddress: unknown value for SpicaSpecific");
00365 
00366                                         }
00367 
00368                                         if (this->address.is_v4()) {
00369 
00370                                                 asio::ip::address_v4::bytes_type b = this->address.to_v4().to_bytes();
00371                                                 for (size_t i = 0; i < b.size(); i++) (*result)[offset + i] = b[i];
00372 
00373                                         } else {
00374                                                 asio::ip::address_v6::bytes_type b = this->address.to_v6().to_bytes();
00375                                                 for (size_t i = 0; i < b.size(); i++) (*result)[offset + i] = b[i];
00376                                         }
00377 
00378                                         return result;
00379                                 }
00380 
00381                                 std::string str() const {
00382 
00383                                         std::ostringstream ss;
00384 
00385                                         switch (this->spicaSpecific) {
00386 
00387                                                 case ss_none:   // generic address
00388 
00389                                                         ss << protocol_to_string(this->protocol) << "://[" << this->address.to_string() << "]";
00390 
00391                                                         if (this->port > 0) {
00392                                                                 ss << ":" << this->port;
00393                                                         }
00394 
00395                                                         ss << "/";
00396 
00397                                                         break;
00398 
00399                                                 case ss_plain:  // spica plain
00400 
00401                                                         ss << "spica" << "://[" << this->address.to_string() << "]/";
00402 
00403                                                         break;
00404 
00405                                                 case ss_host:   // spica host
00406 
00407                                                         ss << "spica+"<< protocol_to_string(this->protocol) << "://[" << this->address.to_string() << "]";
00408 
00409                                                         if (this->port > 0) {
00410                                                                 ss << ":" << this->port;
00411                                                         }
00412 
00413                                                         ss << "/";
00414 
00415                                                         break;
00416 
00417                                                 case ss_network:        // spica network
00418 
00419                                                         ss << "spica+" << protocol_to_string(this->protocol) << "://[" << this->address.to_string() << "]";
00420 
00421                                                         if (this->cidr > 0) {
00422                                                                 ss << "/" << (int)this->cidr;
00423                                                         }
00424 
00425                                                         break;
00426 
00427                                                 default:                // should not be reached
00428 
00429                                                         ss << "NetAddress::str(): this should not be reached";
00430 
00431                                                         break;
00432                                         }
00433 
00434                                         return "." + ss.str();
00435                                 }
00436 
00437                                 inline static std::string protocol_to_string(int protocol) {
00438                                         switch (protocol) {
00439                                                 case IPPROTO_IP:        return "ip";
00440                                                 case IPPROTO_TCP:       return "tcp";
00441                                                 case IPPROTO_UDP:       return "udp";
00442                                                 case IPPROTO_IPV6:      return "ipv6";
00443                                         }
00444                                         return "";
00445                                 }
00446 
00447                                 inline static unsigned char string_to_protocol(const std::string protocol) {
00448                                         if (boost::iequals(protocol, "ip")) {
00449                                                 return (unsigned char)IPPROTO_IP;
00450                                         } else if (boost::iequals(protocol, "tcp")) {
00451                                                 return (unsigned char)IPPROTO_TCP;
00452                                         } else if (boost::iequals(protocol, "udp")) {
00453                                                 return (unsigned char)IPPROTO_UDP;
00454                                         } else if (boost::iequals(protocol, "ipv6")) {
00455                                                 return (unsigned char)IPPROTO_IPV6;
00456                                         }
00457                                         return 0;
00458                                 }
00459 
00460                                 bool equals(const NetAddress &other) const {
00461                                         return (*this == other);
00462                                 }
00463 
00464                                 NetAddress &operator=(const NetAddress &other) {
00465 
00466                                         if (this != &other) {
00467 
00468                                                 this->spicaSpecific = other.spicaSpecific;
00469 
00470                                                 this->protocol = other.protocol;
00471                                                 this->address = other.address;
00472                                                 this->port = other.port;
00473                                                 this->cidr = other.cidr;
00474                                         }
00475 
00476                                         return *this;
00477                                 }
00478 
00479                                 bool operator==(const NetAddress &other) const {
00480 
00481                                         if (this->spicaSpecific != other.spicaSpecific) return false;
00482                                         if (this->address != other.address)                             return false;
00483                                         if ((this->spicaSpecific != ss_plain) &&
00484                                                 (this->spicaSpecific != ss_network) &&
00485                                                 (this->port != other.port))                                     return false;
00486                                         if ((this->spicaSpecific == ss_network) &&
00487                                                 (this->cidr != other.cidr))                                     return false;
00488 
00489                                         return true;
00490                                 }
00491 
00492                                 bool operator!=(const NetAddress &other) const {
00493                                         return !(*this == other);
00494                                 }
00495 
00496                         protected:
00497 
00498                                 void parse(const unsigned char *data, size_t size) throw() {
00499 
00500                                         if (data == NULL)       throw castor::Exception("NetAddress: address data is NULL");
00501                                         if (size < 1)           throw castor::Exception("NetAddress: address too short");
00502 
00503                                         this->spicaSpecific = (SpicaSpecific)data[0];
00504 
00505                                         switch (this->spicaSpecific) {
00506 
00507                                                 case ss_none:   // generic address => 0x00 <uchar:protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00508                                                         {
00509 
00510                                                                 if (size < 5) throw castor::Exception("NetAddress: address too short for a generic address");
00511 
00512                                                                 this->protocol = data[1];
00513                                                                 this->port = asio::detail::socket_ops::host_to_network_short(((unsigned short)data[2] << 8) |
00514                                                                                                                                                                                          ((unsigned short)data[3]));
00515 
00516                                                                 size_t length = (size_t)data[4];
00517 
00518                                                                 if ((length + 5) != size) throw castor::Exception("NetAddress: address too short for a generic address");
00519                                                                 if ((length != 4) && (length != 16)) throw castor::Exception("NetAddress: address is neither an ipv4 nor an ipv6 address");
00520 
00521                                                                 if (length == 4) {
00522 
00523                                                                         asio::ip::address_v4::bytes_type a;
00524                                                                         for (size_t i = 0; i < length; i++) {
00525                                                                                 a[i] = data[5 + i];
00526                                                                         }
00527                                                                         this->address = asio::ip::address_v4(a);
00528 
00529                                                                 } else {
00530 
00531                                                                         asio::ip::address_v6::bytes_type a;
00532                                                                         for (size_t i = 0; i < length; i++) {
00533                                                                                 a[i] = data[5 + i];
00534                                                                         }
00535                                                                         this->address = asio::ip::address_v6(a);
00536                                                                 }
00537                                                         }
00538 
00539                                                         break;
00540 
00541                                                 case ss_plain:  // spica plain => 0x01 <uchar:protocol> <uchar:address-length> <uchar*:address>
00542                                                         {
00543 
00544                                                                 if (size < 3) throw castor::Exception("NetAddress: address too short for a spica plain address");
00545 
00546                                                                 this->protocol = data[1];
00547 
00548                                                                 size_t length = (size_t)data[2];
00549 
00550                                                                 if ((length + 3) != size) throw castor::Exception("NetAddress: address too short for a spica plain address");
00551                                                                 if ((length != 4) && (length != 16)) throw castor::Exception("NetAddress: address is neither an ipv4 nor an ipv6 address");
00552 
00553                                                                 if (length == 4) {
00554 
00555                                                                         asio::ip::address_v4::bytes_type a;
00556                                                                         for (size_t i = 0; i < length; i++) {
00557                                                                                 a[i] = data[3 + i];
00558                                                                         }
00559                                                                         this->address = asio::ip::address_v4(a);
00560 
00561                                                                 } else {
00562 
00563                                                                         asio::ip::address_v6::bytes_type a;
00564                                                                         for (size_t i = 0; i < length; i++) {
00565                                                                                 a[i] = data[3 + i];
00566                                                                         }
00567                                                                         this->address = asio::ip::address_v6(a);
00568                                                                 }
00569                                                         }
00570 
00571                                                         break;
00572 
00573                                                 case ss_host:   // spica host => 0x02 <uchar:protocol> <ushort:port> <uchar:address-length> <uchar*:address>
00574                                                         {
00575 
00576                                                                 if (size < 5) throw castor::Exception("NetAddress: address too short for a spica host address");
00577 
00578                                                                 this->protocol = data[1];
00579                                                                 this->port = asio::detail::socket_ops::host_to_network_short(((unsigned short)data[2] << 8) |
00580                                                                                                                                                                                          ((unsigned short)data[3]));
00581 
00582                                                                 size_t length = (size_t)data[4];
00583 
00584                                                                 if ((length + 5) != size) throw castor::Exception("NetAddress: address too short for a spica host address");
00585                                                                 if ((length != 4) && (length != 16)) throw castor::Exception("NetAddress: address is neither an ipv4 nor an ipv6 address");
00586 
00587                                                                 if (length == 4) {
00588 
00589                                                                         asio::ip::address_v4::bytes_type a;
00590                                                                         for (size_t i = 0; i < length; i++) {
00591                                                                                 a[i] = data[5 + i];
00592                                                                         }
00593                                                                         this->address = asio::ip::address_v4(a);
00594 
00595                                                                 } else {
00596 
00597                                                                         asio::ip::address_v6::bytes_type a;
00598                                                                         for (size_t i = 0; i < length; i++) {
00599                                                                                 a[i] = data[5 + i];
00600                                                                         }
00601                                                                         this->address = asio::ip::address_v6(a);
00602                                                                 }
00603                                                         }
00604 
00605                                                         break;
00606 
00607                                                 case ss_network:        // spica network => 0x03 <uchar:protocol> <uchar:cidr> <uchar:address-length> <uchar*:address>
00608                                                         {
00609 
00610                                                                 if (size < 4) throw castor::Exception("NetAddress: address too short for a spica network address");
00611 
00612                                                                 this->protocol = data[1];
00613                                                                 this->cidr = data[2];
00614                                                                 size_t length = (size_t)data[3];
00615 
00616                                                                 if ((length + 4) != size) throw castor::Exception("NetAddress: address too short for a spica network address");
00617                                                                 if ((length != 4) && (length != 16)) throw castor::Exception("NetAddress: address is neither an ipv4 nor an ipv6 address");
00618 
00619                                                                 if (length == 4) {
00620 
00621                                                                         asio::ip::address_v4::bytes_type a;
00622                                                                         for (size_t i = 0; i < length; i++) {
00623                                                                                 a[i] = data[4 + i];
00624                                                                         }
00625                                                                         this->address = asio::ip::address_v4(a);
00626 
00627                                                                 } else {
00628 
00629                                                                         asio::ip::address_v6::bytes_type a;
00630                                                                         for (size_t i = 0; i < length; i++) {
00631                                                                                 a[i] = data[4 + i];
00632                                                                         }
00633                                                                         this->address = asio::ip::address_v6(a);
00634                                                                 }
00635                                                         }
00636 
00637                                                         break;
00638 
00639                                                 case ss_undecided:
00640                                                         // should not be reached
00641                                                         break;
00642                                         }
00643                                 }
00644                 };
00645         };
00646 };
00647 
00648 std::ostream &operator << (std::ostream &os, const castor::net::NetAddress &x);
00649 
00650 #endif /* CASTOR_NET_NETADDRESS_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39