VirtualBox

Changeset 87362 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Jan 21, 2021 10:05:41 PM (4 years ago)
Author:
vboxsync
Message:

IPRT: Make RTNetStrToIPv4Cidr() accept prefix specified as netmask,
either dotted-decimal or hex. The inputs we convert here are likely
coming from a user and people have different preferences. Sometimes
they even remember specific different networks in specific formats (I
know I do :). bugref:9330

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/net/netaddrstr2.cpp

    r82968 r87362  
    199199RTDECL(int) RTNetStrToIPv4Cidr(const char *pcszAddr, PRTNETADDRIPV4 pAddr, int *piPrefix)
    200200{
    201     RTNETADDRIPV4 Addr;
     201    RTNETADDRIPV4 Addr, Mask;
    202202    uint8_t u8Prefix;
    203203    char *pszNext;
     
    213213        return rc;
    214214
    215     /* if prefix is missing, treat is as exact (/32) address specification */
     215    /*
     216     * If the prefix is missing, treat is as exact (/32) address
     217     * specification.
     218     */
    216219    if (*pszNext == '\0' || rc == VWRN_TRAILING_SPACES)
    217220    {
     
    221224    }
    222225
    223     if (*pszNext != '/')
    224         return VERR_INVALID_PARAMETER;
    225 
    226     ++pszNext;
    227     rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &u8Prefix);
    228     if (RT_FAILURE(rc) || rc == VWRN_TRAILING_CHARS)
    229         return VERR_INVALID_PARAMETER;
     226    /*
     227     * Be flexible about the way the prefix is specified after the
     228     * slash: accept both the prefix length and the netmask, and for
     229     * the latter accept both dotted-decimal and hex.  The inputs we
     230     * convert here are likely coming from a user and people have
     231     * different preferences.  Sometimes they just remember specific
     232     * different networks in specific formats!
     233     */
     234    if (*pszNext == '/')
     235        ++pszNext;
     236    else
     237        return VERR_INVALID_PARAMETER;
     238
     239    /* .../0x... is a hex mask */
     240    if (pszNext[0] == '0' && (pszNext[1] == 'x' || pszNext[1] == 'X'))
     241    {
     242        rc = RTStrToUInt32Ex(pszNext, &pszNext, 16, &Mask.u);
     243        if (rc == VINF_SUCCESS || rc == VWRN_TRAILING_SPACES)
     244            Mask.u = RT_H2N_U32(Mask.u);
     245        else
     246            return VERR_INVALID_PARAMETER;
     247
     248        int iPrefix;
     249        rc = RTNetMaskToPrefixIPv4(&Mask, &iPrefix);
     250        if (RT_SUCCESS(rc))
     251            u8Prefix = (uint8_t)iPrefix;
     252        else
     253            return VERR_INVALID_PARAMETER;
     254    }
     255    else
     256    {
     257        char *pszLookAhead;
     258        uint32_t u32;
     259        rc = RTStrToUInt32Ex(pszNext, &pszLookAhead, 10, &u32);
     260
     261        /* single number after the slash is prefix length */
     262        if (rc == VINF_SUCCESS || rc == VWRN_TRAILING_SPACES)
     263        {
     264            if (u32 <= 32)
     265                u8Prefix = (uint8_t)u32;
     266            else
     267                return VERR_INVALID_PARAMETER;
     268        }
     269        /* a number followed by more stuff, may be a dotted-decimal */
     270        else if (rc == VWRN_TRAILING_CHARS)
     271        {
     272            if (*pszLookAhead != '.') /* don't even bother checking */
     273                return VERR_INVALID_PARAMETER;
     274
     275            rc = rtNetStrToIPv4AddrEx(pszNext, &Mask, &pszNext);
     276            if (rc == VINF_SUCCESS || rc == VWRN_TRAILING_SPACES)
     277            {
     278                int iPrefix;
     279                rc = RTNetMaskToPrefixIPv4(&Mask, &iPrefix);
     280                if (RT_SUCCESS(rc))
     281                    u8Prefix = (uint8_t)iPrefix;
     282                else
     283                    return VERR_INVALID_PARAMETER;
     284            }
     285            else
     286                return VERR_INVALID_PARAMETER;
     287        }
     288        /* failed to convert to number */
     289        else
     290            return VERR_INVALID_PARAMETER;
     291    }
    230292
    231293    if (u8Prefix == 0 || u8Prefix > 32)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette