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 vaddress::Family vaddress::getFamily() const
00047 {
00048 return _family;
00049 }
00050
00051 const std::string vaddress::get(bool internal) const
00052 {
00053 if (_address.length() == 0) throw address_not_set();
00054 std::string ret = _address;
00055
00056
00057 size_t slashpos = _address.find("/");
00058 if (slashpos != string::npos)
00059 {
00060 ret = _address.substr(0, slashpos);
00061 }
00062
00063 if ((_iface > 0) && (internal))
00064 {
00065 stringstream ss; ss << ret << "%" << ibrcommon::LinkManager::getInstance().getInterface(_iface);
00066 ret = ss.str();
00067 }
00068
00069 return ret;
00070 }
00071
00072 bool vaddress::operator!=(const vaddress &obj) const
00073 {
00074 if (_family != obj._family) return false;
00075 if (_address != obj._address) return false;
00076 return true;
00077 }
00078
00079 bool vaddress::isBroadcast() const
00080 {
00081 return _broadcast;
00082 }
00083
00084 struct addrinfo* vaddress::addrinfo(struct addrinfo *hints) const
00085 {
00086 struct addrinfo *res;
00087
00088 if (_family != VADDRESS_UNSPEC)
00089 {
00090 hints->ai_family = _family;
00091 }
00092
00093 if (0 != getaddrinfo(get().c_str(), NULL, hints, &res))
00094 throw vsocket_exception("failed to getaddrinfo with address: " + get());
00095
00096 return res;
00097 }
00098
00099 struct addrinfo* vaddress::addrinfo(struct addrinfo *hints, unsigned int port) const
00100 {
00101 struct addrinfo *res;
00102
00103 if (_family != VADDRESS_UNSPEC)
00104 {
00105 hints->ai_family = _family;
00106 }
00107
00108 std::stringstream port_ss; port_ss << port;
00109 try {
00110 if (0 != getaddrinfo(get().c_str(), port_ss.str().c_str(), hints, &res))
00111 throw vsocket_exception("failed to getaddrinfo with address: " + get());
00112 }
00113 catch (const vaddress::address_not_set&)
00114 {
00115 if (0 != getaddrinfo(NULL, port_ss.str().c_str(), hints, &res))
00116 throw vsocket_exception("failed to getaddrinfo");
00117 }
00118
00119 return res;
00120 }
00121
00122 bool vaddress::isMulticast() const
00123 {
00124 try {
00125 struct sockaddr_in destination;
00126 bzero(&destination, sizeof(destination));
00127
00128
00129 if (inet_pton(AF_INET, get().c_str(), &destination.sin_addr) <= 0)
00130 {
00131 throw address_not_set("can not parse address");
00132 }
00133
00134
00135 uint32_t haddr = ntohl((uint32_t&)destination.sin_addr);
00136
00137 return (IN_MULTICAST(haddr));
00138 } catch (const address_not_set&) {
00139 return false;
00140 }
00141 }
00142
00143 const std::string vaddress::toString() const
00144 {
00145 if (_address.length() == 0) return "<any>";
00146
00147 if (_iface > 0)
00148 {
00149 stringstream ss; ss << _address << "%" << ibrcommon::LinkManager::getInstance().getInterface(_iface);
00150 return ss.str();
00151 }
00152
00153 return _address;
00154 }
00155 }