MCPcopy Create free account
hub / github.com/NazaraEngine/NazaraEngine / ParseIPAddress

Function ParseIPAddress

src/Nazara/Network/AlgorithmNetwork.cpp:203–393  ·  view source on GitHub ↗

! * \ingroup network * \brief Parse a textual IPv4 or IPv6 address * \return true If successful * * From http://rosettacode.org/wiki/Parse_an_IP_Address * Parse a textual IPv4 or IPv6 address, optionally with port, into a binary * array (for the address, in host order), and an optionally provided port. * Also, indicate which of those forms (4 or 6) was parsed. * * \param addressPtr C-str

Source from the content-addressed store, hash-verified

201 * \remark Produces a NazaraAssert if result is invalid
202 */
203 bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port, bool* isIPv6, const char** endOfRead)
204 {
205 NazaraAssert(addressPtr, "Invalid address string");
206 NazaraAssert(result, "Invalid result pointer");
207
208 //find first colon, dot, and open bracket
209 const char* colonPtr = std::strchr(addressPtr, ':');
210 const char* dotPtr = std::strchr(addressPtr, '.');
211 const char* openBracketPtr = std::strchr(addressPtr, '[');
212
213 // we'll consider this to (probably) be IPv6 if we find an open
214 // bracket, or an absence of dots, or if there is a colon, and it
215 // precedes any dots that may or may not be there
216 bool detectedIPv6 = openBracketPtr || !dotPtr || (colonPtr && (!dotPtr || colonPtr < dotPtr));
217
218 // OK, now do a little further sanity check our initial guess...
219 if (detectedIPv6)
220 {
221 // if open bracket, then must have close bracket that follows somewhere
222 const char* closeBracketPtr = std::strchr(addressPtr, ']');
223 if (openBracketPtr && (!closeBracketPtr || closeBracketPtr < openBracketPtr))
224 return false;
225 }
226 else // probably ipv4
227 {
228 // dots must exist, and precede any colons
229 if (!dotPtr || (colonPtr && colonPtr < dotPtr))
230 return false;
231 }
232
233 // OK, there should be no correctly formed strings which are miscategorized,
234 // and now any format errors will be found out as we continue parsing
235 // according to plan.
236 if (!detectedIPv6) //try to parse as IPv4
237 {
238 // 4 dotted quad decimal; optional port if there is a colon
239 // since there are just 4, and because the last one can be terminated
240 // differently, I'm just going to unroll any potential loop.
241 UInt8* resultPtr = result;
242
243 for (unsigned int i = 0; i < 4; ++i)
244 {
245 unsigned int value;
246 if (!Detail::ParseDecimal(addressPtr, &value, &addressPtr) || value > 255) //must be in range and followed by dot and nonempty
247 return false;
248
249 if (i != 3)
250 {
251 if (*addressPtr != '.')
252 return false;
253
254 addressPtr++;
255 }
256
257 *resultPtr++ = static_cast<UInt8>(value);
258 }
259 }
260 else // try to parse as IPv6

Callers 1

BuildFromAddressMethod · 0.85

Calls 2

ParseDecimalFunction · 0.85
ParseHexadecimalFunction · 0.85

Tested by

no test coverage detected