simple-socket library 1.1.5
|
00001 #include "SocketUtils.h" 00002 #include "SimpleSocket.h" 00003 00004 #include <sys/socket.h> 00005 #include <sys/ioctl.h> 00006 #include <arpa/inet.h> 00007 #include <net/if.h> 00008 #include <net/if_arp.h> 00009 #include <netdb.h> 00010 00011 #include <cstring> 00012 #include <cstdlib> 00013 #include <sstream> 00014 #include <iomanip> 00015 00016 using namespace NET; 00017 00018 namespace 00019 { 00020 class sockaddr_ptr 00021 { 00022 public: 00023 sockaddr_ptr( const sockaddr* sa) : msa(*sa) {} 00024 const sockaddr_in& operator*() const { return msi; } 00025 const sockaddr_in* operator->() const { return &msi; } 00026 00027 private: 00028 union { sockaddr msa; sockaddr_in msi; }; 00029 }; 00030 } 00031 00032 std::string NET::resolveHostname( const std::string& hostname) 00033 { 00034 hostent* host = gethostbyname( hostname.c_str()); 00035 if( host == 0) 00036 { 00037 // strerror() will not work for gethostbyname() 00038 throw SocketException("Failed to resolve address (gethostbyname)", false); 00039 } 00040 return std::string(host->h_addr); 00041 } 00042 00043 unsigned short NET::resolveService( const std::string& service, const std::string& protocol) 00044 { 00045 struct servent* serv = getservbyname( service.c_str(), protocol.c_str()); 00046 00047 if(!serv) 00048 // Service is port number 00049 return std::atoi( service.c_str()); 00050 else 00051 // Found port (network byte order) by name 00052 return ntohs( serv->s_port); 00053 } 00054 00055 std::vector<std::string> NET::getNetworkInterfaces() 00056 { 00057 std::vector<std::string> ret; 00058 struct if_nameindex* index = if_nameindex(); 00059 00060 for( int i = 0; index[i].if_index != 0; ++i) 00061 ret.push_back( std::string( index[i].if_name)); 00062 00063 if_freenameindex(index); 00064 return ret; 00065 } 00066 00067 std::string NET::getInterfaceAddress( const std::string& interface) 00068 { 00069 struct ifreq ifr; 00070 00071 ifr.ifr_addr.sa_family = AF_INET; 00072 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00073 00074 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00075 if( sock < 0) 00076 throw SocketException("Couldn't create socket (getInterfaceAddress)"); 00077 00078 if( ioctl( sock, SIOCGIFADDR, &ifr) < 0) 00079 throw SocketException("ioctl failed (getInterfaceAddress)"); 00080 00081 ::close(sock); 00082 00083 return inet_ntoa( sockaddr_ptr( &ifr.ifr_addr)->sin_addr); 00084 } 00085 00086 void NET::setInterfaceAddress( const std::string& interface, const std::string& address) 00087 { 00088 struct ifreq ifr; 00089 00090 ifr.ifr_addr.sa_family = AF_INET; 00091 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00092 00093 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00094 if( sock < 0) 00095 throw SocketException("Couldn't create socket (setInterfaceAddress)"); 00096 00097 inet_aton( address.c_str(), &(reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr)); 00098 00099 if( ioctl( sock, SIOCSIFADDR, &ifr) < 0) 00100 throw SocketException("ioctl failed (setInterfaceAddress)"); 00101 00102 ::close(sock); 00103 } 00104 00105 std::string NET::getBroadcastAddress( const std::string& interface) 00106 { 00107 struct ifreq ifr; 00108 00109 ifr.ifr_addr.sa_family = AF_INET; 00110 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00111 00112 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00113 if( sock < 0) 00114 throw SocketException("Couldn't create socket (getBroadcastAddress)"); 00115 00116 if( ioctl( sock, SIOCGIFBRDADDR, &ifr) < 0) 00117 throw SocketException("ioctl failed (getInterfaceAddress)"); 00118 00119 ::close(sock); 00120 00121 return inet_ntoa( sockaddr_ptr( &ifr.ifr_broadaddr)->sin_addr); 00122 } 00123 00124 void NET::setBroadcastAddress( const std::string& interface, const std::string& address) 00125 { 00126 struct ifreq ifr; 00127 00128 ifr.ifr_addr.sa_family = AF_INET; 00129 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00130 00131 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00132 if( sock < 0) 00133 throw SocketException("Couldn't create socket (setBroadcastAddress)"); 00134 00135 inet_aton( address.c_str(), &(reinterpret_cast<sockaddr_in*>(&ifr.ifr_broadaddr)->sin_addr)); 00136 00137 if( ioctl( sock, SIOCSIFBRDADDR, &ifr) < 0) 00138 throw SocketException("ioctl failed (setBroadcastAddress)"); 00139 00140 ::close(sock); 00141 } 00142 00143 std::string NET::getNetmask( const std::string& interface) 00144 { 00145 struct ifreq ifr; 00146 00147 ifr.ifr_addr.sa_family = AF_INET; 00148 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00149 00150 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00151 if( sock < 0) 00152 throw SocketException("Couldn't create socket (getBroadcastAddress)"); 00153 00154 if( ioctl( sock, SIOCGIFNETMASK, &ifr) < 0) 00155 throw SocketException("ioctl failed (getNetmask)"); 00156 00157 ::close(sock); 00158 00159 return inet_ntoa( sockaddr_ptr( &ifr.ifr_netmask)->sin_addr); 00160 } 00161 00162 void NET::setNetmask( const std::string& interface, const std::string& address) 00163 { 00164 struct ifreq ifr; 00165 00166 ifr.ifr_addr.sa_family = AF_INET; 00167 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00168 00169 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00170 if( sock < 0) 00171 throw SocketException("Couldn't create socket (setNetmask)"); 00172 00173 inet_aton( address.c_str(), &(reinterpret_cast<sockaddr_in*>(&ifr.ifr_netmask)->sin_addr)); 00174 00175 if( ioctl( sock, SIOCSIFNETMASK, &ifr) < 0) 00176 throw SocketException("ioctl failed (setNetmask)"); 00177 00178 ::close(sock); 00179 } 00180 00181 std::string NET::getDestinationAddress( const std::string& interface) 00182 { 00183 struct ifreq ifr; 00184 00185 ifr.ifr_addr.sa_family = AF_INET; 00186 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00187 00188 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00189 if( sock < 0) 00190 throw SocketException("Couldn't create socket (getBroadcastAddress)"); 00191 00192 if( ioctl( sock, SIOCGIFDSTADDR, &ifr) < 0) 00193 throw SocketException("ioctl failed (getDestinationAddress)"); 00194 00195 ::close(sock); 00196 00197 return inet_ntoa( sockaddr_ptr( &ifr.ifr_dstaddr)->sin_addr); 00198 } 00199 00200 void NET::setDestinationAddress( const std::string& interface, const std::string& address) 00201 { 00202 struct ifreq ifr; 00203 00204 ifr.ifr_addr.sa_family = AF_INET; 00205 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00206 00207 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00208 if( sock < 0) 00209 throw SocketException("Couldn't create socket (setDestinationAddress)"); 00210 00211 inet_aton( address.c_str(), &(reinterpret_cast<sockaddr_in*>(&ifr.ifr_dstaddr)->sin_addr)); 00212 00213 if( ioctl( sock, SIOCSIFDSTADDR, &ifr) < 0) 00214 throw SocketException("ioctl failed (setDestinationAddress)"); 00215 00216 ::close(sock); 00217 } 00218 00219 int NET::getMTU( const std::string& interface) 00220 { 00221 struct ifreq ifr; 00222 00223 ifr.ifr_addr.sa_family = AF_INET; 00224 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00225 00226 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00227 if( sock < 0) 00228 throw SocketException("Couldn't create socket (getMTU)"); 00229 00230 if( ioctl( sock, SIOCGIFMTU, &ifr) < 0) 00231 throw SocketException("ioctl failed (getInterfaceAddress)"); 00232 00233 ::close(sock); 00234 00235 return ifr.ifr_mtu; 00236 } 00237 00238 void NET::setMTU( const std::string& interface, int mtu) 00239 { 00240 struct ifreq ifr; 00241 00242 ifr.ifr_addr.sa_family = AF_INET; 00243 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00244 00245 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00246 if( sock < 0) 00247 throw SocketException("Couldn't create socket (setMTU)"); 00248 00249 ifr.ifr_mtu = mtu; 00250 00251 if( ioctl( sock, SIOCSIFDSTADDR, &ifr) < 0) 00252 throw SocketException("ioctl failed (setMTU)"); 00253 00254 ::close(sock); 00255 } 00256 00257 std::string NET::getHardwareAddress( const std::string& interface, char separationChar) 00258 { 00259 struct ifreq ifr; 00260 00261 ifr.ifr_addr.sa_family = AF_INET; 00262 std::strncpy( ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name)); 00263 00264 int sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP); 00265 if( sock < 0) 00266 throw SocketException("Couldn't create socket (getMTU)"); 00267 00268 if( ioctl( sock, SIOCGIFHWADDR, &ifr) < 0) 00269 throw SocketException("ioctl failed (getInterfaceAddress)"); 00270 00271 ::close(sock); 00272 00273 switch( ifr.ifr_hwaddr.sa_family) { 00274 default: 00275 throw SocketException("Invalid Hardware type (getHardwareAddress)"); 00276 break; 00277 case ARPHRD_NETROM: 00278 case ARPHRD_ETHER: 00279 case ARPHRD_PPP: 00280 case ARPHRD_EETHER: 00281 case ARPHRD_IEEE802: 00282 break; 00283 } 00284 00285 std::ostringstream str; 00286 str << std::hex << std::setw(2) << std::setfill('0'); 00287 00288 for( int i = 0; i <= 4; ++i) 00289 { 00290 str << std::uppercase 00291 << static_cast<int>( reinterpret_cast<unsigned char*>( ifr.ifr_addr.sa_data)[i]) 00292 << separationChar; 00293 } 00294 00295 str << std::uppercase 00296 << static_cast<int>( reinterpret_cast<unsigned char*>( ifr.ifr_addr.sa_data)[5]); 00297 return str.str(); 00298 }