|
IBR-DTNSuite 0.6
|
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 }