Go to the documentation of this file.00001
00002
00003
00004
00005
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
00047 const std::string vaddress::strip_netmask(const std::string &data)
00048 {
00049
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
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
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
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 }