cidr.cpp revision d0919fc17582396c6254a3e3e517cccf886dd051
af062818b47340eef15700d2f0211576ba3506eevboxsync/* $Id$ */
af062818b47340eef15700d2f0211576ba3506eevboxsync/** @file
af062818b47340eef15700d2f0211576ba3506eevboxsync * IPRT - IPv4 address parsing.
af062818b47340eef15700d2f0211576ba3506eevboxsync */
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync/*
af062818b47340eef15700d2f0211576ba3506eevboxsync * Copyright (C) 2006-2008 Sun Microsystems, Inc.
af062818b47340eef15700d2f0211576ba3506eevboxsync *
af062818b47340eef15700d2f0211576ba3506eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af062818b47340eef15700d2f0211576ba3506eevboxsync * available from http://www.virtualbox.org. This file is free software;
af062818b47340eef15700d2f0211576ba3506eevboxsync * you can redistribute it and/or modify it under the terms of the GNU
af062818b47340eef15700d2f0211576ba3506eevboxsync * General Public License (GPL) as published by the Free Software
af062818b47340eef15700d2f0211576ba3506eevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af062818b47340eef15700d2f0211576ba3506eevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af062818b47340eef15700d2f0211576ba3506eevboxsync *
af062818b47340eef15700d2f0211576ba3506eevboxsync * The contents of this file may alternatively be used under the terms
af062818b47340eef15700d2f0211576ba3506eevboxsync * of the Common Development and Distribution License Version 1.0
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * CDDL are applicable instead of those of the GPL.
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync *
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync * You may elect to license modified versions of this file under the
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync * terms and conditions of either the GPL or the CDDL or both.
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync *
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
af062818b47340eef15700d2f0211576ba3506eevboxsync * additional information or have any questions.
af062818b47340eef15700d2f0211576ba3506eevboxsync */
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Header Files *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync#include <iprt/cidr.h>
af062818b47340eef15700d2f0211576ba3506eevboxsync#include <iprt/ctype.h>
af062818b47340eef15700d2f0211576ba3506eevboxsync#include <iprt/string.h>
af062818b47340eef15700d2f0211576ba3506eevboxsync#include <iprt/stream.h>
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync
589fd26cedb2b4ebbed14f2964cad03cc8ebbca2vboxsync/**
589fd26cedb2b4ebbed14f2964cad03cc8ebbca2vboxsync * Scan a digit of an IPv4 address.
af062818b47340eef15700d2f0211576ba3506eevboxsync *
af062818b47340eef15700d2f0211576ba3506eevboxsync * @returns IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync *
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param iDigit The index of the IPv4 digit to scan.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param psz Pointer to the begin of the string.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param ppszNext Pointer to variable that should be set pointing to the first invalid character. (output)
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pu8 Pointer to the digit to write (output).
af062818b47340eef15700d2f0211576ba3506eevboxsync */
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int scanIPv4Digit(int iDigit, const char *psz, char **ppszNext, uint8_t *pu8)
af062818b47340eef15700d2f0211576ba3506eevboxsync{
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTStrToUInt8Ex(psz, ppszNext, 10, pu8);
af062818b47340eef15700d2f0211576ba3506eevboxsync if ( rc != VINF_SUCCESS
af062818b47340eef15700d2f0211576ba3506eevboxsync && rc != VWRN_TRAILING_CHARS
af062818b47340eef15700d2f0211576ba3506eevboxsync || *pu8 > 254)
af062818b47340eef15700d2f0211576ba3506eevboxsync return VERR_INVALID_PARAMETER;
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync /* first digit cannot be 0 */
af062818b47340eef15700d2f0211576ba3506eevboxsync if ( iDigit == 1
af062818b47340eef15700d2f0211576ba3506eevboxsync && *pu8 < 1)
af062818b47340eef15700d2f0211576ba3506eevboxsync return VERR_INVALID_PARAMETER;
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync if (**ppszNext == '/')
af062818b47340eef15700d2f0211576ba3506eevboxsync return VINF_SUCCESS;
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync if ( iDigit != 4
af062818b47340eef15700d2f0211576ba3506eevboxsync && ( **ppszNext == '\0'
af062818b47340eef15700d2f0211576ba3506eevboxsync || **ppszNext != '.'))
af062818b47340eef15700d2f0211576ba3506eevboxsync return VERR_INVALID_PARAMETER;
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync return VINF_SUCCESS;
af062818b47340eef15700d2f0211576ba3506eevboxsync}
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsyncint RTCidrStrToIPv4(const char *pszAddress, PRTIPV4ADDR pNetwork, PRTIPV4ADDR pNetmask)
af062818b47340eef15700d2f0211576ba3506eevboxsync{
af062818b47340eef15700d2f0211576ba3506eevboxsync uint8_t cBits;
af062818b47340eef15700d2f0211576ba3506eevboxsync uint8_t a;
af062818b47340eef15700d2f0211576ba3506eevboxsync uint8_t b = 0;
af062818b47340eef15700d2f0211576ba3506eevboxsync uint8_t c = 0;
af062818b47340eef15700d2f0211576ba3506eevboxsync uint8_t d = 0;
af062818b47340eef15700d2f0211576ba3506eevboxsync const char *psz = pszAddress;
af062818b47340eef15700d2f0211576ba3506eevboxsync char *pszNext;
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc;
af062818b47340eef15700d2f0211576ba3506eevboxsync
af062818b47340eef15700d2f0211576ba3506eevboxsync do
af062818b47340eef15700d2f0211576ba3506eevboxsync {
af062818b47340eef15700d2f0211576ba3506eevboxsync /* 1st digit */
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = scanIPv4Digit(1, psz, &pszNext, &a);
af062818b47340eef15700d2f0211576ba3506eevboxsync if (RT_FAILURE(rc))
af062818b47340eef15700d2f0211576ba3506eevboxsync return rc;
af062818b47340eef15700d2f0211576ba3506eevboxsync if (*pszNext == '/')
af062818b47340eef15700d2f0211576ba3506eevboxsync break;
af062818b47340eef15700d2f0211576ba3506eevboxsync psz = pszNext + 1;
/* 2nd digit */
rc = scanIPv4Digit(2, psz, &pszNext, &b);
if (RT_FAILURE(rc))
return rc;
if (*pszNext == '/')
break;
psz = pszNext + 1;
/* 3rd digit */
rc = scanIPv4Digit(3, psz, &pszNext, &c);
if (RT_FAILURE(rc))
return rc;
if (*pszNext == '/')
break;
psz = pszNext + 1;
/* 4th digit */
rc = scanIPv4Digit(4, psz, &pszNext, &d);
if (RT_FAILURE(rc))
return rc;
} while (0);
if (*pszNext == '/')
{
psz = pszNext + 1;
rc = RTStrToUInt8Ex(psz, &pszNext, 10, &cBits);
if (rc != VINF_SUCCESS || cBits < 8 || cBits > 28)
return VERR_INVALID_PARAMETER;
}
else
cBits = 0;
for (psz = pszNext; RT_C_IS_SPACE(*psz); psz++)
/* nothing */;
if (*psz != '\0')
return VERR_INVALID_PARAMETER;
*pNetwork = RT_MAKE_U32_FROM_U8(d, c, b, a);
*pNetmask = ~(((uint32_t)1 << (32 - cBits)) - 1);
return VINF_SUCCESS;
}