IBR-DTNSuite 0.6

ibrcommon/ibrcommon/net/vaddress.cpp

Go to the documentation of this file.
00001 /*
00002  * vaddress.cpp
00003  *
00004  *  Created on: 14.12.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/net/vaddress.h"
00010 #include "ibrcommon/net/vsocket.h"
00011 #include "ibrcommon/net/LinkManager.h"
00012 #include <arpa/inet.h>
00013 #include <string.h>
00014 #include <sstream>
00015 
00016 #ifndef HAVE_BZERO
00017 #define bzero(s,n) (memset((s), '\0', (n)), (void) 0)
00018 #endif
00019 
00020 namespace ibrcommon
00021 {
00022         vaddress::vaddress(const Family &family)
00023          : _family(family), _address(), _broadcast(false), _iface(0)
00024         {
00025         }
00026 
00027         vaddress::vaddress(const std::string &address)
00028          : _family(VADDRESS_UNSPEC), _address(address), _broadcast(false), _iface(0)
00029         {
00030         }
00031 
00032         vaddress::vaddress(const Family &family, const std::string &address, const int iface, const bool broadcast)
00033          : _family(family), _address(address), _broadcast(broadcast), _iface(iface)
00034         {
00035         }
00036 
00037         vaddress::vaddress(const Family &family, const std::string &address, const bool broadcast)
00038          : _family(family), _address(address), _broadcast(broadcast), _iface(0)
00039         {
00040         }
00041 
00042         vaddress::~vaddress()
00043         {
00044         }
00045 
00046         // strip off network mask
00047         const std::string vaddress::strip_netmask(const std::string &data)
00048         {
00049                 // search the last slash
00050                 size_t pos = data.find_last_of("/");
00051                 if (pos == std::string::npos) return data;
00052 
00053                 return data.substr(0, pos);
00054         }
00055 
00056         vaddress::Family vaddress::getFamily() const
00057         {
00058                 return _family;
00059         }
00060 
00061         const std::string vaddress::get(bool internal) const
00062         {
00063                 if (_address.length() == 0) throw address_not_set();
00064                 std::string ret = _address;
00065 
00066                 // strip netmask number
00067                 size_t slashpos = _address.find("/");
00068                 if (slashpos != string::npos)
00069                 {
00070                         ret = _address.substr(0, slashpos);
00071                 }
00072 
00073                 if ((_iface > 0) && (internal))
00074                 {
00075                         stringstream ss; ss << ret << "%" << ibrcommon::LinkManager::getInstance().getInterface(_iface);
00076                         ret = ss.str();
00077                 }
00078 
00079                 return ret;
00080         }
00081 
00082         bool vaddress::operator!=(const vaddress &obj) const
00083         {
00084                 if (_family != obj._family) return true;
00085                 if (_address != obj._address) return true;
00086                 return false;
00087         }
00088         
00089         bool vaddress::operator==(const vaddress &obj) const
00090         {
00091                 if (_family != obj._family) return false;
00092                 if (_address != obj._address) return false;
00093                 return true;
00094         }
00095 
00096         bool vaddress::isBroadcast() const
00097         {
00098                 return _broadcast;
00099         }
00100 
00101         struct addrinfo* vaddress::addrinfo(struct addrinfo *hints) const
00102         {
00103                 struct addrinfo *res;
00104 
00105                 if (_family != VADDRESS_UNSPEC)
00106                 {
00107                         hints->ai_family = _family;
00108                 }
00109 
00110                 if (0 != getaddrinfo(get().c_str(), NULL, hints, &res))
00111                         throw vsocket_exception("failed to getaddrinfo with address: " + get());
00112 
00113                 return res;
00114         }
00115 
00116         struct addrinfo* vaddress::addrinfo(struct addrinfo *hints, unsigned int port) const
00117         {
00118                 struct addrinfo *res;
00119 
00120                 if (_family != VADDRESS_UNSPEC)
00121                 {
00122                         hints->ai_family = _family;
00123                 }
00124 
00125                 std::stringstream port_ss; port_ss << port;
00126                 try {
00127                         if (0 != getaddrinfo(get().c_str(), port_ss.str().c_str(), hints, &res))
00128                                 throw vsocket_exception("failed to getaddrinfo with address: " + get());
00129                 }
00130                 catch (const vaddress::address_not_set&)
00131                 {
00132                         if (0 != getaddrinfo(NULL, port_ss.str().c_str(), hints, &res))
00133                                 throw vsocket_exception("failed to getaddrinfo");
00134                 }
00135 
00136                 return res;
00137         }
00138 
00139         bool vaddress::isMulticast() const
00140         {
00141                 try {
00142                         struct sockaddr_in destination;
00143                         bzero(&destination, sizeof(destination));
00144 
00145                         // convert given address
00146                         if (inet_pton(AF_INET, get().c_str(), &destination.sin_addr) <= 0)
00147                         {
00148                                         throw address_not_set("can not parse address");
00149                         }
00150 
00151                         // check if address is in a multicast range
00152                         uint32_t haddr = ntohl((uint32_t&)destination.sin_addr);
00153 
00154                         return (IN_MULTICAST(haddr));
00155                 } catch (const address_not_set&) {
00156                         return false;
00157                 }
00158         }
00159 
00160         const std::string vaddress::toString() const
00161         {
00162                 if (_address.length() == 0) return "<any>";
00163 
00164                 if (_iface > 0)
00165                 {
00166                         stringstream ss; ss << _address << "%" << ibrcommon::LinkManager::getInstance().getInterface(_iface);
00167                         return ss.str();
00168                 }
00169 
00170                 return _address;
00171         }
00172 }