blob: 024b3d960e291e90e2abbafe2f02e43e9b8dec74 [file] [log] [blame]
/******************************************************************************
*
* <:copyright-BRCM:2016:DUAL/GPL:standard
*
* Copyright (c) 2016 Broadcom
* All Rights Reserved
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed
* to you under the terms of the GNU General Public License version 2
* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
* with the following added to such license:
*
* As a special exception, the copyright holders of this software give
* you permission to link this software with independent modules, and
* to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent
* module, the terms and conditions of the license of that module.
* An independent module is a module which is not derived from this
* software. The special exception does not apply to any modifications
* of the software.
*
* Not withstanding the above, under no circumstances may you combine
* this software in any way with any other Broadcom software provided
* under a license other than the GPL, without Broadcom's express prior
* written consent.
*
* :>
*
*****************************************************************************/
/**
* @file bal_utils.c
* @brief BAL Utilities source
*
* This file contains the implementation of various BAL "utilities",
* which are provided via the libutils.a library.
*/
/*@{*/
#ifdef USING_BAL_UTILS
/* --- system includes ---*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <arpa/inet.h>
#include <string.h>
#include <bcmos_system.h>
/* --- project includes ---*/
#include "bal_utils.h"
/*
* Generic helper functions
*/
char *mac_addr_to_str(char *buffer, bcmos_mac_address mac)
{
char *fmt_str = NULL;
fmt_str = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
snprintf(buffer, 20, fmt_str,
mac.u8[0], mac.u8[1],
mac.u8[2], mac.u8[3],
mac.u8[4], mac.u8[5]);
return buffer;
}
bcmos_bool mac_add_is_null(bcmos_mac_address mac)
{
return ((0 != mac.u8[0]) || (0 != mac.u8[1]) || (0 != mac.u8[2]) ||
(0 != mac.u8[3]) || (0 != mac.u8[4]) || (0 != mac.u8[5])) ? BCMOS_FALSE : BCMOS_TRUE;
}
/**
* @brief Determines if string contains a valid IPv4 or IPv6 address
*
*
* @param ipAddrStr Pointer to string to parse
*
* @return bcmos_bool
* @retval TRUE String contains a valid IP address
* @retval FALSE String does not
*/
bcmos_bool BalIsValidIp(const char *ipAddrStr)
{
struct sockaddr_in addr4;
struct in6_addr addr6;
bcmos_bool ret = BCMOS_FALSE;
/* Parameter checks. */
BUG_UNLESS(NULL != ipAddrStr, BCMOS_FALSE);
/* First look to see if it's a valid IPv4 address, then look to see if it's
a valid IPv6 address*/
if (inet_pton(AF_INET, ipAddrStr, &addr4) > 0 || inet_pton(AF_INET6, ipAddrStr, &addr6) > 0)
{
ret = TRUE;
}
return ret;
}
/**
* @brief Convert a string to the specified type of integer
*
* NOTE: This function uses the strtoll() function to convert the string to an
* integer value. U64 values greater than 0x7fffffffffffffff cannot be converted
* by the strtoll() function because the string value is considered out of the
* valid -0x8000000000000000 to 0x7fffffffffffffff 64-bit integer range.
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
static bcmos_errno BalStringToInt(char *str, BalIntStringT *pVal)
{
bcmos_errno rc = BAL_OK;
U64 u64 = 0;
S64 s64 = 0;
char *endptr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
BUG_UNLESS(pVal->intType > BAL_STR2INT_INVALID, BAL_PARAM);
BUG_UNLESS(pVal->intType < BAL_STR2INT_MAX, BAL_PARAM);
do
{
if ((pVal->intType >= BAL_STR2INT_S8) &&
(pVal->intType <= BAL_STR2INT_S64))
{
/* Just assume a signed 64-bit value when converting the string to
* an integer. Range checking is done below. Make sure that errno
* is set to zero before calling strtoll().
*/
errno = 0;
pVal->intU.s64 = 0; /* Clear all possibilities to 0 */
s64 = strtoll(str, &endptr, 10);
/* General range and error check */
if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
|| (errno != 0 && s64 == 0))
{
errno = 0;
rc = BCM_ERR_RANGE;
break;
}
/* test for no digits or mixed digits and characters */
if (endptr == str || '\0' != *endptr)
{
errno = 0;
rc = BCM_ERR_PARM;
break;
}
/* routine specific range check */
switch (pVal->intType)
{
case BAL_STR2INT_S8:
if ((s64 < -128) || (s64 > 127))
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.s8 = (S8)s64;
}
break;
case BAL_STR2INT_S16:
if ((s64 < -32768) || (s64 > 32767))
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.s16 = (S16)s64;
}
break;
case BAL_STR2INT_S32:
if ((s64 < (-2147483647L -1L)) || (s64 > 2147483647L))
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.s32 = (S32)s64;
}
break;
case BAL_STR2INT_S64:
/* No range checking is needed since the strtoll() function
* does the range checking. If the string was invalid, errno
* would have been non-zero.
*/
pVal->intU.s64 = s64;
break;
default:
/* Should never make it here. */
rc = BCM_ERR_PARM;
break;
}
}
else {
/* Just assume an unsigned 64-bit value when converting the string
* to an integer. Range checking is done below. Make sure that errno
* is set to zero before calling strtoull().
*/
errno = 0;
pVal->intU.u64 = 0;
u64 = strtoull(str, &endptr, 10);
/* General range and error check */
if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
|| (errno != 0 && s64 == 0))
{
errno = 0;
rc = BCM_ERR_RANGE;
break;
}
/* test for no digits or mixed digits and characters */
if (endptr == str || '\0' != *endptr)
{
errno = 0;
rc = BCM_ERR_PARM;
break;
}
/* routine specific range check */
switch(pVal->intType)
{
case BAL_STR2INT_U8:
if (u64 > 255)
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.u8 = (U8)u64;
}
break;
case BAL_STR2INT_U16:
if (u64 > 65535)
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.u16 = (U16)u64;
}
break;
case BAL_STR2INT_U32:
if (u64 > 4294967295UL)
{
rc = BCM_ERR_RANGE;
}
else
{
pVal->intU.u32 = (U32)u64;
}
break;
case BAL_STR2INT_U64:
/* No range checking is needed since the strtoull() function
* does the range checking. If the string was invalid, errno
* would have been non-zero.
*/
pVal->intU.u64 = u64;
break;
default:
/* Should never make it here. */
rc = BCM_ERR_PARM;
break;
}
}
} while (0);
return(rc);
}
/**
* @brief Convert a string to an S8 type integer
*
* This function converts a string to an S8 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToS8(char *str, S8 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_S8;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.s8;
}
return(rc);
}
/**
* @brief Convert a string to an S16 type integer
*
* This function converts a string to an S16 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToS16(char *str, S16 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_S16;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.s16;
}
return(rc);
}
/**
* @brief Convert a string to an S32 type integer
*
* This function converts a string to an S32 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToS32(char *str, S32 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_S32;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.s32;
}
return(rc);
}
/**
* @brief Convert a string to an S64 type integer
*
* This function converts a string to an S64 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToS64(char *str, S64 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_S64;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.s64;
}
return(rc);
}
/**
* @brief Convert a string to a U8 type integer
*
* This function converts a string to a U8 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToU8(char *str, U8 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_U8;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.u8;
}
return(rc);
}
/**
* @brief Convert a string to a U16 type integer
*
* This function converts a string to a U16 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToU16(char *str, U16 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_U16;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.u16;
}
return(rc);
}
/**
* @brief Convert a string to a U32 type integer
*
* This function converts a string to a U32 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToU32(char *str, U32 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_U32;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.u32;
}
return(rc);
}
/**
* @brief Convert a string to a U64 type integer
*
* This function converts a string to a U64 type integer
*
* @param str String to convert
* @param pVal Pointer to the return value
*
* @return bcmos_errno
*/
bcmos_errno BalStringToU64(char *str, U64 *pVal)
{
bcmos_errno rc = BAL_OK;
BalIntStringT intStr;
BUG_UNLESS(NULL != str, BAL_PARAM);
BUG_UNLESS(NULL != pVal, BAL_PARAM);
memset(&intStr, 0, sizeof(intStr));
intStr.intType = BAL_STR2INT_U64;
rc = BalStringToInt(str, &intStr);
if (BAL_OK == rc)
{
*pVal = intStr.intU.u64;
}
return(rc);
}
#endif /* USING_BAL_UTILS */