IPAddress.cpp
1 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
24 
26 // Headers
28 #include <SFML/Network/IPAddress.hpp>
29 #include <SFML/Network/Http.hpp>
30 #include <SFML/Network/SocketHelper.hpp>
31 #include <string.h>
32 
33 
34 namespace sf
35 {
39 const IPAddress IPAddress::LocalHost("127.0.0.1");
40 
41 
46 myAddress(INADDR_NONE)
47 {
48 
49 }
50 
51 
55 IPAddress::IPAddress(const std::string& Address)
56 {
57  // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
58  myAddress = inet_addr(Address.c_str());
59 
60  // If not successful, try to convert it as a host name
61  if (!IsValid())
62  {
63  hostent* Host = gethostbyname(Address.c_str());
64  if (Host)
65  {
66  // Host found, extract its IP address
67  myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
68  }
69  else
70  {
71  // Host name not found on the network
72  myAddress = INADDR_NONE;
73  }
74  }
75 }
76 
77 
82 IPAddress::IPAddress(const char* Address)
83 {
84  // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
85  myAddress = inet_addr(Address);
86 
87  // If not successful, try to convert it as a host name
88  if (!IsValid())
89  {
90  hostent* Host = gethostbyname(Address);
91  if (Host)
92  {
93  // Host found, extract its IP address
94  myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
95  }
96  else
97  {
98  // Host name not found on the network
99  myAddress = INADDR_NONE;
100  }
101  }
102 }
103 
104 
108 IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3)
109 {
110  myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
111 }
112 
113 
117 IPAddress::IPAddress(Uint32 Address)
118 {
119  myAddress = htonl(Address);
120 }
121 
122 
126 bool IPAddress::IsValid() const
127 {
128  return myAddress != INADDR_NONE;
129 }
130 
131 
135 std::string IPAddress::ToString() const
136 {
137  in_addr InAddr;
138  InAddr.s_addr = myAddress;
139 
140  return inet_ntoa(InAddr);
141 }
142 
143 
147 Uint32 IPAddress::ToInteger() const
148 {
149  return ntohl(myAddress);
150 }
151 
152 
157 {
158  // The method here is to connect a UDP socket to anyone (here to localhost),
159  // and get the local socket address with the getsockname function.
160  // UDP connection will not send anything to the network, so this function won't cause any overhead.
161 
162  IPAddress LocalAddress;
163 
164  // Create the socket
165  SocketHelper::SocketType Socket = socket(PF_INET, SOCK_DGRAM, 0);
166  if (Socket == SocketHelper::InvalidSocket())
167  return LocalAddress;
168 
169  // Build the host address (use a random port)
170  sockaddr_in SockAddr;
171  memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
172  SockAddr.sin_addr.s_addr = INADDR_LOOPBACK;
173  SockAddr.sin_family = AF_INET;
174  SockAddr.sin_port = htons(4567);
175 
176  // Connect the socket
177  if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
178  {
179  SocketHelper::Close(Socket);
180  return LocalAddress;
181  }
182 
183  // Get the local address of the socket connection
184  SocketHelper::LengthType Size = sizeof(SockAddr);
185  if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1)
186  {
187  SocketHelper::Close(Socket);
188  return LocalAddress;
189  }
190 
191  // Close the socket
192  SocketHelper::Close(Socket);
193 
194  // Finally build the IP address
195  LocalAddress.myAddress = SockAddr.sin_addr.s_addr;
196 
197  return LocalAddress;
198 }
199 
200 
205 {
206  // The trick here is more complicated, because the only way
207  // to get our public IP address is to get it from a distant computer.
208  // Here we get the web page from http://www.sfml-dev.org/ip-provider.php
209  // and parse the result to extract our IP address
210  // (not very hard : the web page contains only our IP address).
211 
212  Http Server("www.sfml-dev.org");
213  Http::Request Request(Http::Request::Get, "/ip-provider.php");
214  Http::Response Page = Server.SendRequest(Request, Timeout);
215  if (Page.GetStatus() == Http::Response::Ok)
216  return IPAddress(Page.GetBody());
217 
218  // Something failed: return an invalid address
219  return IPAddress();
220 }
221 
222 
226 bool IPAddress::operator ==(const IPAddress& Other) const
227 {
228  return myAddress == Other.myAddress;
229 }
230 
231 
235 bool IPAddress::operator !=(const IPAddress& Other) const
236 {
237  return myAddress != Other.myAddress;
238 }
239 
240 
244 bool IPAddress::operator <(const IPAddress& Other) const
245 {
246  return myAddress < Other.myAddress;
247 }
248 
249 
253 bool IPAddress::operator >(const IPAddress& Other) const
254 {
255  return myAddress > Other.myAddress;
256 }
257 
258 
262 bool IPAddress::operator <=(const IPAddress& Other) const
263 {
264  return myAddress <= Other.myAddress;
265 }
266 
267 
271 bool IPAddress::operator >=(const IPAddress& Other) const
272 {
273  return myAddress >= Other.myAddress;
274 }
275 
276 
280 std::istream& operator >>(std::istream& Stream, IPAddress& Address)
281 {
282  std::string Str;
283  Stream >> Str;
284  Address = IPAddress(Str);
285 
286  return Stream;
287 }
288 
289 
293 std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address)
294 {
295  return Stream << Address.ToString();
296 }
297 
298 } // namespace sf
This class wraps an HTTP response, which is basically :
Definition: Http.hpp:168
bool operator>=(const IPAddress &Other) const
Comparison operator >=.
Definition: IPAddress.cpp:271
IPAddress()
Default constructor – constructs an invalid address.
Definition: IPAddress.cpp:45
bool operator!=(const IPAddress &Other) const
Comparison operator !=.
Definition: IPAddress.cpp:235
bool operator<=(const IPAddress &Other) const
Comparison operator <=.
Definition: IPAddress.cpp:262
bool operator==(const IPAddress &Other) const
Comparison operator ==.
Definition: IPAddress.cpp:226
static IPAddress GetPublicAddress(float Timeout=0.f)
Get the computer&#39;s public IP address (from the web point of view).
Definition: IPAddress.cpp:204
bool operator>(const IPAddress &Other) const
Comparison operator >
Definition: IPAddress.cpp:253
Uint32 ToInteger() const
Get an integer representation of the address.
Definition: IPAddress.cpp:147
Most common code returned when operation was successful.
Definition: Http.hpp:179
static SocketType InvalidSocket()
Return the value of the invalid socket.
Status GetStatus() const
Get the header&#39;s status code.
Definition: Http.cpp:199
std::string ToString() const
Get a string representation of the address.
Definition: IPAddress.cpp:135
static IPAddress GetLocalAddress()
Get the computer&#39;s local IP address (from the LAN point of view)
Definition: IPAddress.cpp:156
IPAddress provides easy manipulation of IP v4 addresses.
Definition: IPAddress.hpp:42
Request in get mode, standard method to retrieve a page.
Definition: Http.hpp:63
bool IsValid() const
Tell if the address is a valid one.
Definition: IPAddress.cpp:126
const std::string & GetBody() const
Get the body of the response.
Definition: Http.cpp:230
static const IPAddress LocalHost
Local host address (to connect to the same computer)
Definition: IPAddress.hpp:196
This class wraps an HTTP request, which is basically :
Definition: Http.hpp:54
bool operator<(const IPAddress &Other) const
Comparison operator <.
Definition: IPAddress.cpp:244
static bool Close(SocketType Socket)
Close / destroy a socket.
This class provides methods for manipulating the HTTP protocol (described in RFC 1945).
Definition: Http.hpp:45
Response SendRequest(const Request &Req, float Timeout=0.f)
Send a HTTP request and return the server&#39;s response.
Definition: Http.cpp:366