$search
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 // do nothing 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