| /****************************************************************************** |
| * |
| * <: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 */ |