Go to the documentation of this file.00001 #include <ifaddrs.h>
00002
00003 #include "NetInterface.h"
00004
00005 namespace castor { namespace net {
00006
00007 NetInterface::NetInterface(const std::string name) :
00008 name(name), addresses(), addressesb()
00009 {
00010 }
00011
00012 NetInterface::NetInterface(const NetInterface ©) :
00013 name(copy.name), addresses(copy.addresses), addressesb(copy.addressesb)
00014 {
00015 }
00016
00017 std::string NetInterface::getName() const {
00018 return this->name;
00019 }
00020
00021 NetAddressPtrSet NetInterface::getAddresses() const {
00022 return this->addresses;
00023 }
00024
00025 NetAddressPtrSet NetInterface::getBroadcastAddresses() const {
00026 return this->addressesb;
00027 }
00028
00029 void NetInterface::addAddress(const NetAddress &address) {
00030
00031 NetAddressPtr copy(new NetAddress(address));
00032
00033 if (this->addresses.find(copy) == this->addresses.end()) {
00034 this->addresses.insert(copy);
00035 }
00036 }
00037
00038 void NetInterface::addBroadcastAddress(const NetAddress &address) {
00039
00040 NetAddressPtr copy(new NetAddress(address));
00041
00042 if (this->addressesb.find(copy) == this->addressesb.end()) {
00043 this->addressesb.insert(copy);
00044 }
00045 }
00046
00047 bool NetInterface::contains(const NetAddress &address) {
00048
00049 NetAddressPtr copy(new NetAddress(address));
00050
00051 return (this->addresses.find(copy) != this->addresses.end());
00052 }
00053
00054 bool NetInterface::matches(const NetAddress &address) {
00055
00056 for (NetAddressPtrSet::iterator itr = this->addresses.begin();
00057 itr != this->addresses.end(); itr++)
00058 {
00059 if ((*itr)->sameScope(address)) {
00060 return true;
00061 }
00062 }
00063
00064 return false;
00065 }
00066
00067 typedef std::map<std::string, NetInterfacePtr> InterfaceMap;
00068
00069 NetInterfacePtrList NetInterface::getInterfaces() {
00070
00071 NetInterfacePtrList result;
00072
00073 ifaddrs *myaddrs;
00074 ifaddrs *ifa;
00075
00076 int status = getifaddrs(&myaddrs);
00077
00078 if (status) {
00079 throw Exception("error getting local interface addresses: %s", strerror(status));
00080 }
00081
00082 InterfaceMap ifaces;
00083
00084 for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) {
00085
00086 if (ifa->ifa_addr == NULL) continue;
00087
00088 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
00089
00090 std::string ifaceName(ifa->ifa_name);
00091
00092 NetInterfacePtr iface;
00093
00094 InterfaceMap::iterator itr = ifaces.find(ifaceName);
00095
00096 if (itr == ifaces.end()) {
00097 iface = NetInterfacePtr(new NetInterface(ifaceName));
00098 ifaces[ifaceName] = iface;
00099 } else {
00100 iface = itr->second;
00101 }
00102
00103 NetAddress address;
00104 NetAddress addressb_;
00105
00106 if (ifa->ifa_addr->sa_family == AF_INET) {
00107
00108 sockaddr_in *sa = (sockaddr_in *)(ifa->ifa_addr);
00109 sockaddr_in *sab = (sockaddr_in *)(ifa->ifa_broadaddr);
00110
00111 boost::array<unsigned char, 4> buffer;
00112 for (int i = 0; i < 4; i++) buffer[i] = ((unsigned char *)&sa->sin_addr)[i];
00113
00114 boost::array<unsigned char, 4> bufferb;
00115 for (int i = 0; i < 4; i++) bufferb[i] = ((unsigned char *)&sab->sin_addr)[i];
00116
00117 address = NetAddress(asio::ip::address_v4(buffer));
00118 NetAddress addressb = NetAddress(asio::ip::address_v4(bufferb));
00119 addressb_ = addressb;
00120
00121 iface->addBroadcastAddress(addressb);
00122
00123 } else if (ifa->ifa_addr->sa_family == AF_INET6) {
00124
00125 sockaddr_in6 *sa = (sockaddr_in6 *)(ifa->ifa_addr);
00126 sockaddr_in6 *sab = (sockaddr_in6 *)(ifa->ifa_broadaddr);
00127
00128 boost::array<unsigned char, 16> buffer;
00129 for (int i = 0; i < 16; i++) buffer[i] = ((unsigned char *)&sa->sin6_addr)[i];
00130
00131 boost::array<unsigned char, 16> bufferb;
00132 for (int i = 0; i < 16; i++) bufferb[i] = ((unsigned char *)&sab->sin6_addr)[i];
00133
00134 address = NetAddress(asio::ip::address_v6(buffer, sa->sin6_scope_id));
00135
00136 } else {
00137 continue;
00138 }
00139
00140 iface->addAddress(address);
00141
00142 }
00143
00144 for (InterfaceMap::iterator itr = ifaces.begin();
00145 itr != ifaces.end(); itr++)
00146 {
00147 result.push_back(itr->second);
00148 }
00149
00150 freeifaddrs(myaddrs);
00151
00152 return result;
00153 }
00154
00155 NetInterfacePtr NetInterface::getDefaultRoute() {
00156 char buf[256];
00157 FILE *fp = fopen("/proc/net/route", "r");
00158
00159 if (!fp) {
00160 return NetInterfacePtr();
00161 }
00162
00163 if (fgets(buf, sizeof(buf), fp)) {
00164
00165 }
00166
00167 while (fgets(buf, sizeof(buf), fp)) {
00168 char iface[256];
00169 unsigned int dest;
00170 unsigned int gateway;
00171 unsigned int flags;
00172 unsigned int refcnt;
00173 unsigned int use;
00174 unsigned int metric;
00175 unsigned int mask;
00176 unsigned int mtu;
00177 unsigned int window;
00178 unsigned int irtt;
00179
00180 if (sscanf(buf, "%s%08x%08x%04x%d%d%d%08x%d%d%d", iface,
00181 &dest, &gateway, &flags, &refcnt, &use,
00182 &metric, &mask, &mtu, &window, &irtt) != 11)
00183 {
00184 continue;
00185 }
00186
00187 if (dest != 0) {
00188 continue;
00189 }
00190
00191 std::string ifaceStr(iface);
00192 NetInterfacePtrList ifaces = getInterfaces();
00193
00194 for (NetInterfacePtrList::iterator itr = ifaces.begin();
00195 itr != ifaces.end(); itr++)
00196 {
00197 if ((*itr)->getName() == ifaceStr) {
00198 return *itr;
00199 }
00200 }
00201 }
00202
00203 return NetInterfacePtr();
00204 }
00205
00206 NetInterfacePtr NetInterface::getDefaultRoute6() {
00207 std::cout << "NetInterface::getDefaultRoute6() not implemented!" << std::endl;
00208 return NetInterfacePtr();
00209 }
00210
00211 std::string NetInterface::str() const {
00212
00213 std::ostringstream ss;
00214
00215 ss << this->name << ":";
00216
00217 for (NetAddressPtrSet::iterator itr = this->addresses.begin();
00218 itr != this->addresses.end(); itr++)
00219 {
00220 ss << " " << **itr;
00221 }
00222
00223 return ss.str();
00224 }
00225
00226 bool operator<(const NetInterface &one, const NetInterface &other) {
00227 return (one.name < other.name);
00228 }
00229
00230 } }
00231