Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 43220)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 43221)
@@ -336,4 +336,5 @@
 	common/misc/term.cpp \
 	common/misc/uri.cpp \
+	common/net/netaddrstr.cpp \
 	common/path/rtPathRootSpecLen.cpp \
 	common/path/rtPathVolumeSpecLen.cpp \
@@ -377,5 +378,4 @@
 	common/string/RTStrCopyP.cpp \
 	common/string/RTStrCopyPEx.cpp \
-	common/string/RTStrIPv6.cpp \
 	common/string/RTStrNCmp.cpp \
 	common/string/RTStrNLen.cpp \
Index: /trunk/src/VBox/Runtime/common/net/netaddrstr.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/net/netaddrstr.cpp	(revision 43221)
+++ /trunk/src/VBox/Runtime/common/net/netaddrstr.cpp	(revision 43221)
@@ -0,0 +1,1286 @@
+/* $Id$ */
+/** @file
+ * IPRT - Network Address String Handling.
+ */
+
+/*
+ * Contributed by Oliver Loch.
+ *
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/net.h>
+
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/stream.h>
+#include "internal/string.h"
+
+
+/** @page pg_rtnetipv6_addr IPv6 Address Format
+ *
+ * IPv6 Addresses, their representation in text and other problems.
+ *
+ * The following is based on:
+ *
+ * - http://tools.ietf.org/html/rfc4291
+ * - http://tools.ietf.org/html/rfc5952
+ * - http://tools.ietf.org/html/rfc6052
+ *
+ *
+ * Before you start using those functions, you should have an idea of
+ * what you're dealing with, before you come and blame the functions...
+ *
+ * First of all, the address itself:
+ *
+ * An address is written like this: (READ THIS FINE MANUAL!)
+ *
+ * - 2001:db8:abc:def::1
+ *
+ * The characters between two colons are called a "hextet".
+ * Each hextet consists of four characters and each IPv6 address
+ * consists of a maximum of eight hextets. So a full blown address
+ * would look like this:
+ *
+ * - 1111:2222:3333:4444:5555:6666:7777:8888
+ *
+ * The allowed characters are "0123456789abcdef". They have to be
+ * lower case. Upper case is not allowed.
+ *
+ * *** Gaps and adress shortening
+ *
+ * If an address contains hextets that contain only "0"s, they
+ * can be shortened, like this:
+ *
+ * - 1111:2222:0000:0000:0000:0000:7777:8888 -> 1111:2222::7777:8888
+ *
+ * The double colon represents the hextets that have been shortened "::".
+ * The "::" will be called "gap" from now on.
+ *
+ * When shortening an address, there are some special rules that need to be applied:
+ *
+ * - Shorten always the longest group of hextets.
+ *
+ *   Let's say, you have this address: 2001:db8:0:0:0:1:0:0 then it has to be
+ *   shortened to "2001:db8::1:0:0". Shortening to "2001:db8:0:0:0:1::" would
+ *   return an error.
+ *
+ * - Two or more gaps the same size.
+ *
+ *   Let's say you have this address: 2001:db8:0:0:1:0:0:1. As you can see, there
+ *   are two gaps, both the size of two hextets. If you shorten the last two hextets,
+ *   you end up in pain, as the RFC forbids this, so the correct address is:
+ *   "2001:db8::1:0:0:1"
+ *
+ * It's important to note that an address can only be shortened ONE TIME!
+ * This is invalid: "2001:db8::1::1"
+ *
+ * *** The scope.
+ *
+ * Each address has a so called "scope" it is added to the end of the address,
+ * separated by a percent sign "%". If there is no scope at the end, it defaults
+ * to "0".
+ *
+ * So "2001:db8::1" is the same as "2001:db8::1%0".
+ *
+ * As in IPv6 all network interfaces can/should have the same address, the scope
+ * gives you the ability to choose on which interface the system should listen.
+ *
+ * AFAIK, the scope can be used with unicast as well as link local addresses, but
+ * it is mandatory with link local addresses (starting with fe80::).
+ *
+ * On Linux the default scope is the interface's name. On Windows it's just the index
+ * of the interface. Run "route print -6" in the shell, to see the interface's index
+ * on Winodows.
+ *
+ * All functions can deal with the scope, and DO NOT warn if you put garbage there.
+ *
+ * *** Port added to the IPv6 address
+ *
+ * There is only one way to add a port to an IPv6 address is to embed it in brackets:
+ *
+ * [2001:db8::1]:12345
+ *
+ * This gives you the address "2001:db8::1" and the port "12345".
+ *
+ * What also works, but is not recommended by rfc is to separate the port
+ * by a dot:
+ *
+ * 2001:db8::1.12345
+ *
+ * It even works with embedded IPv4 addresses.
+ *
+ * *** Special addresses and how they are written
+ *
+ * The following are notations to represent "special addresses".
+ *
+ * "::" IN6ADDR_ANY
+ * ":::123" IN6ADDR_ANY with port "123"
+ * "[::]:123" IN6ADDR_ANY with port "123"
+ * "[:::123]" -> NO. Not allowed and makes no sense
+ * "::1" -> address of the loopback device (127.0.0.1 in v4)
+ *
+ * On systems with dual sockets, one can use so called embedded IPv4 addresses:
+ *
+ * "::ffff:192.168.1.1" results in the IPv6 address "::ffff:c0a8:0101" as two octets
+ * of the IPv4 address will be converted to one hextet in the IPv6 address.
+ *
+ * The prefix of such addresses MUST BE "::ffff:", 10 bytes as zero and two bytes as 255.
+ *
+ * The so called IPv4-compatible IPv6 addresses are deprecated and no longer in use.
+ *
+ * *** Valid addresses and string
+ *
+ * If you use any of the IPv6 address functions, keep in mind, that those addresses
+ * are all returning "valid" even if the underlying system (e.g. VNC) doesn't like
+ * such strings.
+ *
+ * [2001:db8::1]
+ * [2001:db8::1]:12345
+ *
+ * and so on. So to make sure you only pass the underlying software a pure IPv6 address
+ * without any garbage, you should use the "outAddress" parameters to get a RFC compliant
+ * address returned.
+ *
+ * So after reading the above, you'll start using the functions and see a bool called
+ * "followRfc" which is true by default. This is what this bool does:
+ *
+ * The following addresses all represent the exact same address:
+ *
+ * 1 - 2001:db8::1
+ * 2 - 2001:db8:0::1
+ * 3 - 2001:0db8:0000:0000:0000:0000:0000:0001
+ * 4 - 2001:DB8::1
+ * 5 - [2001:db8::1]
+ * 6 - [2001:db8:0::1]
+ *
+ * According to RFC 5952, number two, three, four and six are invalid.
+ *
+ * #2 - because there is a single hextet that hasn't been shortened
+ *
+ * #3 - because there has nothing been shortened (hextets 3 to 7) and
+ *      there are leading zeros in at least one hextet ("0db8")
+ *
+ * #4 - all characters in an IPv6 address have to be lower case
+ *
+ * #6 - same as two but included in brackets
+ *
+ * If you follow RFC, the above addresses are not converted and an
+ * error is returned. If you turn RFC off, you will get the expected
+ * representation of the address.
+ *
+ * It's a nice way to convert "weird" addresses to rfc compliant addresses
+ *
+ */
+
+
+/**
+ * Parses any string and tests if it is an IPv6 Address
+ *
+ * This function should NOT be used directly. If you do, note
+ * that no security checks are done at the moment. This can change.
+ *
+ * @returns iprt sstatus code.
+ * @param pszAddress       The strin that holds the IPv6 address
+ * @param addressLength    The length of pszAddress
+ * @param pszAddressOut    Returns a plain, full blown IPv6 address
+ *                         as a char array
+ * @param addressOutSize   The size of pszAddressOut (length)
+ * @param pPortOut         32 bit unsigned integer, holding the port
+ *                         If pszAddress doesn't contain a port, it's 0
+ * @param pszScopeOut      Returns the scope of the address, if none it's 0
+ * @param scopeOutSize     sizeof(pszScopeOut)
+ * @param pBrackets        returns true if the address was enclosed in brackets
+ * @param pEmbeddedV4      returns true if the address is an embedded IPv4 address
+ * @param followRfc        if set to true, the function follows RFC (default)
+ */
+static int rtStrParseAddrStr6(const char *pszAddress, size_t addressLength, char *pszAddressOut, size_t addressOutSize, uint32_t *pPortOut, char *pszIfIdOut, size_t ifIdOutSize, bool *pBrackets, bool *pEmbeddedV4, bool followRfc)
+{
+    /************************\
+     *  Pointer Hell Ahead  *
+    \************************/
+
+    const char szIpV6AddressChars[] = "ABCDEF01234567890abcdef.:[]%"; // order IMPORTANT
+    const char szIpV4AddressChars[] = "01234567890.:[]"; // order IMPORTANT
+    const char szLinkLocalPrefix[] = "FfEe8800"; //
+    const char *pszIpV6AddressChars = NULL, *pszIpV4AddressChars = NULL, *pszLinkLocalPrefix = NULL;
+
+    char *pszSourceAddress = NULL, *pszSourceAddressStart = NULL;
+    char *pszResultAddress = NULL, *pszResultAddressStart = NULL;
+    char *pszResultAddress4 = NULL, *pszResultAddress4Start = NULL;
+    char *pszResultPort = NULL, *pszResultPortStart = NULL;
+    char *pszInternalAddress = NULL, *pszInternalAddressStart = NULL;
+    char *pszInternalPort = NULL, *pszInternalPortStart = NULL;
+
+    char *pStart = NULL, *pNow = NULL, *pNext = NULL, *pNowChar = NULL, *pIfId = NULL, *pIfIdEnd = NULL;
+    char *pNowDigit = NULL, *pFrom = NULL, *pTo = NULL, *pLast = NULL;
+    char *pGap = NULL, *pMisc = NULL, *pDotStart = NULL, *pFieldStart = NULL, *pFieldEnd = NULL;
+    char *pFieldStartLongest = NULL, *pBracketOpen = NULL, *pBracketClose = NULL;
+    char *pszRc = NULL;
+
+    bool isLinkLocal = false;
+    char szDummy[4];
+
+    uint8_t *pByte = NULL;
+    uint32_t byteOut = 0;
+    uint16_t returnValue = 0;
+    uint32_t colons = 0;
+    uint32_t colonsOverAll = 0;
+    uint32_t fieldLength = 0;
+    uint32_t dots = 0;
+    size_t gapSize = 0;
+    uint32_t intPortOut = 0;
+
+    pszIpV4AddressChars = &szIpV4AddressChars[0];
+    pszIpV6AddressChars = &szIpV6AddressChars[6];
+    pszLinkLocalPrefix = &szLinkLocalPrefix[6];
+
+    if (!followRfc)
+        pszIpV6AddressChars = &szIpV6AddressChars[0];
+
+    if (addressLength<2)
+        returnValue = 711;
+
+    pszResultAddressStart = (char *)RTMemTmpAlloc(34);
+    pszInternalAddressStart = (char *)RTMemTmpAlloc(34);
+    pszInternalPortStart = (char * )RTMemTmpAlloc(10);
+
+    if (! (pszResultAddressStart && pszInternalAddressStart && pszInternalPortStart))
+    {
+        if (pszResultAddressStart)
+            RTMemTmpFree(pszResultAddressStart);
+
+        if (pszInternalAddressStart)
+            RTMemTmpFree(pszInternalAddressStart);
+
+        if (pszInternalPortStart)
+            RTMemTmpFree(pszInternalPortStart);
+
+        return -701;
+    }
+
+    memset(szDummy, '\0', 4);
+
+    pszResultAddress = pszResultAddressStart;
+    memset(pszResultAddressStart, '\0', 34);
+
+    pszInternalAddress = pszInternalAddressStart;
+    memset(pszInternalAddressStart, '\0' , 34);
+
+    pszInternalPort = pszInternalPortStart;
+    memset(pszInternalPortStart, '\0', 10);
+
+    pszSourceAddress = pszSourceAddressStart = (char *)pszAddress;
+
+    pFrom = pTo = pStart = pLast = pszSourceAddressStart;
+
+    while (*pszSourceAddress != '\0' && !returnValue)
+    {
+        pNow = NULL;
+        pNext = NULL;
+        pNowChar = NULL;
+        pNowDigit = NULL;
+
+        pNow = pszSourceAddress;
+        pNext = pszSourceAddress + 1;
+
+        if (!pFrom)
+            pFrom = pTo = pNow;
+
+        pNowChar = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars));
+        pNowDigit = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars) - 5);
+
+        if (pszResultPort)
+        {
+            if (pLast && (pszResultPort == pszSourceAddressStart))
+            {
+                if (*pLast == '\0')
+                    returnValue = 721;
+
+                pszResultPortStart = (char *)RTMemTmpAlloc(10);
+
+                if (!pszResultPortStart)
+                    returnValue = 702;
+
+                memset(pszResultPortStart, '\0', 10);
+                pszResultPort = pszResultPortStart;
+                pszSourceAddress = pLast;
+                pMisc = pLast;
+                pLast = NULL;
+                continue;
+            }
+
+            pNowDigit = NULL;
+            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);
+
+            if (strlen(pszResultPortStart) == 5)
+                returnValue = 11;
+
+            if (*pNow == '0' && pszResultPort == pszResultPortStart && *pNext != '\0' && (pNow - pMisc) < 5 )
+            {
+                pszSourceAddress++;
+                continue;
+            }
+
+            if (pNowDigit)
+            {
+                *pszResultPort = *pNowDigit;
+                pszResultPort++;
+                pszSourceAddress++;
+                continue;
+            }
+            else
+                returnValue = 12;
+        }
+
+        if (pszResultAddress4)
+        {
+            if (pszResultAddress4 == pszSourceAddressStart && pLast)
+            {
+                dots = 0;
+                pszResultAddress4 = NULL;
+                pszResultAddress4Start = NULL;
+                pszResultAddress4Start = (char *)RTMemTmpAlloc(20);
+
+                if (!pszResultAddress4Start)
+                {
+                    returnValue = 401;
+                    break;
+                }
+
+                memset(pszResultAddress4Start, '\0', 20);
+                pszResultAddress4 = pszResultAddress4Start;
+                pszSourceAddress = pLast;
+                pFrom = pLast;
+                pTo = pLast;
+                pLast = NULL;
+                continue;
+            }
+
+            pTo = pNow;
+            pNowDigit = NULL;
+            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);
+
+            if (!pNowDigit && *pNow != '.' && *pNow != ']' && *pNow != ':' && *pNow != '%')
+                returnValue = 412;
+
+            if ((pNow - pFrom) > 3)
+            {
+                returnValue = 402;
+                break;
+            }
+
+            if (pNowDigit && *pNext != '\0')
+            {
+                pszSourceAddress++;
+                continue;
+            }
+
+            if (!pNowDigit  && !pBracketOpen && (*pNext == '.' || *pNext == ']' || *pNext == ':'))
+                returnValue = 411;
+
+            memset(pszResultAddress4, '0', 3);
+            pMisc = pszResultAddress4 + 2;
+            pszResultAddress4 = pszResultAddress4 + 3;
+
+            if (*pNow != '.' && !pNowDigit && strlen(pszResultAddress4Start) < 9)
+                returnValue = 403;
+
+            if ((pTo - pFrom) > 0)
+                pTo--;
+
+            dots++;
+
+            while (pTo >= pFrom)
+            {
+                *pMisc = *pTo;
+                pMisc--;
+                pTo--;
+            }
+
+            if (dots == 4 && *pNow == '.')
+            {
+                if (!pBracketOpen)
+                {
+                    pszResultPort = pszSourceAddressStart;
+                    pLast = pNext;
+                }
+                else
+                {
+                    returnValue = 409;
+                }
+            }
+
+            dots = 0;
+
+            pFrom = pNext;
+            pTo = pNext;
+
+            if (strlen(pszResultAddress4Start) > 11)
+                pszResultAddress4 = NULL;
+
+            if ((*pNow == ':' || *pNow == '.') && strlen(pszResultAddress4Start) == 12)
+            {
+                pLast = pNext;
+                pszResultPort = pszSourceAddressStart;
+            }
+
+            if (*pNow == '%')
+            {
+                pIfId =  pNow;
+                pLast = pNow;
+                continue;
+            }
+            pszSourceAddress = pNext;
+
+            if (*pNow != ']')
+                continue;
+
+            pFrom = pNow;
+            pTo = pNow;
+        }
+
+        if (pIfId && (!pIfIdEnd))
+        {
+            if (*pIfId == '%' && pIfId == pLast && *pNext != '\0')
+            {
+                pFrom = pNext;
+                pIfId = pNext;
+                pLast = NULL;
+
+                pszSourceAddress++;
+                continue;
+            }
+
+            if (*pNow == '%' && pIfId <= pNow)
+            {
+                returnValue = 442;
+                break;
+            }
+
+            if (*pNow != ']' && *pNext != '\0')
+            {
+                pTo = pNow;
+                pszSourceAddress++;
+                continue;
+            }
+
+            if (*pNow == ']')
+            {
+                pIfIdEnd = pNow - 1;
+                pFrom = pNow;
+                pTo = pNow;
+                continue;
+            }
+            else
+            {
+                pIfIdEnd = pNow;
+                pFrom = NULL;
+                pTo = NULL;
+                pszSourceAddress++;
+                continue;
+            }
+        }
+
+        if (!pNowChar)
+        {
+            returnValue = 254;
+
+            if (followRfc)
+            {
+                pMisc = (char *)memchr(&szIpV6AddressChars[0], *pNow, strlen(&szIpV6AddressChars[0]));
+
+                if (pMisc)
+                    returnValue = 253;
+            }
+        }
+
+        if (strlen(pszResultAddressStart) > 32 && !pszResultAddress4Start)
+            returnValue = 255;
+
+        if (pNowDigit && *pNext != '\0' && colons == 0)
+        {
+            pTo = pNow;
+            pszSourceAddress++;
+            continue;
+        }
+
+        if (*pNow == ':' && *pNext != '\0')
+        {
+            colonsOverAll++;
+            colons++;
+            pszSourceAddress++;
+            continue;
+        }
+
+        if (*pNow == ':' )
+        {
+            colons++;
+            colonsOverAll++;
+        }
+
+        if (*pNow == '.')
+        {
+            pMisc = pNow;
+
+            while (*pMisc != '\0' && *pMisc != ']')
+            {
+                if (*pMisc == '.')
+                    dots++;
+
+                pMisc++;
+            }
+        }
+
+        if (*pNow == ']')
+        {
+            if (pBracketClose)
+                returnValue = 77;
+
+            if (!pBracketOpen)
+                returnValue = 22;
+
+            if (*pNext == ':' || *pNext == '.')
+            {
+                pszResultPort = pszSourceAddressStart;
+                pLast = pNext + 1;
+            }
+
+            if (pFrom == pNow)
+                pFrom = NULL;
+
+            pBracketClose = pNow;
+        }
+
+        if (*pNow == '[')
+        {
+            if (pBracketOpen)
+                returnValue = 23;
+
+            if (pStart != pNow)
+                returnValue = 24;
+
+            pBracketOpen = pNow;
+            pStart++;
+            pFrom++;
+            pszSourceAddress++;
+            continue;
+        }
+
+        if (*pNow == '%')
+        {
+            if (pIfId)
+                returnValue = 441;
+
+            pLast = pNext;
+            pIfId = pNext;
+        }
+
+        if (colons > 0)
+        {
+            if (colons == 1)
+            {
+                if (pStart + 1 == pNow )
+                    returnValue = 31;
+
+                if (*pNext == '\0' && !pNowDigit)
+                    returnValue = 32;
+
+                pLast = pNow;
+            }
+
+            if (colons == 2)
+            {
+                if (pGap)
+                    returnValue = 33;
+
+                pGap = pszResultAddress + 4;
+
+                if (pStart + 1 == pNow || pStart + 2 == pNow)
+                {
+                    pGap = pszResultAddressStart;
+                    pFrom = pNow;
+                }
+
+                if (*pNext == '\0' && !pNowDigit)
+                    pszSourceAddress++;
+
+                if (*pNext != ':' && *pNext != '.')
+                    pLast = pNow;
+            }
+
+            if (colons == 3)
+            {
+                pFrom = pLast;
+                pLast = pNow;
+
+                if (*pNext == '\0' && !pNowDigit)
+                    returnValue = 34;
+
+                if (pBracketOpen)
+                    returnValue = 35;
+
+                if (pGap && followRfc)
+                    returnValue = 36;
+
+                if (!pGap)
+                    pGap = pszResultAddress + 4;
+
+                if (pStart + 3 == pNow)
+                {
+                    pszResultPort = pszSourceAddressStart;
+                    pGap = pszResultAddress;
+                    pFrom = NULL;
+                }
+
+                if (pNowDigit)
+                {
+                    pszResultPort = pszSourceAddressStart;
+                }
+            }
+        }
+        if (*pNext == '\0' && colons == 0 && !pIfIdEnd)
+        {
+            pFrom = pLast;
+
+            if (pNowDigit)
+                pTo = pNow;
+
+            pLast = NULL;
+        }
+
+        if (dots > 0)
+        {
+            if (dots == 1)
+            {
+                pszResultPort = pszSourceAddressStart;
+                pLast = pNext;
+            }
+
+            if (dots == 4 && pBracketOpen)
+                returnValue = 601;
+
+            if (dots == 3 || dots == 4)
+            {
+                pszResultAddress4 = pszSourceAddressStart;
+                pLast = pFrom;
+                pFrom = NULL;
+            }
+
+            if (dots > 4)
+                returnValue = 603;
+
+            dots = 0;
+        }
+
+        if (pFrom && pTo)
+        {
+            if (pTo - pFrom > 3)
+            {
+                returnValue = 51;
+                break;
+            }
+
+            if (followRfc)
+            {
+                if ((pTo - pFrom > 0) && *pFrom == '0')
+                    returnValue = 101;
+
+                if ((pTo - pFrom) == 0 && *pFrom == '0' && colons == 2)
+                    returnValue = 102;
+
+                if ((pTo - pFrom) == 0 && *pFrom == '0' && pszResultAddress == pGap)
+                    returnValue = 103;
+
+                if ((pTo - pFrom) == 0 && *pFrom == '0')
+                {
+                    if (!pFieldStart)
+                    {
+                        pFieldStart = pszResultAddress;
+                        pFieldEnd = pszResultAddress + 4;
+                    }
+                    else
+                    {
+                        pFieldEnd = pFieldEnd + 4;
+                    }
+                }
+                else
+                {
+                    if ((size_t)(pFieldEnd - pFieldStart) > fieldLength)
+                    {
+                        fieldLength = pFieldEnd - pFieldStart;
+                        pFieldStartLongest = pFieldStart;
+                    }
+
+                    pFieldStart = NULL;
+                    pFieldEnd = NULL;
+                }
+            }
+            if (!(pGap == pszResultAddressStart && (size_t)(pNow - pStart) == colons))
+            {
+                memset(pszResultAddress, '0', 4);
+                pMisc = pszResultAddress + 3;
+                pszResultAddress = pszResultAddress + 4;
+
+                if (pFrom == pStart && (pTo - pFrom) == 3)
+                {
+                    isLinkLocal = true;
+
+                    while (pTo >= pFrom)
+                    {
+                        *pMisc = *pTo;
+
+                        if (*pTo != *pszLinkLocalPrefix && *pTo != *(pszLinkLocalPrefix + 1))
+                            isLinkLocal = false;
+
+                        pTo--;
+                        pMisc--;
+                        pszLinkLocalPrefix = pszLinkLocalPrefix - 2;
+                    }
+                }
+                else
+                {
+                    while (pTo >= pFrom)
+                    {
+                        *pMisc = *pTo;
+                        pMisc--;
+                        pTo--;
+                    }
+                }
+            }
+
+            pFrom = pNow;
+            pTo = pNow;
+
+        }
+        if (*pNext == '\0' && colons == 0)
+            pszSourceAddress++;
+
+        if (*pNext == '\0' && !pBracketClose && !pszResultPort)
+            pTo = pNext;
+
+        colons = 0;
+    } // end of loop
+
+    if (!returnValue && colonsOverAll < 2)
+        returnValue = 252;
+
+    if (!returnValue && (pBracketOpen && !pBracketClose))
+        returnValue = 25;
+
+    if (!returnValue && pGap)
+    {
+        gapSize = 32 - strlen(pszResultAddressStart);
+
+        if (followRfc)
+        {
+            if (gapSize < 5)
+                returnValue = 104;
+
+            if (fieldLength > gapSize)
+                returnValue = 105;
+
+            if (fieldLength == gapSize && pFieldStartLongest < pGap)
+                returnValue = 106;
+        }
+
+        pszResultAddress = pszResultAddressStart;
+        pszInternalAddress = pszInternalAddressStart;
+
+        if (!returnValue && pszResultAddress4Start)
+        {
+            if (strlen(pszResultAddressStart) > 4)
+                returnValue = 405;
+
+            pszResultAddress = pszResultAddressStart;
+
+            if (pGap != pszResultAddressStart)
+                returnValue = 407;
+
+            memset(pszInternalAddressStart, '0', 20);
+            pszInternalAddress = pszInternalAddressStart + 20;
+
+            for (int i = 0; i < 4; i++)
+            {
+                if (*pszResultAddress != 'f' && *pszResultAddress != 'F')
+                {
+                    returnValue = 406;
+                    break;
+                }
+
+                *pszInternalAddress = *pszResultAddress;
+                pszResultAddress++;
+                pszInternalAddress++;
+            }
+            pszResultAddress4 = pszResultAddress4Start;
+
+            for (int i = 0; i<4; i++)
+            {
+                memcpy(szDummy, pszResultAddress4, 3);
+
+                int rc = RTStrToUInt32Ex((const char *)&szDummy[0], NULL, 16, &byteOut);
+
+                if (rc == 0 && byteOut < 256)
+                {
+                    RTStrPrintf(szDummy, 3, "%02x", byteOut);
+                    memcpy(pszInternalAddress, szDummy, 2);
+                    pszInternalAddress = pszInternalAddress + 2;
+                    pszResultAddress4 = pszResultAddress4 + 3;
+                    memset(szDummy, '\0', 4);
+                }
+                else
+                {
+                    returnValue = 499;
+                }
+            }
+        }
+        else
+        {
+            while (!returnValue && pszResultAddress != pGap)
+            {
+                *pszInternalAddress = *pszResultAddress;
+                pszResultAddress++;
+                pszInternalAddress++;
+            }
+
+            memset(pszInternalAddress, '0', gapSize);
+            pszInternalAddress = pszInternalAddress + gapSize;
+
+            while (!returnValue && *pszResultAddress != '\0')
+            {
+                *pszInternalAddress = *pszResultAddress;
+                pszResultAddress++;
+                pszInternalAddress++;
+            }
+        }
+    }
+    else
+    {
+        if (!returnValue)
+        {
+            if (strlen(pszResultAddressStart) != 32)
+                returnValue = 111;
+
+            if (followRfc)
+            {
+                if (fieldLength > 4)
+                    returnValue = 112;
+            }
+
+            memcpy(pszInternalAddressStart, pszResultAddressStart, strlen(pszResultAddressStart));
+        }
+    }
+
+    if (pszResultPortStart)
+    {
+        if (strlen(pszResultPortStart) > 0 && strlen(pszResultPortStart) < 6)
+        {
+            memcpy(pszInternalPortStart, pszResultPortStart, strlen(pszResultPortStart));
+
+            intPortOut = 0;
+            int rc = RTStrToUInt32Ex(pszInternalPortStart, NULL, 10, &intPortOut);
+
+            if (rc == 0)
+            {
+                if (!(intPortOut > 0 && intPortOut < 65536))
+                    intPortOut = 0;
+            }
+            else
+            {
+                returnValue = 888;
+            }
+        }
+        else
+        {
+            returnValue = 889;
+        }
+    }
+
+    /*
+       full blown address 32 bytes, no colons -> pszInternalAddressStart
+       port as string -> pszResultPortStart
+       port as binary integer -> intPortOut
+       interface id in pIfId and pIfIdEnd
+
+       Now fill the out parameters.
+
+     */
+
+    if (!returnValue && pszAddressOut)
+    {
+        if (strlen(pszInternalAddressStart) < addressOutSize)
+        {
+            pszRc = NULL;
+            pszRc = (char *)memset(pszAddressOut, '\0', addressOutSize);
+
+            if (!pszRc)
+                returnValue = 910;
+
+            pszRc = NULL;
+
+            pszRc = (char *)memcpy(pszAddressOut, pszInternalAddressStart, strlen(pszInternalAddressStart));
+
+            if (!pszRc)
+                returnValue = 911;
+        }
+        else
+        {
+            returnValue = 912;
+        }
+    }
+
+    if (!returnValue && pPortOut)
+    {
+        *pPortOut = intPortOut;
+    }
+
+    if (!returnValue && pszIfIdOut)
+    {
+        if (pIfIdEnd && pIfId)
+        {
+            if ((size_t)(pIfIdEnd - pIfId) + 1 < ifIdOutSize)
+            {
+                pszRc = NULL;
+                pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);
+
+                if (!pszRc)
+                    returnValue = 913;
+
+                pszRc = NULL;
+                pszRc = (char *)memcpy(pszIfIdOut, pIfId, (pIfIdEnd - pIfId) + 1);
+
+                if (!pszRc)
+                    returnValue = 914;
+            }
+            else
+            {
+                returnValue = 915;
+            }
+        }
+        else
+        {
+            pszRc = NULL;
+            pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);
+
+            if (!pszRc)
+                returnValue = 916;
+        }
+        // temporary hack
+        if (isLinkLocal && (strlen(pszIfIdOut) < 1))
+        {
+            memset(pszIfIdOut, '\0', ifIdOutSize);
+            *pszIfIdOut = '%';
+            pszIfIdOut++;
+            *pszIfIdOut = '0';
+            pszIfIdOut++;
+        }
+    }
+
+    if (pBracketOpen && pBracketClose && pBrackets)
+        *pBrackets = true;
+
+    if (pEmbeddedV4 && pszResultAddress4Start)
+        *pEmbeddedV4 = true;
+
+    if (pszResultAddressStart)
+        RTMemTmpFree(pszResultAddressStart);
+
+    if (pszResultPortStart)
+        RTMemTmpFree(pszResultPortStart);
+
+    if (pszResultAddress4Start)
+        RTMemTmpFree(pszResultAddress4Start);
+
+    if (pszInternalAddressStart)
+        RTMemTmpFree(pszInternalAddressStart);
+
+    if (pszInternalPortStart)
+        RTMemTmpFree(pszInternalPortStart);
+
+    return (uint32_t)(returnValue - (returnValue * 2)); // make it negative...
+}
+
+/**
+ * Takes a string and returns a RFC compliant string of the address
+ * This function SHOULD NOT be used directly. It expects a 33 byte
+ * char array with a full blown IPv6 address without separators.
+ *
+ * @returns iprt status code.
+ * @param psz              The string to convert
+ * @param pszAddrOut       The char[] that will hold the result
+ * @param addOutSize       The size of the char[] from above.
+ * @param pszPortOut       char[] for the text representation of the port
+ * @param portOutSize      sizeof(pszPortOut);
+ */
+DECLHIDDEN(int) rtStrToIpAddr6Str(const char *psz, char *pszAddrOut, size_t addrOutSize, char *pszPortOut, size_t portOutSize, bool followRfc)
+{
+    char *pStart = NULL;
+    char *pGapStart = NULL;
+    char *pGapEnd = NULL;
+    char *pGapTStart = NULL;
+    char *pGapTEnd = NULL;
+    char *pCurrent = NULL;
+    char *pOut = NULL;
+
+    if (!psz || !pszAddrOut)
+        return VERR_NOT_SUPPORTED;
+
+    if (addrOutSize < 40)
+        return VERR_NOT_SUPPORTED;
+
+    pStart = (char *)psz;
+    pCurrent = (char *)psz;
+    pGapStart = (char *)psz;
+    pGapEnd =  (char *)psz;
+
+    while (*pCurrent != '\0')
+    {
+        if (*pCurrent != '0')
+            pGapTStart = NULL;
+
+        if ((pCurrent - pStart) % 4 == 0) // ok, start of a hextet
+        {
+            if (*pCurrent == '0' &&  !pGapTStart)
+                pGapTStart = pCurrent;
+        }
+
+        if ((pCurrent - pStart) % 4 == 3)
+        {
+            if (*pCurrent == '0' && pGapTStart)
+                pGapTEnd = pCurrent;
+
+            if (pGapTStart && pGapTEnd)
+            {
+                pGapTEnd = pCurrent;
+
+                if ((pGapTEnd - pGapTStart) > (pGapEnd - pGapStart))
+                {
+                    pGapEnd = pGapTEnd;
+                    pGapStart = pGapTStart;
+                }
+            }
+        }
+
+        pCurrent++;
+    }
+
+    pCurrent = (char *)psz;
+    pStart = (char *)psz;
+    pOut = (char *)pszAddrOut;
+
+    while (*pCurrent != '\0')
+    {
+        if (*pCurrent != '0')
+            pGapTStart = NULL;
+
+        if (!pGapTStart)
+        {
+            *pOut = *pCurrent;
+            pOut++;
+        }
+
+        if ((pCurrent - pStart) % 4 == 3)
+        {
+            if (pGapTStart && *pCurrent == '0')
+            {
+                *pOut = *pCurrent;
+                pOut++;
+            }
+
+            if (*(pCurrent + 1) != '\0')
+            {
+                *pOut = ':';
+                pOut++;
+            }
+
+            pGapTStart = pCurrent + 1;
+        }
+
+        if ((pCurrent + 1) == pGapStart && (pGapEnd - pGapStart) > 3)
+        {
+            *pOut = ':';
+            pOut++;
+            pCurrent = pGapEnd;
+        }
+
+        pCurrent++;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Tests if the given string is a valid IPv6 address.
+ *
+ * @returns 0 if valid, some random number if not.  THIS IS NOT AN IPRT STATUS!
+ * @param psz                  The string to test
+ * @param pszResultAddress     plain address, optional read "valid addresses
+ *                             and strings" above.
+ * @param resultAddressSize    size of pszResultAddress
+ * @param addressOnly          return only the plain address (no scope)
+ *                             Ignored, and will always return the if id
+ */
+static int rtNetIpv6CheckAddrStr(const char *psz, char *pszResultAddress, size_t resultAddressSize, bool addressOnly, bool followRfc)
+{
+    int rc;
+    int rc2;
+    int returnValue;
+
+    char *p = NULL, *pl = NULL;
+
+    size_t memAllocMaxSize = RT_MAX(strlen(psz), resultAddressSize) + 40;
+
+    char *pszAddressOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
+    char *pszIfIdOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
+    char *pszAddressRfcOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
+
+    if (!pszAddressOutLocal || !pszIfIdOutLocal || !pszAddressRfcOutLocal)
+        return VERR_NO_TMP_MEMORY;
+
+    memset(pszAddressOutLocal, '\0', memAllocMaxSize);
+    memset(pszIfIdOutLocal, '\0', memAllocMaxSize);
+    memset(pszAddressRfcOutLocal, '\0', memAllocMaxSize);
+
+    rc = rtStrParseAddrStr6(psz, strlen(psz), pszAddressOutLocal, memAllocMaxSize, NULL, pszIfIdOutLocal, memAllocMaxSize, NULL, NULL, followRfc);
+
+    if (rc == 0)
+        returnValue = VINF_SUCCESS;
+
+    if (rc == 0 && pszResultAddress)
+    {
+        // convert the 32 characters to a valid, shortened ipv6 address
+
+        rc2 = rtStrToIpAddr6Str((const char *)pszAddressOutLocal, pszAddressRfcOutLocal, memAllocMaxSize, NULL, 0, followRfc);
+
+        if (rc2 != 0)
+            returnValue = 951;
+
+        // this is a temporary solution
+        if (!returnValue && strlen(pszIfIdOutLocal) > 0) // the if identifier is copied over _ALWAYS_ && !addressOnly)
+        {
+            p = pszAddressRfcOutLocal + strlen(pszAddressRfcOutLocal);
+
+            *p = '%';
+
+            p++;
+
+            pl = (char *)memcpy(p, pszIfIdOutLocal, strlen(pszIfIdOutLocal));
+
+            if (!pl)
+                returnValue = VERR_NOT_SUPPORTED;
+        }
+
+        pl = NULL;
+
+        pl = (char *)memcpy(pszResultAddress, pszAddressRfcOutLocal, strlen(pszAddressRfcOutLocal));
+
+        if (!pl)
+            returnValue = VERR_NOT_SUPPORTED;
+    }
+
+    if (rc != 0)
+        returnValue = VERR_NOT_SUPPORTED;
+
+    if (pszAddressOutLocal)
+        RTMemTmpFree(pszAddressOutLocal);
+
+    if (pszAddressRfcOutLocal)
+        RTMemTmpFree(pszAddressRfcOutLocal);
+
+    if (pszIfIdOutLocal)
+        RTMemTmpFree(pszIfIdOutLocal);
+
+    return returnValue;
+
+}
+
+
+RTDECL(bool) RTNetIsIPv6AddrStr(const char *pszAddress)
+{
+    return rtNetIpv6CheckAddrStr(pszAddress, NULL, 0, true, true) >= 0;
+}
+RT_EXPORT_SYMBOL(RTNetIsIPv6AddrStr);
+
+
+RTDECL(bool) RTNetIsIPv4AddrStr(const char *pszAddress)
+{
+    static char const s_szIpV4Digits[] = "0123456789.";
+
+    size_t cchAddress = strlen(pszAddress);
+    if (cchAddress < 7 || cchAddress > 15)
+        return false;
+
+    const char *pStart, *pFrom, *pTo, *pNow;
+    pStart = pNow = pFrom = pTo = pszAddress;
+
+    unsigned cOctets = 0;
+    while (*pNow != '\0')
+    {
+        const char *pChar  = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 1);
+        const char *pDigit = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 2);
+        const char *pNext  = pNow + 1;
+
+        if (!pChar)
+            return false;
+
+        if (pDigit && *pNext != '\0')
+        {
+            pTo = pNow;
+            pNow++;
+            continue;
+        }
+
+        if (*pNow == '.' || *pNext == '\0')
+        {
+            if (*pNext == '\0')
+                pTo = pNow;
+
+            size_t cchSub = pTo - pFrom;
+            if (cchSub > 2)
+                return false;
+
+            char szDummy[4] = { 0, 0, 0, 0 };
+            memcpy(szDummy, pFrom, cchSub + 1);
+
+            int rc = RTStrToUInt8Ex(szDummy, NULL, 10, NULL);
+            if (rc != VINF_SUCCESS)
+                return false;
+
+            cOctets++;
+            if (cOctets > 4)
+                return false;
+            pFrom = pNext;
+        }
+        pNow++;
+    }
+
+    if (cOctets != 4)
+        return false;
+
+    return true;
+}
+RT_EXPORT_SYMBOL(RTNetIsIPv4AddrStr);
+
Index: unk/src/VBox/Runtime/common/string/RTStrIPv6.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/string/RTStrIPv6.cpp	(revision 43220)
+++ 	(revision )
@@ -1,1286 +1,0 @@
-/* $Id$ */
-/** @file
- * IPRT - Network Address String Handling.
- */
-
-/*
- * Contributed by Oliver Loch.
- *
- * Copyright (C) 2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#include "internal/iprt.h"
-#include <iprt/net.h>
-
-#include <iprt/mem.h>
-#include <iprt/string.h>
-#include <iprt/stream.h>
-#include "internal/string.h"
-
-
-/** @page pg_rtnetipv6_addr IPv6 Address Format
- *
- * IPv6 Addresses, their representation in text and other problems.
- *
- * The following is based on:
- *
- * - http://tools.ietf.org/html/rfc4291
- * - http://tools.ietf.org/html/rfc5952
- * - http://tools.ietf.org/html/rfc6052
- *
- *
- * Before you start using those functions, you should have an idea of
- * what you're dealing with, before you come and blame the functions...
- *
- * First of all, the address itself:
- *
- * An address is written like this: (READ THIS FINE MANUAL!)
- *
- * - 2001:db8:abc:def::1
- *
- * The characters between two colons are called a "hextet".
- * Each hextet consists of four characters and each IPv6 address
- * consists of a maximum of eight hextets. So a full blown address
- * would look like this:
- *
- * - 1111:2222:3333:4444:5555:6666:7777:8888
- *
- * The allowed characters are "0123456789abcdef". They have to be
- * lower case. Upper case is not allowed.
- *
- * *** Gaps and adress shortening
- *
- * If an address contains hextets that contain only "0"s, they
- * can be shortened, like this:
- *
- * - 1111:2222:0000:0000:0000:0000:7777:8888 -> 1111:2222::7777:8888
- *
- * The double colon represents the hextets that have been shortened "::".
- * The "::" will be called "gap" from now on.
- *
- * When shortening an address, there are some special rules that need to be applied:
- *
- * - Shorten always the longest group of hextets.
- *
- *   Let's say, you have this address: 2001:db8:0:0:0:1:0:0 then it has to be
- *   shortened to "2001:db8::1:0:0". Shortening to "2001:db8:0:0:0:1::" would
- *   return an error.
- *
- * - Two or more gaps the same size.
- *
- *   Let's say you have this address: 2001:db8:0:0:1:0:0:1. As you can see, there
- *   are two gaps, both the size of two hextets. If you shorten the last two hextets,
- *   you end up in pain, as the RFC forbids this, so the correct address is:
- *   "2001:db8::1:0:0:1"
- *
- * It's important to note that an address can only be shortened ONE TIME!
- * This is invalid: "2001:db8::1::1"
- *
- * *** The scope.
- *
- * Each address has a so called "scope" it is added to the end of the address,
- * separated by a percent sign "%". If there is no scope at the end, it defaults
- * to "0".
- *
- * So "2001:db8::1" is the same as "2001:db8::1%0".
- *
- * As in IPv6 all network interfaces can/should have the same address, the scope
- * gives you the ability to choose on which interface the system should listen.
- *
- * AFAIK, the scope can be used with unicast as well as link local addresses, but
- * it is mandatory with link local addresses (starting with fe80::).
- *
- * On Linux the default scope is the interface's name. On Windows it's just the index
- * of the interface. Run "route print -6" in the shell, to see the interface's index
- * on Winodows.
- *
- * All functions can deal with the scope, and DO NOT warn if you put garbage there.
- *
- * *** Port added to the IPv6 address
- *
- * There is only one way to add a port to an IPv6 address is to embed it in brackets:
- *
- * [2001:db8::1]:12345
- *
- * This gives you the address "2001:db8::1" and the port "12345".
- *
- * What also works, but is not recommended by rfc is to separate the port
- * by a dot:
- *
- * 2001:db8::1.12345
- *
- * It even works with embedded IPv4 addresses.
- *
- * *** Special addresses and how they are written
- *
- * The following are notations to represent "special addresses".
- *
- * "::" IN6ADDR_ANY
- * ":::123" IN6ADDR_ANY with port "123"
- * "[::]:123" IN6ADDR_ANY with port "123"
- * "[:::123]" -> NO. Not allowed and makes no sense
- * "::1" -> address of the loopback device (127.0.0.1 in v4)
- *
- * On systems with dual sockets, one can use so called embedded IPv4 addresses:
- *
- * "::ffff:192.168.1.1" results in the IPv6 address "::ffff:c0a8:0101" as two octets
- * of the IPv4 address will be converted to one hextet in the IPv6 address.
- *
- * The prefix of such addresses MUST BE "::ffff:", 10 bytes as zero and two bytes as 255.
- *
- * The so called IPv4-compatible IPv6 addresses are deprecated and no longer in use.
- *
- * *** Valid addresses and string
- *
- * If you use any of the IPv6 address functions, keep in mind, that those addresses
- * are all returning "valid" even if the underlying system (e.g. VNC) doesn't like
- * such strings.
- *
- * [2001:db8::1]
- * [2001:db8::1]:12345
- *
- * and so on. So to make sure you only pass the underlying software a pure IPv6 address
- * without any garbage, you should use the "outAddress" parameters to get a RFC compliant
- * address returned.
- *
- * So after reading the above, you'll start using the functions and see a bool called
- * "followRfc" which is true by default. This is what this bool does:
- *
- * The following addresses all represent the exact same address:
- *
- * 1 - 2001:db8::1
- * 2 - 2001:db8:0::1
- * 3 - 2001:0db8:0000:0000:0000:0000:0000:0001
- * 4 - 2001:DB8::1
- * 5 - [2001:db8::1]
- * 6 - [2001:db8:0::1]
- *
- * According to RFC 5952, number two, three, four and six are invalid.
- *
- * #2 - because there is a single hextet that hasn't been shortened
- *
- * #3 - because there has nothing been shortened (hextets 3 to 7) and
- *      there are leading zeros in at least one hextet ("0db8")
- *
- * #4 - all characters in an IPv6 address have to be lower case
- *
- * #6 - same as two but included in brackets
- *
- * If you follow RFC, the above addresses are not converted and an
- * error is returned. If you turn RFC off, you will get the expected
- * representation of the address.
- *
- * It's a nice way to convert "weird" addresses to rfc compliant addresses
- *
- */
-
-
-/**
- * Parses any string and tests if it is an IPv6 Address
- *
- * This function should NOT be used directly. If you do, note
- * that no security checks are done at the moment. This can change.
- *
- * @returns iprt sstatus code.
- * @param pszAddress       The strin that holds the IPv6 address
- * @param addressLength    The length of pszAddress
- * @param pszAddressOut    Returns a plain, full blown IPv6 address
- *                         as a char array
- * @param addressOutSize   The size of pszAddressOut (length)
- * @param pPortOut         32 bit unsigned integer, holding the port
- *                         If pszAddress doesn't contain a port, it's 0
- * @param pszScopeOut      Returns the scope of the address, if none it's 0
- * @param scopeOutSize     sizeof(pszScopeOut)
- * @param pBrackets        returns true if the address was enclosed in brackets
- * @param pEmbeddedV4      returns true if the address is an embedded IPv4 address
- * @param followRfc        if set to true, the function follows RFC (default)
- */
-static int rtStrParseAddrStr6(const char *pszAddress, size_t addressLength, char *pszAddressOut, size_t addressOutSize, uint32_t *pPortOut, char *pszIfIdOut, size_t ifIdOutSize, bool *pBrackets, bool *pEmbeddedV4, bool followRfc)
-{
-    /************************\
-     *  Pointer Hell Ahead  *
-    \************************/
-
-    const char szIpV6AddressChars[] = "ABCDEF01234567890abcdef.:[]%"; // order IMPORTANT
-    const char szIpV4AddressChars[] = "01234567890.:[]"; // order IMPORTANT
-    const char szLinkLocalPrefix[] = "FfEe8800"; //
-    const char *pszIpV6AddressChars = NULL, *pszIpV4AddressChars = NULL, *pszLinkLocalPrefix = NULL;
-
-    char *pszSourceAddress = NULL, *pszSourceAddressStart = NULL;
-    char *pszResultAddress = NULL, *pszResultAddressStart = NULL;
-    char *pszResultAddress4 = NULL, *pszResultAddress4Start = NULL;
-    char *pszResultPort = NULL, *pszResultPortStart = NULL;
-    char *pszInternalAddress = NULL, *pszInternalAddressStart = NULL;
-    char *pszInternalPort = NULL, *pszInternalPortStart = NULL;
-
-    char *pStart = NULL, *pNow = NULL, *pNext = NULL, *pNowChar = NULL, *pIfId = NULL, *pIfIdEnd = NULL;
-    char *pNowDigit = NULL, *pFrom = NULL, *pTo = NULL, *pLast = NULL;
-    char *pGap = NULL, *pMisc = NULL, *pDotStart = NULL, *pFieldStart = NULL, *pFieldEnd = NULL;
-    char *pFieldStartLongest = NULL, *pBracketOpen = NULL, *pBracketClose = NULL;
-    char *pszRc = NULL;
-
-    bool isLinkLocal = false;
-    char szDummy[4];
-
-    uint8_t *pByte = NULL;
-    uint32_t byteOut = 0;
-    uint16_t returnValue = 0;
-    uint32_t colons = 0;
-    uint32_t colonsOverAll = 0;
-    uint32_t fieldLength = 0;
-    uint32_t dots = 0;
-    size_t gapSize = 0;
-    uint32_t intPortOut = 0;
-
-    pszIpV4AddressChars = &szIpV4AddressChars[0];
-    pszIpV6AddressChars = &szIpV6AddressChars[6];
-    pszLinkLocalPrefix = &szLinkLocalPrefix[6];
-
-    if (!followRfc)
-        pszIpV6AddressChars = &szIpV6AddressChars[0];
-
-    if (addressLength<2)
-        returnValue = 711;
-
-    pszResultAddressStart = (char *)RTMemTmpAlloc(34);
-    pszInternalAddressStart = (char *)RTMemTmpAlloc(34);
-    pszInternalPortStart = (char * )RTMemTmpAlloc(10);
-
-    if (! (pszResultAddressStart && pszInternalAddressStart && pszInternalPortStart))
-    {
-        if (pszResultAddressStart)
-            RTMemTmpFree(pszResultAddressStart);
-
-        if (pszInternalAddressStart)
-            RTMemTmpFree(pszInternalAddressStart);
-
-        if (pszInternalPortStart)
-            RTMemTmpFree(pszInternalPortStart);
-
-        return -701;
-    }
-
-    memset(szDummy, '\0', 4);
-
-    pszResultAddress = pszResultAddressStart;
-    memset(pszResultAddressStart, '\0', 34);
-
-    pszInternalAddress = pszInternalAddressStart;
-    memset(pszInternalAddressStart, '\0' , 34);
-
-    pszInternalPort = pszInternalPortStart;
-    memset(pszInternalPortStart, '\0', 10);
-
-    pszSourceAddress = pszSourceAddressStart = (char *)pszAddress;
-
-    pFrom = pTo = pStart = pLast = pszSourceAddressStart;
-
-    while (*pszSourceAddress != '\0' && !returnValue)
-    {
-        pNow = NULL;
-        pNext = NULL;
-        pNowChar = NULL;
-        pNowDigit = NULL;
-
-        pNow = pszSourceAddress;
-        pNext = pszSourceAddress + 1;
-
-        if (!pFrom)
-            pFrom = pTo = pNow;
-
-        pNowChar = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars));
-        pNowDigit = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars) - 5);
-
-        if (pszResultPort)
-        {
-            if (pLast && (pszResultPort == pszSourceAddressStart))
-            {
-                if (*pLast == '\0')
-                    returnValue = 721;
-
-                pszResultPortStart = (char *)RTMemTmpAlloc(10);
-
-                if (!pszResultPortStart)
-                    returnValue = 702;
-
-                memset(pszResultPortStart, '\0', 10);
-                pszResultPort = pszResultPortStart;
-                pszSourceAddress = pLast;
-                pMisc = pLast;
-                pLast = NULL;
-                continue;
-            }
-
-            pNowDigit = NULL;
-            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);
-
-            if (strlen(pszResultPortStart) == 5)
-                returnValue = 11;
-
-            if (*pNow == '0' && pszResultPort == pszResultPortStart && *pNext != '\0' && (pNow - pMisc) < 5 )
-            {
-                pszSourceAddress++;
-                continue;
-            }
-
-            if (pNowDigit)
-            {
-                *pszResultPort = *pNowDigit;
-                pszResultPort++;
-                pszSourceAddress++;
-                continue;
-            }
-            else
-                returnValue = 12;
-        }
-
-        if (pszResultAddress4)
-        {
-            if (pszResultAddress4 == pszSourceAddressStart && pLast)
-            {
-                dots = 0;
-                pszResultAddress4 = NULL;
-                pszResultAddress4Start = NULL;
-                pszResultAddress4Start = (char *)RTMemTmpAlloc(20);
-
-                if (!pszResultAddress4Start)
-                {
-                    returnValue = 401;
-                    break;
-                }
-
-                memset(pszResultAddress4Start, '\0', 20);
-                pszResultAddress4 = pszResultAddress4Start;
-                pszSourceAddress = pLast;
-                pFrom = pLast;
-                pTo = pLast;
-                pLast = NULL;
-                continue;
-            }
-
-            pTo = pNow;
-            pNowDigit = NULL;
-            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);
-
-            if (!pNowDigit && *pNow != '.' && *pNow != ']' && *pNow != ':' && *pNow != '%')
-                returnValue = 412;
-
-            if ((pNow - pFrom) > 3)
-            {
-                returnValue = 402;
-                break;
-            }
-
-            if (pNowDigit && *pNext != '\0')
-            {
-                pszSourceAddress++;
-                continue;
-            }
-
-            if (!pNowDigit  && !pBracketOpen && (*pNext == '.' || *pNext == ']' || *pNext == ':'))
-                returnValue = 411;
-
-            memset(pszResultAddress4, '0', 3);
-            pMisc = pszResultAddress4 + 2;
-            pszResultAddress4 = pszResultAddress4 + 3;
-
-            if (*pNow != '.' && !pNowDigit && strlen(pszResultAddress4Start) < 9)
-                returnValue = 403;
-
-            if ((pTo - pFrom) > 0)
-                pTo--;
-
-            dots++;
-
-            while (pTo >= pFrom)
-            {
-                *pMisc = *pTo;
-                pMisc--;
-                pTo--;
-            }
-
-            if (dots == 4 && *pNow == '.')
-            {
-                if (!pBracketOpen)
-                {
-                    pszResultPort = pszSourceAddressStart;
-                    pLast = pNext;
-                }
-                else
-                {
-                    returnValue = 409;
-                }
-            }
-
-            dots = 0;
-
-            pFrom = pNext;
-            pTo = pNext;
-
-            if (strlen(pszResultAddress4Start) > 11)
-                pszResultAddress4 = NULL;
-
-            if ((*pNow == ':' || *pNow == '.') && strlen(pszResultAddress4Start) == 12)
-            {
-                pLast = pNext;
-                pszResultPort = pszSourceAddressStart;
-            }
-
-            if (*pNow == '%')
-            {
-                pIfId =  pNow;
-                pLast = pNow;
-                continue;
-            }
-            pszSourceAddress = pNext;
-
-            if (*pNow != ']')
-                continue;
-
-            pFrom = pNow;
-            pTo = pNow;
-        }
-
-        if (pIfId && (!pIfIdEnd))
-        {
-            if (*pIfId == '%' && pIfId == pLast && *pNext != '\0')
-            {
-                pFrom = pNext;
-                pIfId = pNext;
-                pLast = NULL;
-
-                pszSourceAddress++;
-                continue;
-            }
-
-            if (*pNow == '%' && pIfId <= pNow)
-            {
-                returnValue = 442;
-                break;
-            }
-
-            if (*pNow != ']' && *pNext != '\0')
-            {
-                pTo = pNow;
-                pszSourceAddress++;
-                continue;
-            }
-
-            if (*pNow == ']')
-            {
-                pIfIdEnd = pNow - 1;
-                pFrom = pNow;
-                pTo = pNow;
-                continue;
-            }
-            else
-            {
-                pIfIdEnd = pNow;
-                pFrom = NULL;
-                pTo = NULL;
-                pszSourceAddress++;
-                continue;
-            }
-        }
-
-        if (!pNowChar)
-        {
-            returnValue = 254;
-
-            if (followRfc)
-            {
-                pMisc = (char *)memchr(&szIpV6AddressChars[0], *pNow, strlen(&szIpV6AddressChars[0]));
-
-                if (pMisc)
-                    returnValue = 253;
-            }
-        }
-
-        if (strlen(pszResultAddressStart) > 32 && !pszResultAddress4Start)
-            returnValue = 255;
-
-        if (pNowDigit && *pNext != '\0' && colons == 0)
-        {
-            pTo = pNow;
-            pszSourceAddress++;
-            continue;
-        }
-
-        if (*pNow == ':' && *pNext != '\0')
-        {
-            colonsOverAll++;
-            colons++;
-            pszSourceAddress++;
-            continue;
-        }
-
-        if (*pNow == ':' )
-        {
-            colons++;
-            colonsOverAll++;
-        }
-
-        if (*pNow == '.')
-        {
-            pMisc = pNow;
-
-            while (*pMisc != '\0' && *pMisc != ']')
-            {
-                if (*pMisc == '.')
-                    dots++;
-
-                pMisc++;
-            }
-        }
-
-        if (*pNow == ']')
-        {
-            if (pBracketClose)
-                returnValue = 77;
-
-            if (!pBracketOpen)
-                returnValue = 22;
-
-            if (*pNext == ':' || *pNext == '.')
-            {
-                pszResultPort = pszSourceAddressStart;
-                pLast = pNext + 1;
-            }
-
-            if (pFrom == pNow)
-                pFrom = NULL;
-
-            pBracketClose = pNow;
-        }
-
-        if (*pNow == '[')
-        {
-            if (pBracketOpen)
-                returnValue = 23;
-
-            if (pStart != pNow)
-                returnValue = 24;
-
-            pBracketOpen = pNow;
-            pStart++;
-            pFrom++;
-            pszSourceAddress++;
-            continue;
-        }
-
-        if (*pNow == '%')
-        {
-            if (pIfId)
-                returnValue = 441;
-
-            pLast = pNext;
-            pIfId = pNext;
-        }
-
-        if (colons > 0)
-        {
-            if (colons == 1)
-            {
-                if (pStart + 1 == pNow )
-                    returnValue = 31;
-
-                if (*pNext == '\0' && !pNowDigit)
-                    returnValue = 32;
-
-                pLast = pNow;
-            }
-
-            if (colons == 2)
-            {
-                if (pGap)
-                    returnValue = 33;
-
-                pGap = pszResultAddress + 4;
-
-                if (pStart + 1 == pNow || pStart + 2 == pNow)
-                {
-                    pGap = pszResultAddressStart;
-                    pFrom = pNow;
-                }
-
-                if (*pNext == '\0' && !pNowDigit)
-                    pszSourceAddress++;
-
-                if (*pNext != ':' && *pNext != '.')
-                    pLast = pNow;
-            }
-
-            if (colons == 3)
-            {
-                pFrom = pLast;
-                pLast = pNow;
-
-                if (*pNext == '\0' && !pNowDigit)
-                    returnValue = 34;
-
-                if (pBracketOpen)
-                    returnValue = 35;
-
-                if (pGap && followRfc)
-                    returnValue = 36;
-
-                if (!pGap)
-                    pGap = pszResultAddress + 4;
-
-                if (pStart + 3 == pNow)
-                {
-                    pszResultPort = pszSourceAddressStart;
-                    pGap = pszResultAddress;
-                    pFrom = NULL;
-                }
-
-                if (pNowDigit)
-                {
-                    pszResultPort = pszSourceAddressStart;
-                }
-            }
-        }
-        if (*pNext == '\0' && colons == 0 && !pIfIdEnd)
-        {
-            pFrom = pLast;
-
-            if (pNowDigit)
-                pTo = pNow;
-
-            pLast = NULL;
-        }
-
-        if (dots > 0)
-        {
-            if (dots == 1)
-            {
-                pszResultPort = pszSourceAddressStart;
-                pLast = pNext;
-            }
-
-            if (dots == 4 && pBracketOpen)
-                returnValue = 601;
-
-            if (dots == 3 || dots == 4)
-            {
-                pszResultAddress4 = pszSourceAddressStart;
-                pLast = pFrom;
-                pFrom = NULL;
-            }
-
-            if (dots > 4)
-                returnValue = 603;
-
-            dots = 0;
-        }
-
-        if (pFrom && pTo)
-        {
-            if (pTo - pFrom > 3)
-            {
-                returnValue = 51;
-                break;
-            }
-
-            if (followRfc)
-            {
-                if ((pTo - pFrom > 0) && *pFrom == '0')
-                    returnValue = 101;
-
-                if ((pTo - pFrom) == 0 && *pFrom == '0' && colons == 2)
-                    returnValue = 102;
-
-                if ((pTo - pFrom) == 0 && *pFrom == '0' && pszResultAddress == pGap)
-                    returnValue = 103;
-
-                if ((pTo - pFrom) == 0 && *pFrom == '0')
-                {
-                    if (!pFieldStart)
-                    {
-                        pFieldStart = pszResultAddress;
-                        pFieldEnd = pszResultAddress + 4;
-                    }
-                    else
-                    {
-                        pFieldEnd = pFieldEnd + 4;
-                    }
-                }
-                else
-                {
-                    if ((size_t)(pFieldEnd - pFieldStart) > fieldLength)
-                    {
-                        fieldLength = pFieldEnd - pFieldStart;
-                        pFieldStartLongest = pFieldStart;
-                    }
-
-                    pFieldStart = NULL;
-                    pFieldEnd = NULL;
-                }
-            }
-            if (!(pGap == pszResultAddressStart && (size_t)(pNow - pStart) == colons))
-            {
-                memset(pszResultAddress, '0', 4);
-                pMisc = pszResultAddress + 3;
-                pszResultAddress = pszResultAddress + 4;
-
-                if (pFrom == pStart && (pTo - pFrom) == 3)
-                {
-                    isLinkLocal = true;
-
-                    while (pTo >= pFrom)
-                    {
-                        *pMisc = *pTo;
-
-                        if (*pTo != *pszLinkLocalPrefix && *pTo != *(pszLinkLocalPrefix + 1))
-                            isLinkLocal = false;
-
-                        pTo--;
-                        pMisc--;
-                        pszLinkLocalPrefix = pszLinkLocalPrefix - 2;
-                    }
-                }
-                else
-                {
-                    while (pTo >= pFrom)
-                    {
-                        *pMisc = *pTo;
-                        pMisc--;
-                        pTo--;
-                    }
-                }
-            }
-
-            pFrom = pNow;
-            pTo = pNow;
-
-        }
-        if (*pNext == '\0' && colons == 0)
-            pszSourceAddress++;
-
-        if (*pNext == '\0' && !pBracketClose && !pszResultPort)
-            pTo = pNext;
-
-        colons = 0;
-    } // end of loop
-
-    if (!returnValue && colonsOverAll < 2)
-        returnValue = 252;
-
-    if (!returnValue && (pBracketOpen && !pBracketClose))
-        returnValue = 25;
-
-    if (!returnValue && pGap)
-    {
-        gapSize = 32 - strlen(pszResultAddressStart);
-
-        if (followRfc)
-        {
-            if (gapSize < 5)
-                returnValue = 104;
-
-            if (fieldLength > gapSize)
-                returnValue = 105;
-
-            if (fieldLength == gapSize && pFieldStartLongest < pGap)
-                returnValue = 106;
-        }
-
-        pszResultAddress = pszResultAddressStart;
-        pszInternalAddress = pszInternalAddressStart;
-
-        if (!returnValue && pszResultAddress4Start)
-        {
-            if (strlen(pszResultAddressStart) > 4)
-                returnValue = 405;
-
-            pszResultAddress = pszResultAddressStart;
-
-            if (pGap != pszResultAddressStart)
-                returnValue = 407;
-
-            memset(pszInternalAddressStart, '0', 20);
-            pszInternalAddress = pszInternalAddressStart + 20;
-
-            for (int i = 0; i < 4; i++)
-            {
-                if (*pszResultAddress != 'f' && *pszResultAddress != 'F')
-                {
-                    returnValue = 406;
-                    break;
-                }
-
-                *pszInternalAddress = *pszResultAddress;
-                pszResultAddress++;
-                pszInternalAddress++;
-            }
-            pszResultAddress4 = pszResultAddress4Start;
-
-            for (int i = 0; i<4; i++)
-            {
-                memcpy(szDummy, pszResultAddress4, 3);
-
-                int rc = RTStrToUInt32Ex((const char *)&szDummy[0], NULL, 16, &byteOut);
-
-                if (rc == 0 && byteOut < 256)
-                {
-                    RTStrPrintf(szDummy, 3, "%02x", byteOut);
-                    memcpy(pszInternalAddress, szDummy, 2);
-                    pszInternalAddress = pszInternalAddress + 2;
-                    pszResultAddress4 = pszResultAddress4 + 3;
-                    memset(szDummy, '\0', 4);
-                }
-                else
-                {
-                    returnValue = 499;
-                }
-            }
-        }
-        else
-        {
-            while (!returnValue && pszResultAddress != pGap)
-            {
-                *pszInternalAddress = *pszResultAddress;
-                pszResultAddress++;
-                pszInternalAddress++;
-            }
-
-            memset(pszInternalAddress, '0', gapSize);
-            pszInternalAddress = pszInternalAddress + gapSize;
-
-            while (!returnValue && *pszResultAddress != '\0')
-            {
-                *pszInternalAddress = *pszResultAddress;
-                pszResultAddress++;
-                pszInternalAddress++;
-            }
-        }
-    }
-    else
-    {
-        if (!returnValue)
-        {
-            if (strlen(pszResultAddressStart) != 32)
-                returnValue = 111;
-
-            if (followRfc)
-            {
-                if (fieldLength > 4)
-                    returnValue = 112;
-            }
-
-            memcpy(pszInternalAddressStart, pszResultAddressStart, strlen(pszResultAddressStart));
-        }
-    }
-
-    if (pszResultPortStart)
-    {
-        if (strlen(pszResultPortStart) > 0 && strlen(pszResultPortStart) < 6)
-        {
-            memcpy(pszInternalPortStart, pszResultPortStart, strlen(pszResultPortStart));
-
-            intPortOut = 0;
-            int rc = RTStrToUInt32Ex(pszInternalPortStart, NULL, 10, &intPortOut);
-
-            if (rc == 0)
-            {
-                if (!(intPortOut > 0 && intPortOut < 65536))
-                    intPortOut = 0;
-            }
-            else
-            {
-                returnValue = 888;
-            }
-        }
-        else
-        {
-            returnValue = 889;
-        }
-    }
-
-    /*
-       full blown address 32 bytes, no colons -> pszInternalAddressStart
-       port as string -> pszResultPortStart
-       port as binary integer -> intPortOut
-       interface id in pIfId and pIfIdEnd
-
-       Now fill the out parameters.
-
-     */
-
-    if (!returnValue && pszAddressOut)
-    {
-        if (strlen(pszInternalAddressStart) < addressOutSize)
-        {
-            pszRc = NULL;
-            pszRc = (char *)memset(pszAddressOut, '\0', addressOutSize);
-
-            if (!pszRc)
-                returnValue = 910;
-
-            pszRc = NULL;
-
-            pszRc = (char *)memcpy(pszAddressOut, pszInternalAddressStart, strlen(pszInternalAddressStart));
-
-            if (!pszRc)
-                returnValue = 911;
-        }
-        else
-        {
-            returnValue = 912;
-        }
-    }
-
-    if (!returnValue && pPortOut)
-    {
-        *pPortOut = intPortOut;
-    }
-
-    if (!returnValue && pszIfIdOut)
-    {
-        if (pIfIdEnd && pIfId)
-        {
-            if ((size_t)(pIfIdEnd - pIfId) + 1 < ifIdOutSize)
-            {
-                pszRc = NULL;
-                pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);
-
-                if (!pszRc)
-                    returnValue = 913;
-
-                pszRc = NULL;
-                pszRc = (char *)memcpy(pszIfIdOut, pIfId, (pIfIdEnd - pIfId) + 1);
-
-                if (!pszRc)
-                    returnValue = 914;
-            }
-            else
-            {
-                returnValue = 915;
-            }
-        }
-        else
-        {
-            pszRc = NULL;
-            pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);
-
-            if (!pszRc)
-                returnValue = 916;
-        }
-        // temporary hack
-        if (isLinkLocal && (strlen(pszIfIdOut) < 1))
-        {
-            memset(pszIfIdOut, '\0', ifIdOutSize);
-            *pszIfIdOut = '%';
-            pszIfIdOut++;
-            *pszIfIdOut = '0';
-            pszIfIdOut++;
-        }
-    }
-
-    if (pBracketOpen && pBracketClose && pBrackets)
-        *pBrackets = true;
-
-    if (pEmbeddedV4 && pszResultAddress4Start)
-        *pEmbeddedV4 = true;
-
-    if (pszResultAddressStart)
-        RTMemTmpFree(pszResultAddressStart);
-
-    if (pszResultPortStart)
-        RTMemTmpFree(pszResultPortStart);
-
-    if (pszResultAddress4Start)
-        RTMemTmpFree(pszResultAddress4Start);
-
-    if (pszInternalAddressStart)
-        RTMemTmpFree(pszInternalAddressStart);
-
-    if (pszInternalPortStart)
-        RTMemTmpFree(pszInternalPortStart);
-
-    return (uint32_t)(returnValue - (returnValue * 2)); // make it negative...
-}
-
-/**
- * Takes a string and returns a RFC compliant string of the address
- * This function SHOULD NOT be used directly. It expects a 33 byte
- * char array with a full blown IPv6 address without separators.
- *
- * @returns iprt status code.
- * @param psz              The string to convert
- * @param pszAddrOut       The char[] that will hold the result
- * @param addOutSize       The size of the char[] from above.
- * @param pszPortOut       char[] for the text representation of the port
- * @param portOutSize      sizeof(pszPortOut);
- */
-DECLHIDDEN(int) rtStrToIpAddr6Str(const char *psz, char *pszAddrOut, size_t addrOutSize, char *pszPortOut, size_t portOutSize, bool followRfc)
-{
-    char *pStart = NULL;
-    char *pGapStart = NULL;
-    char *pGapEnd = NULL;
-    char *pGapTStart = NULL;
-    char *pGapTEnd = NULL;
-    char *pCurrent = NULL;
-    char *pOut = NULL;
-
-    if (!psz || !pszAddrOut)
-        return VERR_NOT_SUPPORTED;
-
-    if (addrOutSize < 40)
-        return VERR_NOT_SUPPORTED;
-
-    pStart = (char *)psz;
-    pCurrent = (char *)psz;
-    pGapStart = (char *)psz;
-    pGapEnd =  (char *)psz;
-
-    while (*pCurrent != '\0')
-    {
-        if (*pCurrent != '0')
-            pGapTStart = NULL;
-
-        if ((pCurrent - pStart) % 4 == 0) // ok, start of a hextet
-        {
-            if (*pCurrent == '0' &&  !pGapTStart)
-                pGapTStart = pCurrent;
-        }
-
-        if ((pCurrent - pStart) % 4 == 3)
-        {
-            if (*pCurrent == '0' && pGapTStart)
-                pGapTEnd = pCurrent;
-
-            if (pGapTStart && pGapTEnd)
-            {
-                pGapTEnd = pCurrent;
-
-                if ((pGapTEnd - pGapTStart) > (pGapEnd - pGapStart))
-                {
-                    pGapEnd = pGapTEnd;
-                    pGapStart = pGapTStart;
-                }
-            }
-        }
-
-        pCurrent++;
-    }
-
-    pCurrent = (char *)psz;
-    pStart = (char *)psz;
-    pOut = (char *)pszAddrOut;
-
-    while (*pCurrent != '\0')
-    {
-        if (*pCurrent != '0')
-            pGapTStart = NULL;
-
-        if (!pGapTStart)
-        {
-            *pOut = *pCurrent;
-            pOut++;
-        }
-
-        if ((pCurrent - pStart) % 4 == 3)
-        {
-            if (pGapTStart && *pCurrent == '0')
-            {
-                *pOut = *pCurrent;
-                pOut++;
-            }
-
-            if (*(pCurrent + 1) != '\0')
-            {
-                *pOut = ':';
-                pOut++;
-            }
-
-            pGapTStart = pCurrent + 1;
-        }
-
-        if ((pCurrent + 1) == pGapStart && (pGapEnd - pGapStart) > 3)
-        {
-            *pOut = ':';
-            pOut++;
-            pCurrent = pGapEnd;
-        }
-
-        pCurrent++;
-    }
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Tests if the given string is a valid IPv6 address.
- *
- * @returns 0 if valid, some random number if not.  THIS IS NOT AN IPRT STATUS!
- * @param psz                  The string to test
- * @param pszResultAddress     plain address, optional read "valid addresses
- *                             and strings" above.
- * @param resultAddressSize    size of pszResultAddress
- * @param addressOnly          return only the plain address (no scope)
- *                             Ignored, and will always return the if id
- */
-static int rtNetIpv6CheckAddrStr(const char *psz, char *pszResultAddress, size_t resultAddressSize, bool addressOnly, bool followRfc)
-{
-    int rc;
-    int rc2;
-    int returnValue;
-
-    char *p = NULL, *pl = NULL;
-
-    size_t memAllocMaxSize = RT_MAX(strlen(psz), resultAddressSize) + 40;
-
-    char *pszAddressOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
-    char *pszIfIdOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
-    char *pszAddressRfcOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
-
-    if (!pszAddressOutLocal || !pszIfIdOutLocal || !pszAddressRfcOutLocal)
-        return VERR_NO_TMP_MEMORY;
-
-    memset(pszAddressOutLocal, '\0', memAllocMaxSize);
-    memset(pszIfIdOutLocal, '\0', memAllocMaxSize);
-    memset(pszAddressRfcOutLocal, '\0', memAllocMaxSize);
-
-    rc = rtStrParseAddrStr6(psz, strlen(psz), pszAddressOutLocal, memAllocMaxSize, NULL, pszIfIdOutLocal, memAllocMaxSize, NULL, NULL, followRfc);
-
-    if (rc == 0)
-        returnValue = VINF_SUCCESS;
-
-    if (rc == 0 && pszResultAddress)
-    {
-        // convert the 32 characters to a valid, shortened ipv6 address
-
-        rc2 = rtStrToIpAddr6Str((const char *)pszAddressOutLocal, pszAddressRfcOutLocal, memAllocMaxSize, NULL, 0, followRfc);
-
-        if (rc2 != 0)
-            returnValue = 951;
-
-        // this is a temporary solution
-        if (!returnValue && strlen(pszIfIdOutLocal) > 0) // the if identifier is copied over _ALWAYS_ && !addressOnly)
-        {
-            p = pszAddressRfcOutLocal + strlen(pszAddressRfcOutLocal);
-
-            *p = '%';
-
-            p++;
-
-            pl = (char *)memcpy(p, pszIfIdOutLocal, strlen(pszIfIdOutLocal));
-
-            if (!pl)
-                returnValue = VERR_NOT_SUPPORTED;
-        }
-
-        pl = NULL;
-
-        pl = (char *)memcpy(pszResultAddress, pszAddressRfcOutLocal, strlen(pszAddressRfcOutLocal));
-
-        if (!pl)
-            returnValue = VERR_NOT_SUPPORTED;
-    }
-
-    if (rc != 0)
-        returnValue = VERR_NOT_SUPPORTED;
-
-    if (pszAddressOutLocal)
-        RTMemTmpFree(pszAddressOutLocal);
-
-    if (pszAddressRfcOutLocal)
-        RTMemTmpFree(pszAddressRfcOutLocal);
-
-    if (pszIfIdOutLocal)
-        RTMemTmpFree(pszIfIdOutLocal);
-
-    return returnValue;
-
-}
-
-
-RTDECL(bool) RTNetIsIPv6AddrStr(const char *pszAddress)
-{
-    return rtNetIpv6CheckAddrStr(pszAddress, NULL, 0, true, true) >= 0;
-}
-RT_EXPORT_SYMBOL(RTNetIsIPv6AddrStr);
-
-
-RTDECL(bool) RTNetIsIPv4AddrStr(const char *pszAddress)
-{
-    static char const s_szIpV4Digits[] = "0123456789.";
-
-    size_t cchAddress = strlen(pszAddress);
-    if (cchAddress < 7 || cchAddress > 15)
-        return false;
-
-    const char *pStart, *pFrom, *pTo, *pNow;
-    pStart = pNow = pFrom = pTo = pszAddress;
-
-    unsigned cOctets = 0;
-    while (*pNow != '\0')
-    {
-        const char *pChar  = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 1);
-        const char *pDigit = (const char *)memchr(s_szIpV4Digits, *pNow, sizeof(s_szIpV4Digits) - 2);
-        const char *pNext  = pNow + 1;
-
-        if (!pChar)
-            return false;
-
-        if (pDigit && *pNext != '\0')
-        {
-            pTo = pNow;
-            pNow++;
-            continue;
-        }
-
-        if (*pNow == '.' || *pNext == '\0')
-        {
-            if (*pNext == '\0')
-                pTo = pNow;
-
-            size_t cchSub = pTo - pFrom;
-            if (cchSub > 2)
-                return false;
-
-            char szDummy[4] = { 0, 0, 0, 0 };
-            memcpy(szDummy, pFrom, cchSub + 1);
-
-            int rc = RTStrToUInt8Ex(szDummy, NULL, 10, NULL);
-            if (rc != VINF_SUCCESS)
-                return false;
-
-            cOctets++;
-            if (cOctets > 4)
-                return false;
-            pFrom = pNext;
-        }
-        pNow++;
-    }
-
-    if (cOctets != 4)
-        return false;
-
-    return true;
-}
-RT_EXPORT_SYMBOL(RTNetIsIPv4AddrStr);
-
