Back to index

libsfml  1.6+dfsg2
IPAddress.cpp
Go to the documentation of this file.
00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Network/IPAddress.hpp>
00029 #include <SFML/Network/Http.hpp>
00030 #include <SFML/Network/SocketHelper.hpp>
00031 #include <string.h>
00032 
00033 
00034 namespace sf
00035 {
00039 const IPAddress IPAddress::LocalHost("127.0.0.1");
00040 
00041 
00045 IPAddress::IPAddress() :
00046 myAddress(INADDR_NONE)
00047 {
00048 
00049 }
00050 
00051 
00055 IPAddress::IPAddress(const std::string& Address)
00056 {
00057     // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
00058     myAddress = inet_addr(Address.c_str());
00059 
00060     // If not successful, try to convert it as a host name
00061     if (!IsValid())
00062     {
00063         hostent* Host = gethostbyname(Address.c_str());
00064         if (Host)
00065         {
00066             // Host found, extract its IP address
00067             myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
00068         }
00069         else
00070         {
00071             // Host name not found on the network
00072             myAddress = INADDR_NONE;
00073         }
00074     }
00075 }
00076 
00077 
00082 IPAddress::IPAddress(const char* Address)
00083 {
00084     // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
00085     myAddress = inet_addr(Address);
00086 
00087     // If not successful, try to convert it as a host name
00088     if (!IsValid())
00089     {
00090         hostent* Host = gethostbyname(Address);
00091         if (Host)
00092         {
00093             // Host found, extract its IP address
00094             myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
00095         }
00096         else
00097         {
00098             // Host name not found on the network
00099             myAddress = INADDR_NONE;
00100         }
00101     }
00102 }
00103 
00104 
00108 IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3)
00109 {
00110     myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
00111 }
00112 
00113 
00117 IPAddress::IPAddress(Uint32 Address)
00118 {
00119     myAddress = htonl(Address);
00120 }
00121 
00122 
00126 bool IPAddress::IsValid() const
00127 {
00128     return myAddress != INADDR_NONE;
00129 }
00130 
00131 
00135 std::string IPAddress::ToString() const
00136 {
00137     in_addr InAddr;
00138     InAddr.s_addr = myAddress;
00139 
00140     return inet_ntoa(InAddr);
00141 }
00142 
00143 
00147 Uint32 IPAddress::ToInteger() const
00148 {
00149     return ntohl(myAddress);
00150 }
00151 
00152 
00156 IPAddress IPAddress::GetLocalAddress()
00157 {
00158     // The method here is to connect a UDP socket to anyone (here to localhost),
00159     // and get the local socket address with the getsockname function.
00160     // UDP connection will not send anything to the network, so this function won't cause any overhead.
00161 
00162     IPAddress LocalAddress;
00163 
00164     // Create the socket
00165     SocketHelper::SocketType Socket = socket(PF_INET, SOCK_DGRAM, 0);
00166     if (Socket == SocketHelper::InvalidSocket())
00167         return LocalAddress;
00168 
00169     // Build the host address (use a random port)
00170     sockaddr_in SockAddr;
00171     memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
00172     SockAddr.sin_addr.s_addr = INADDR_LOOPBACK;
00173     SockAddr.sin_family      = AF_INET;
00174     SockAddr.sin_port        = htons(4567);
00175 
00176     // Connect the socket
00177     if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
00178     {
00179         SocketHelper::Close(Socket);
00180         return LocalAddress;
00181     }
00182  
00183     // Get the local address of the socket connection
00184     SocketHelper::LengthType Size = sizeof(SockAddr);
00185     if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1)
00186     {
00187         SocketHelper::Close(Socket);
00188         return LocalAddress;
00189     }
00190 
00191     // Close the socket
00192     SocketHelper::Close(Socket);
00193 
00194     // Finally build the IP address
00195     LocalAddress.myAddress = SockAddr.sin_addr.s_addr;
00196 
00197     return LocalAddress;
00198 }
00199 
00200 
00204 IPAddress IPAddress::GetPublicAddress(float Timeout)
00205 {
00206     // The trick here is more complicated, because the only way
00207     // to get our public IP address is to get it from a distant computer.
00208     // Here we get the web page from http://www.sfml-dev.org/ip-provider.php
00209     // and parse the result to extract our IP address
00210     // (not very hard : the web page contains only our IP address).
00211 
00212     Http Server("www.sfml-dev.org");
00213     Http::Request Request(Http::Request::Get, "/ip-provider.php");
00214     Http::Response Page = Server.SendRequest(Request, Timeout);
00215     if (Page.GetStatus() == Http::Response::Ok)
00216         return IPAddress(Page.GetBody());
00217 
00218     // Something failed: return an invalid address
00219     return IPAddress();
00220 }
00221 
00222 
00226 bool IPAddress::operator ==(const IPAddress& Other) const
00227 {
00228     return myAddress == Other.myAddress;
00229 }
00230 
00231 
00235 bool IPAddress::operator !=(const IPAddress& Other) const
00236 {
00237     return myAddress != Other.myAddress;
00238 }
00239 
00240 
00244 bool IPAddress::operator <(const IPAddress& Other) const
00245 {
00246     return myAddress < Other.myAddress;
00247 }
00248 
00249 
00253 bool IPAddress::operator >(const IPAddress& Other) const
00254 {
00255     return myAddress > Other.myAddress;
00256 }
00257 
00258 
00262 bool IPAddress::operator <=(const IPAddress& Other) const
00263 {
00264     return myAddress <= Other.myAddress;
00265 }
00266 
00267 
00271 bool IPAddress::operator >=(const IPAddress& Other) const
00272 {
00273     return myAddress >= Other.myAddress;
00274 }
00275 
00276 
00280 std::istream& operator >>(std::istream& Stream, IPAddress& Address)
00281 {
00282     std::string Str;
00283     Stream >> Str;
00284     Address = IPAddress(Str);
00285 
00286     return Stream;
00287 }
00288 
00289 
00293 std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address)
00294 {
00295     return Stream << Address.ToString();
00296 }
00297 
00298 } // namespace sf