blob: 024b3d960e291e90e2abbafe2f02e43e9b8dec74 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
2 *
3 * <:copyright-BRCM:2016:DUAL/GPL:standard
4 *
5 * Copyright (c) 2016 Broadcom
6 * All Rights Reserved
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed
10 * to you under the terms of the GNU General Public License version 2
11 * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
12 * with the following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give
15 * you permission to link this software with independent modules, and
16 * to copy and distribute the resulting executable under terms of your
17 * choice, provided that you also meet, for each linked independent
18 * module, the terms and conditions of the license of that module.
19 * An independent module is a module which is not derived from this
20 * software. The special exception does not apply to any modifications
21 * of the software.
22 *
23 * Not withstanding the above, under no circumstances may you combine
24 * this software in any way with any other Broadcom software provided
25 * under a license other than the GPL, without Broadcom's express prior
26 * written consent.
27 *
28 * :>
29 *
30 *****************************************************************************/
31
32/**
33 * @file bal_utils.c
34 * @brief BAL Utilities source
35 *
36 * This file contains the implementation of various BAL "utilities",
37 * which are provided via the libutils.a library.
38 */
39
40/*@{*/
41
42#ifdef USING_BAL_UTILS
43
44/* --- system includes ---*/
45#include <stdio.h>
46#include <stdlib.h>
47#include <errno.h>
48#include <limits.h>
49#include <arpa/inet.h>
50#include <string.h>
51
52#include <bcmos_system.h>
53
54/* --- project includes ---*/
55#include "bal_utils.h"
56
57
58/*
59 * Generic helper functions
60 */
61char *mac_addr_to_str(char *buffer, bcmos_mac_address mac)
62{
63 char *fmt_str = NULL;
64
65 fmt_str = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
66
67 snprintf(buffer, 20, fmt_str,
68 mac.u8[0], mac.u8[1],
69 mac.u8[2], mac.u8[3],
70 mac.u8[4], mac.u8[5]);
71
72 return buffer;
73}
74
75
76bcmos_bool mac_add_is_null(bcmos_mac_address mac)
77{
78 return ((0 != mac.u8[0]) || (0 != mac.u8[1]) || (0 != mac.u8[2]) ||
79 (0 != mac.u8[3]) || (0 != mac.u8[4]) || (0 != mac.u8[5])) ? BCMOS_FALSE : BCMOS_TRUE;
80}
81
82/**
83 * @brief Determines if string contains a valid IPv4 or IPv6 address
84 *
85 *
86 * @param ipAddrStr Pointer to string to parse
87 *
88 * @return bcmos_bool
89 * @retval TRUE String contains a valid IP address
90 * @retval FALSE String does not
91 */
92bcmos_bool BalIsValidIp(const char *ipAddrStr)
93{
94 struct sockaddr_in addr4;
95 struct in6_addr addr6;
96 bcmos_bool ret = BCMOS_FALSE;
97
98 /* Parameter checks. */
99 BUG_UNLESS(NULL != ipAddrStr, BCMOS_FALSE);
100
101 /* First look to see if it's a valid IPv4 address, then look to see if it's
102 a valid IPv6 address*/
103 if (inet_pton(AF_INET, ipAddrStr, &addr4) > 0 || inet_pton(AF_INET6, ipAddrStr, &addr6) > 0)
104 {
105 ret = TRUE;
106 }
107
108 return ret;
109}
110
111
112/**
113 * @brief Convert a string to the specified type of integer
114 *
115 * NOTE: This function uses the strtoll() function to convert the string to an
116 * integer value. U64 values greater than 0x7fffffffffffffff cannot be converted
117 * by the strtoll() function because the string value is considered out of the
118 * valid -0x8000000000000000 to 0x7fffffffffffffff 64-bit integer range.
119 *
120 * @param str String to convert
121 * @param pVal Pointer to the return value
122 *
123 * @return bcmos_errno
124 */
125static bcmos_errno BalStringToInt(char *str, BalIntStringT *pVal)
126{
127 bcmos_errno rc = BAL_OK;
128 U64 u64 = 0;
129 S64 s64 = 0;
130 char *endptr;
131
132 BUG_UNLESS(NULL != str, BAL_PARAM);
133 BUG_UNLESS(NULL != pVal, BAL_PARAM);
134 BUG_UNLESS(pVal->intType > BAL_STR2INT_INVALID, BAL_PARAM);
135 BUG_UNLESS(pVal->intType < BAL_STR2INT_MAX, BAL_PARAM);
136
137 do
138 {
139 if ((pVal->intType >= BAL_STR2INT_S8) &&
140 (pVal->intType <= BAL_STR2INT_S64))
141 {
142 /* Just assume a signed 64-bit value when converting the string to
143 * an integer. Range checking is done below. Make sure that errno
144 * is set to zero before calling strtoll().
145 */
146 errno = 0;
147 pVal->intU.s64 = 0; /* Clear all possibilities to 0 */
148 s64 = strtoll(str, &endptr, 10);
149
150 /* General range and error check */
151 if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
152 || (errno != 0 && s64 == 0))
153 {
154 errno = 0;
155 rc = BCM_ERR_RANGE;
156 break;
157
158 }
159
160 /* test for no digits or mixed digits and characters */
161 if (endptr == str || '\0' != *endptr)
162 {
163 errno = 0;
164 rc = BCM_ERR_PARM;
165 break;
166 }
167
168 /* routine specific range check */
169 switch (pVal->intType)
170 {
171 case BAL_STR2INT_S8:
172 if ((s64 < -128) || (s64 > 127))
173 {
174 rc = BCM_ERR_RANGE;
175 }
176 else
177 {
178 pVal->intU.s8 = (S8)s64;
179 }
180 break;
181 case BAL_STR2INT_S16:
182 if ((s64 < -32768) || (s64 > 32767))
183 {
184 rc = BCM_ERR_RANGE;
185 }
186 else
187 {
188 pVal->intU.s16 = (S16)s64;
189 }
190 break;
191 case BAL_STR2INT_S32:
192 if ((s64 < (-2147483647L -1L)) || (s64 > 2147483647L))
193 {
194 rc = BCM_ERR_RANGE;
195 }
196 else
197 {
198 pVal->intU.s32 = (S32)s64;
199 }
200 break;
201 case BAL_STR2INT_S64:
202 /* No range checking is needed since the strtoll() function
203 * does the range checking. If the string was invalid, errno
204 * would have been non-zero.
205 */
206 pVal->intU.s64 = s64;
207 break;
208 default:
209 /* Should never make it here. */
210 rc = BCM_ERR_PARM;
211 break;
212 }
213 }
214 else {
215 /* Just assume an unsigned 64-bit value when converting the string
216 * to an integer. Range checking is done below. Make sure that errno
217 * is set to zero before calling strtoull().
218 */
219 errno = 0;
220 pVal->intU.u64 = 0;
221 u64 = strtoull(str, &endptr, 10);
222
223 /* General range and error check */
224 if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
225 || (errno != 0 && s64 == 0))
226 {
227 errno = 0;
228 rc = BCM_ERR_RANGE;
229 break;
230
231 }
232
233 /* test for no digits or mixed digits and characters */
234 if (endptr == str || '\0' != *endptr)
235 {
236 errno = 0;
237 rc = BCM_ERR_PARM;
238 break;
239 }
240
241 /* routine specific range check */
242 switch(pVal->intType)
243 {
244 case BAL_STR2INT_U8:
245 if (u64 > 255)
246 {
247 rc = BCM_ERR_RANGE;
248 }
249 else
250 {
251 pVal->intU.u8 = (U8)u64;
252 }
253 break;
254 case BAL_STR2INT_U16:
255 if (u64 > 65535)
256 {
257 rc = BCM_ERR_RANGE;
258 }
259 else
260 {
261 pVal->intU.u16 = (U16)u64;
262 }
263 break;
264 case BAL_STR2INT_U32:
265 if (u64 > 4294967295UL)
266 {
267 rc = BCM_ERR_RANGE;
268 }
269 else
270 {
271 pVal->intU.u32 = (U32)u64;
272 }
273 break;
274 case BAL_STR2INT_U64:
275 /* No range checking is needed since the strtoull() function
276 * does the range checking. If the string was invalid, errno
277 * would have been non-zero.
278 */
279 pVal->intU.u64 = u64;
280 break;
281 default:
282 /* Should never make it here. */
283 rc = BCM_ERR_PARM;
284 break;
285 }
286 }
287 } while (0);
288
289 return(rc);
290}
291
292/**
293 * @brief Convert a string to an S8 type integer
294 *
295 * This function converts a string to an S8 type integer
296 *
297 * @param str String to convert
298 * @param pVal Pointer to the return value
299 *
300 * @return bcmos_errno
301 */
302bcmos_errno BalStringToS8(char *str, S8 *pVal)
303{
304 bcmos_errno rc = BAL_OK;
305 BalIntStringT intStr;
306
307 BUG_UNLESS(NULL != str, BAL_PARAM);
308 BUG_UNLESS(NULL != pVal, BAL_PARAM);
309
310 memset(&intStr, 0, sizeof(intStr));
311
312 intStr.intType = BAL_STR2INT_S8;
313
314 rc = BalStringToInt(str, &intStr);
315 if (BAL_OK == rc)
316 {
317 *pVal = intStr.intU.s8;
318 }
319
320 return(rc);
321}
322
323/**
324 * @brief Convert a string to an S16 type integer
325 *
326 * This function converts a string to an S16 type integer
327 *
328 * @param str String to convert
329 * @param pVal Pointer to the return value
330 *
331 * @return bcmos_errno
332 */
333bcmos_errno BalStringToS16(char *str, S16 *pVal)
334{
335 bcmos_errno rc = BAL_OK;
336 BalIntStringT intStr;
337
338 BUG_UNLESS(NULL != str, BAL_PARAM);
339 BUG_UNLESS(NULL != pVal, BAL_PARAM);
340
341 memset(&intStr, 0, sizeof(intStr));
342
343 intStr.intType = BAL_STR2INT_S16;
344
345 rc = BalStringToInt(str, &intStr);
346 if (BAL_OK == rc)
347 {
348 *pVal = intStr.intU.s16;
349 }
350
351 return(rc);
352}
353
354/**
355 * @brief Convert a string to an S32 type integer
356 *
357 * This function converts a string to an S32 type integer
358 *
359 * @param str String to convert
360 * @param pVal Pointer to the return value
361 *
362 * @return bcmos_errno
363 */
364bcmos_errno BalStringToS32(char *str, S32 *pVal)
365{
366 bcmos_errno rc = BAL_OK;
367 BalIntStringT intStr;
368
369 BUG_UNLESS(NULL != str, BAL_PARAM);
370 BUG_UNLESS(NULL != pVal, BAL_PARAM);
371
372 memset(&intStr, 0, sizeof(intStr));
373
374 intStr.intType = BAL_STR2INT_S32;
375
376 rc = BalStringToInt(str, &intStr);
377 if (BAL_OK == rc)
378 {
379 *pVal = intStr.intU.s32;
380 }
381
382 return(rc);
383}
384
385/**
386 * @brief Convert a string to an S64 type integer
387 *
388 * This function converts a string to an S64 type integer
389 *
390 * @param str String to convert
391 * @param pVal Pointer to the return value
392 *
393 * @return bcmos_errno
394 */
395bcmos_errno BalStringToS64(char *str, S64 *pVal)
396{
397 bcmos_errno rc = BAL_OK;
398 BalIntStringT intStr;
399
400 BUG_UNLESS(NULL != str, BAL_PARAM);
401 BUG_UNLESS(NULL != pVal, BAL_PARAM);
402
403 memset(&intStr, 0, sizeof(intStr));
404
405 intStr.intType = BAL_STR2INT_S64;
406
407 rc = BalStringToInt(str, &intStr);
408 if (BAL_OK == rc)
409 {
410 *pVal = intStr.intU.s64;
411 }
412
413 return(rc);
414}
415
416/**
417 * @brief Convert a string to a U8 type integer
418 *
419 * This function converts a string to a U8 type integer
420 *
421 * @param str String to convert
422 * @param pVal Pointer to the return value
423 *
424 * @return bcmos_errno
425 */
426bcmos_errno BalStringToU8(char *str, U8 *pVal)
427{
428 bcmos_errno rc = BAL_OK;
429 BalIntStringT intStr;
430
431 BUG_UNLESS(NULL != str, BAL_PARAM);
432 BUG_UNLESS(NULL != pVal, BAL_PARAM);
433
434 memset(&intStr, 0, sizeof(intStr));
435
436 intStr.intType = BAL_STR2INT_U8;
437
438 rc = BalStringToInt(str, &intStr);
439 if (BAL_OK == rc)
440 {
441 *pVal = intStr.intU.u8;
442 }
443
444 return(rc);
445}
446
447/**
448 * @brief Convert a string to a U16 type integer
449 *
450 * This function converts a string to a U16 type integer
451 *
452 * @param str String to convert
453 * @param pVal Pointer to the return value
454 *
455 * @return bcmos_errno
456 */
457bcmos_errno BalStringToU16(char *str, U16 *pVal)
458{
459 bcmos_errno rc = BAL_OK;
460 BalIntStringT intStr;
461
462 BUG_UNLESS(NULL != str, BAL_PARAM);
463 BUG_UNLESS(NULL != pVal, BAL_PARAM);
464
465 memset(&intStr, 0, sizeof(intStr));
466
467 intStr.intType = BAL_STR2INT_U16;
468
469 rc = BalStringToInt(str, &intStr);
470 if (BAL_OK == rc)
471 {
472 *pVal = intStr.intU.u16;
473 }
474
475 return(rc);
476}
477
478/**
479 * @brief Convert a string to a U32 type integer
480 *
481 * This function converts a string to a U32 type integer
482 *
483 * @param str String to convert
484 * @param pVal Pointer to the return value
485 *
486 * @return bcmos_errno
487 */
488bcmos_errno BalStringToU32(char *str, U32 *pVal)
489{
490 bcmos_errno rc = BAL_OK;
491 BalIntStringT intStr;
492
493 BUG_UNLESS(NULL != str, BAL_PARAM);
494 BUG_UNLESS(NULL != pVal, BAL_PARAM);
495
496 memset(&intStr, 0, sizeof(intStr));
497
498 intStr.intType = BAL_STR2INT_U32;
499
500 rc = BalStringToInt(str, &intStr);
501 if (BAL_OK == rc)
502 {
503 *pVal = intStr.intU.u32;
504 }
505
506 return(rc);
507}
508
509/**
510 * @brief Convert a string to a U64 type integer
511 *
512 * This function converts a string to a U64 type integer
513 *
514 * @param str String to convert
515 * @param pVal Pointer to the return value
516 *
517 * @return bcmos_errno
518 */
519bcmos_errno BalStringToU64(char *str, U64 *pVal)
520{
521 bcmos_errno rc = BAL_OK;
522 BalIntStringT intStr;
523
524 BUG_UNLESS(NULL != str, BAL_PARAM);
525 BUG_UNLESS(NULL != pVal, BAL_PARAM);
526
527 memset(&intStr, 0, sizeof(intStr));
528
529 intStr.intType = BAL_STR2INT_U64;
530
531 rc = BalStringToInt(str, &intStr);
532 if (BAL_OK == rc)
533 {
534 *pVal = intStr.intU.u64;
535 }
536
537 return(rc);
538}
539
540
541#endif /* USING_BAL_UTILS */