suricata
util-byte.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Brian Rectanus <brectanu@gmail.com>
22 *
23 * Byte utility functions
24 */
25
26#include "suricata-common.h"
27#include "util-byte.h"
28#include "util-unittest.h"
29#include "util-debug.h"
30#include "util-validate.h"
31
32/** \brief Turn byte array into string.
33 *
34 * All non-printables are copied over, except for '\0', which is
35 * turned into literal \0 in the string.
36 *
37 * \param bytes byte array
38 * \param nbytes number of bytes
39 * \return string nul-terminated string or NULL on error
40 */
41char *BytesToString(const uint8_t *bytes, size_t nbytes)
42{
43 size_t n = nbytes + 1;
44 size_t nulls = 0;
45
46 size_t u;
47 for (u = 0; u < nbytes; u++) {
48 if (bytes[u] == '\0')
49 nulls++;
50 }
51 n += nulls;
52
53 char *string = SCCalloc(1, n);
54 if (string == NULL)
55 return NULL;
56
57 if (nulls == 0) {
58 /* no nulls */
59 memcpy(string, bytes, nbytes);
60 } else {
61 /* nulls present */
62 char *dst = string;
63 for (u = 0; u < nbytes; u++) {
64 if (bytes[u] == '\0') {
65 *dst++ = '\\';
66 *dst++ = '0';
67 } else {
68 *dst++ = bytes[u];
69 }
70 }
71 }
72 return string;
73}
74
75/** \brief Turn byte array into string.
76 *
77 * All non-printables are copied over, except for '\0', which is
78 * turned into literal \0 in the string.
79 *
80 * \param bytes byte array
81 * \param nbytes number of bytes
82 * \param outstr[out] buffer to fill
83 * \param outlen size of outstr. Must be at least 2 * nbytes + 1 in size
84 */
85void BytesToStringBuffer(const uint8_t *bytes, size_t nbytes, char *outstr, size_t outlen)
86{
87 DEBUG_VALIDATE_BUG_ON(outlen < (nbytes * 2 + 1));
88
89 size_t n = nbytes + 1;
90 size_t nulls = 0;
91
92 size_t u;
93 for (u = 0; u < nbytes; u++) {
94 if (bytes[u] == '\0')
95 nulls++;
96 }
97 n += nulls;
98
99 char string[n];
100
101 if (nulls == 0) {
102 /* no nulls */
103 memcpy(string, bytes, nbytes);
104 string[nbytes] = '\0';
105 } else {
106 /* nulls present */
107 char *dst = string;
108 for (u = 0; u < nbytes; u++) {
109 if (bytes[u] == '\0') {
110 *dst++ = '\\';
111 *dst++ = '0';
112 } else {
113 *dst++ = bytes[u];
114 }
115 }
116 *dst = '\0';
117 }
118
119 strlcpy(outstr, string, outlen);
120}
121
122int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
123{
124 uint64_t i64;
125 int ret;
126
127 /* Uint64 is limited to 8 bytes */
128 if (len > 8) {
129 /** \todo Need standard return values */
130 return -1;
131 }
132
133 ret = ByteExtract(&i64, e, len, bytes);
134 if (ret <= 0) {
135 return ret;
136 }
137
138 *res = (uint64_t)i64;
139
140 return ret;
141}
142
143int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
144{
145 uint64_t i64;
146 int ret;
147
148 /* Uint32 is limited to 4 bytes */
149 if (len > 4) {
150 /** \todo Need standard return values */
151 return -1;
152 }
153
154 ret = ByteExtract(&i64, e, len, bytes);
155 if (ret <= 0) {
156 return ret;
157 }
158
159 *res = (uint32_t)i64;
160
161 return ret;
162}
163
164int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
165{
166 uint64_t i64;
167 int ret;
168
169 /* Uint16 is limited to 2 bytes */
170 if (len > 2) {
171 /** \todo Need standard return values */
172 return -1;
173 }
174
175 ret = ByteExtract(&i64, e, len, bytes);
176 if (ret <= 0) {
177 return ret;
178 }
179
180 *res = (uint16_t)i64;
181
182 return ret;
183}
184
185int ByteExtractString(uint64_t *res, int base, size_t len, const char *str, bool strict)
186{
187 const char *ptr = str;
188 char *endptr = NULL;
189
190 /* 23 - This is the largest string (octal, with a zero prefix) that
191 * will not overflow uint64_t. The only way this length
192 * could be over 23 and still not overflow is if it were zero
193 * prefixed and we only support 1 byte of zero prefix for octal.
194 *
195 * "01777777777777777777777" = 0xffffffffffffffff
196 */
197 char strbuf[24];
198
199 if (len > 23) {
200 SCLogDebug("len too large (23 max)");
201 return -1;
202 }
203
204 if (len) {
205 /* Extract out the string so it can be null terminated */
206 memcpy(strbuf, str, len);
207 strbuf[len] = '\0';
208 ptr = strbuf;
209 }
210
211 errno = 0;
212 *res = strtoull(ptr, &endptr, base);
213
214 if (errno == ERANGE) {
215 SCLogDebug("numeric value out of range");
216 return -1;
217 /* If there is no numeric value in the given string then strtoull(), makes
218 endptr equals to ptr and return 0 as result */
219 } else if (endptr == ptr && *res == 0) {
220 SCLogDebug("no numeric value");
221 return -1;
222 } else if (endptr == ptr) {
223 SCLogDebug("invalid numeric value");
224 return -1;
225 }
226 else if (strict && *endptr != '\0') {
227 SCLogError("Extra characters following numeric value");
228 return -1;
229 }
230
231 return (int)(endptr - ptr);
232}
233
234int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
235{
236 return ByteExtractString(res, base, len, str, false);
237}
238
239int ByteExtractStringUint32(uint32_t *res, int base, size_t len, const char *str)
240{
241 uint64_t i64;
242
243 int ret = ByteExtractString(&i64, base, len, str, false);
244 if (ret <= 0) {
245 return ret;
246 }
247 if (i64 > UINT32_MAX) {
248 return -1;
249 }
250
251 *res = (uint32_t)i64;
252
253 if ((uint64_t)(*res) != i64) {
254 SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
255 i64, (uintmax_t)UINT_MAX);
256 return -1;
257 }
258
259 return ret;
260}
261
262int ByteExtractStringUint16(uint16_t *res, int base, size_t len, const char *str)
263{
264 uint64_t i64;
265
266 int ret = ByteExtractString(&i64, base, len, str, false);
267 if (ret <= 0) {
268 return ret;
269 }
270 if (i64 > UINT16_MAX) {
271 return -1;
272 }
273
274 *res = (uint16_t)i64;
275
276 if ((uint64_t)(*res) != i64) {
277 SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
278 i64, (uintmax_t)USHRT_MAX);
279 return -1;
280 }
281
282 return ret;
283}
284
285int ByteExtractStringUint8(uint8_t *res, int base, size_t len, const char *str)
286{
287 uint64_t i64;
288
289 int ret = ByteExtractString(&i64, base, len, str, false);
290 if (ret <= 0) {
291 return ret;
292 }
293 if (i64 > UINT8_MAX) {
294 return -1;
295 }
296
297 *res = (uint8_t)i64;
298
299 if ((uint64_t)(*res) != i64) {
300 SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
301 i64, (uintmax_t)UCHAR_MAX);
302 return -1;
303 }
304
305 return ret;
306}
307
308int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
309{
310 return ByteExtractString(res, base, len, str, true);
311}
312
313int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
314{
315 uint64_t i64;
316
317 int ret = ByteExtractString(&i64, base, len, str, true);
318 if (ret <= 0) {
319 return ret;
320 }
321 if (i64 > UINT32_MAX) {
322 return -1;
323 }
324
325 *res = (uint32_t)i64;
326
327 if ((uint64_t)(*res) != i64) {
328 SCLogError("Numeric value out of range "
329 "(%" PRIu64 " > %" PRIuMAX ")",
330 i64, (uintmax_t)UINT_MAX);
331 return -1;
332 }
333
334 return ret;
335}
336
337int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
338{
339 uint64_t i64;
340
341 int ret = ByteExtractString(&i64, base, len, str, true);
342 if (ret <= 0) {
343 return ret;
344 }
345 if (i64 > UINT16_MAX) {
346 return -1;
347 }
348
349 *res = (uint16_t)i64;
350
351 if ((uint64_t)(*res) != i64) {
352 SCLogError("Numeric value out of range "
353 "(%" PRIu64 " > %" PRIuMAX ")",
354 i64, (uintmax_t)USHRT_MAX);
355 return -1;
356 }
357
358 return ret;
359}
360
361int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
362{
363 uint64_t i64;
364
365 int ret = ByteExtractString(&i64, base, len, str, true);
366 if (ret <= 0) {
367 return ret;
368 }
369 if (i64 > UINT8_MAX) {
370 return -1;
371 }
372
373 *res = (uint8_t)i64;
374
375 if ((uint64_t)(*res) != i64) {
376 SCLogError("Numeric value out of range "
377 "(%" PRIu64 " > %" PRIuMAX ")",
378 i64, (uintmax_t)UCHAR_MAX);
379 return -1;
380 }
381
382 return ret;
383}
384
386 uint64_t *res, int base, size_t len, const char *str, uint64_t min, uint64_t max)
387{
388 uint64_t u64;
389
390 int ret = ByteExtractString(&u64, base, len, str, true);
391 if (ret <= 0) {
392 return ret;
393 }
394
395 *res = u64;
396
397 if (*res < min || *res > max) {
398 return -1;
399 }
400
401 return ret;
402}
403
405 uint32_t *res, int base, size_t len, const char *str, uint32_t min, uint32_t max)
406{
407 uint64_t u64;
408
409 int ret = ByteExtractString(&u64, base, len, str, true);
410 if (ret <= 0) {
411 return ret;
412 }
413 if (u64 > UINT32_MAX) {
414 return -1;
415 }
416
417 *res = (uint32_t)u64;
418
419 if (*res < min || *res > max) {
420 return -1;
421 }
422
423 if ((uint64_t)(*res) != u64) {
424 SCLogError("Numeric value out of range "
425 "(%" PRIu64 " > %" PRIuMAX ")",
426 u64, (uintmax_t)UINT_MAX);
427 return -1;
428 }
429
430 return ret;
431}
432
434 uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
435{
436 uint64_t u64;
437
438 int ret = ByteExtractString(&u64, base, len, str, true);
439 if (ret <= 0) {
440 return ret;
441 }
442 if (u64 > UINT16_MAX) {
443 return -1;
444 }
445
446 *res = (uint16_t)u64;
447
448 if (*res < min || *res > max) {
449 return -1;
450 }
451
452 if ((uint64_t)(*res) != u64) {
453 SCLogError("Numeric value out of range "
454 "(%" PRIu64 " > %" PRIuMAX ")",
455 u64, (uintmax_t)USHRT_MAX);
456 return -1;
457 }
458
459 return ret;
460}
461
463 uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
464{
465 uint64_t u64;
466
467 int ret = ByteExtractString(&u64, base, len, str, true);
468 if (ret <= 0) {
469 return ret;
470 }
471 if (u64 > UINT8_MAX) {
472 return -1;
473 }
474
475 *res = (uint8_t)u64;
476
477 if (*res < min || *res > max) {
478 return -1;
479 }
480
481 if ((uint64_t)(*res) != u64) {
482 SCLogError("Numeric value out of range "
483 "(%" PRIu64 " > %" PRIuMAX ")",
484 u64, (uintmax_t)UCHAR_MAX);
485 return -1;
486 }
487
488 return ret;
489}
490
491int ByteExtractStringSigned(int64_t *res, int base, size_t len, const char *str, bool strict)
492{
493 const char *ptr = str;
494 char *endptr;
495
496 /* 23 - This is the largest string (octal, with a zero prefix) that
497 * will not overflow int64_t. The only way this length
498 * could be over 23 and still not overflow is if it were zero
499 * prefixed and we only support 1 byte of zero prefix for octal.
500 *
501 * "-0777777777777777777777" = 0xffffffffffffffff
502 */
503 char strbuf[24];
504
505 if (len > 23) {
506 SCLogError("len too large (23 max)");
507 return -1;
508 }
509
510 if (len) {
511 /* Extract out the string so it can be null terminated */
512 memcpy(strbuf, str, len);
513 strbuf[len] = '\0';
514 ptr = strbuf;
515 }
516
517 errno = 0;
518 *res = strtoll(ptr, &endptr, base);
519
520 if (errno == ERANGE) {
521 SCLogError("Numeric value out of range");
522 return -1;
523 } else if (endptr == str) {
524 SCLogError("Invalid numeric value");
525 return -1;
526 }
527 else if (strict && len && *endptr != '\0') {
528 SCLogError("Extra characters following numeric value");
529 return -1;
530 }
531
532 //fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res);
533
534 return (int)(endptr - ptr);
535}
536
537int ByteExtractStringInt64(int64_t *res, int base, size_t len, const char *str)
538{
539 return ByteExtractStringSigned(res, base, len, str, false);
540}
541
542int ByteExtractStringInt32(int32_t *res, int base, size_t len, const char *str)
543{
544 int64_t i64;
545 int ret;
546
547 ret = ByteExtractStringSigned(&i64, base, len, str, false);
548 if (ret <= 0) {
549 return ret;
550 }
551 if (i64 < INT32_MIN || i64 > INT32_MAX) {
552 return -1;
553 }
554
555 *res = (int32_t)i64;
556
557 if ((int64_t)(*res) != i64) {
558 SCLogError("Numeric value out of range "
559 "(%" PRIi64 " > %" PRIiMAX ")\n",
560 i64, (intmax_t)INT_MAX);
561 return -1;
562 }
563
564 return ret;
565}
566
567int ByteExtractStringInt16(int16_t *res, int base, size_t len, const char *str)
568{
569 int64_t i64;
570 int ret;
571
572 ret = ByteExtractStringSigned(&i64, base, len, str, false);
573 if (ret <= 0) {
574 return ret;
575 }
576 if (i64 < INT16_MIN || i64 > INT16_MAX) {
577 return -1;
578 }
579
580 *res = (int16_t)i64;
581
582 if ((int64_t)(*res) != i64) {
583 SCLogError("Numeric value out of range "
584 "(%" PRIi64 " > %" PRIiMAX ")\n",
585 i64, (intmax_t)SHRT_MAX);
586 return -1;
587 }
588
589 return ret;
590}
591
592int ByteExtractStringInt8(int8_t *res, int base, size_t len, const char *str)
593{
594 int64_t i64;
595 int ret;
596
597 ret = ByteExtractStringSigned(&i64, base, len, str, false);
598 if (ret <= 0) {
599 return ret;
600 }
601 if (i64 < INT8_MIN || i64 > INT8_MAX) {
602 return -1;
603 }
604
605 *res = (int8_t)i64;
606
607 if ((int64_t)(*res) != i64) {
608 SCLogError("Numeric value out of range "
609 "(%" PRIi64 " > %" PRIiMAX ")\n",
610 i64, (intmax_t)CHAR_MAX);
611 return -1;
612 }
613
614 return ret;
615}
616
617int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
618{
619 return ByteExtractStringSigned(res, base, len, str, true);
620}
621
622int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
623{
624 int64_t i64;
625 int ret;
626
627 ret = ByteExtractStringSigned(&i64, base, len, str, true);
628 if (ret <= 0) {
629 return ret;
630 }
631 if (i64 < INT32_MIN || i64 > INT32_MAX) {
632 return -1;
633 }
634
635 *res = (int32_t)i64;
636
637 if ((int64_t)(*res) != i64) {
638 SCLogError("Numeric value out of range "
639 "(%" PRIi64 " > %" PRIiMAX ")\n",
640 i64, (intmax_t)INT_MAX);
641 return -1;
642 }
643
644 return ret;
645}
646
647int StringParseInt16(int16_t *res, int base, size_t len, const char *str)
648{
649 int64_t i64;
650 int ret;
651
652 ret = ByteExtractStringSigned(&i64, base, len, str, true);
653 if (ret <= 0) {
654 return ret;
655 }
656 if (i64 < INT16_MIN || i64 > INT16_MAX) {
657 return -1;
658 }
659
660 *res = (int16_t)i64;
661
662 if ((int64_t)(*res) != i64) {
663 SCLogError("Numeric value out of range "
664 "(%" PRIi64 " > %" PRIiMAX ")\n",
665 i64, (intmax_t)SHRT_MAX);
666 return -1;
667 }
668
669 return ret;
670}
671
672int StringParseInt8(int8_t *res, int base, size_t len, const char *str)
673{
674 int64_t i64;
675 int ret;
676
677 ret = ByteExtractStringSigned(&i64, base, len, str, true);
678 if (ret <= 0) {
679 return ret;
680 }
681 if (i64 < INT8_MIN || i64 > INT8_MAX) {
682 return -1;
683 }
684
685 *res = (int8_t)i64;
686
687 if ((int64_t)(*res) != i64) {
688 SCLogError("Numeric value out of range "
689 "(%" PRIi64 " > %" PRIiMAX ")\n",
690 i64, (intmax_t)CHAR_MAX);
691 return -1;
692 }
693
694 return ret;
695}
696
698 int64_t *res, int base, size_t len, const char *str, int64_t min, int64_t max)
699{
700 int64_t i64;
701 int ret;
702
703 ret = ByteExtractStringSigned(&i64, base, len, str, true);
704 if (ret <= 0) {
705 return ret;
706 }
707
708 *res = i64;
709 if (*res < min || *res > max) {
710 return -1;
711 }
712
713 return ret;
714}
715
717 int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
718{
719 int64_t i64;
720 int ret;
721
722 ret = ByteExtractStringSigned(&i64, base, len, str, true);
723 if (ret <= 0) {
724 return ret;
725 }
726 if (i64 < INT32_MIN || i64 > INT32_MAX) {
727 return -1;
728 }
729
730 *res = (int32_t)i64;
731
732 if (*res < min || *res > max) {
733 return -1;
734 }
735
736 if ((int64_t)(*res) != i64) {
737 SCLogError("Numeric value out of range "
738 "(%" PRIi64 " > %" PRIiMAX ")\n",
739 i64, (intmax_t)INT_MAX);
740 return -1;
741 }
742
743 return ret;
744}
745
747 int16_t *res, int base, size_t len, const char *str, int16_t min, int16_t max)
748{
749 int64_t i64;
750 int ret;
751
752 ret = ByteExtractStringSigned(&i64, base, len, str, true);
753 if (ret <= 0) {
754 return ret;
755 }
756 if (i64 < INT16_MIN || i64 > INT16_MAX) {
757 return -1;
758 }
759
760 *res = (int16_t)i64;
761
762 if (*res < min || *res > max) {
763 return -1;
764 }
765
766 if ((int64_t)(*res) != i64) {
767 SCLogError("Numeric value out of range "
768 "(%" PRIi64 " > %" PRIiMAX ")\n",
769 i64, (intmax_t)SHRT_MAX);
770 return -1;
771 }
772
773 return ret;
774}
775
777 int8_t *res, int base, size_t len, const char *str, int8_t min, int8_t max)
778{
779 int64_t i64;
780 int ret;
781
782 ret = ByteExtractStringSigned(&i64, base, len, str, true);
783 if (ret <= 0) {
784 return ret;
785 }
786 if (i64 < INT8_MIN || i64 > INT8_MAX) {
787 return -1;
788 }
789
790 *res = (int8_t)i64;
791
792 if (*res < min || *res > max) {
793 return -1;
794 }
795
796 if ((int64_t)(*res) != i64) {
797 SCLogError("Numeric value out of range "
798 "(%" PRIi64 " > %" PRIiMAX ")\n",
799 i64, (intmax_t)CHAR_MAX);
800 return -1;
801 }
802
803 return ret;
804}
805
806int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
807{
808 if (ins < 2)
809 return -1;
810 if (ins % 2 != 0)
811 return -1;
812 if (outs != ins / 2)
813 return -1;
814
815 uint8_t hash[outs];
816 memset(hash, 0, outs);
817 size_t i, x;
818 for (x = 0, i = 0; i < ins; i += 2, x++) {
819 char buf[3] = { 0, 0, 0 };
820 buf[0] = in[i];
821 buf[1] = in[i + 1];
822
823 long value = strtol(buf, NULL, 16);
824 if (value >= 0 && value <= 255)
825 hash[x] = (uint8_t)value;
826 else {
827 SCLogError("hash byte out of range %ld", value);
828 return -1;
829 }
830 }
831
832 memcpy(out, hash, outs);
833 return 0;
834}
835
836/* UNITTESTS */
837#ifdef UNITTESTS
838
839static int ByteTest01 (void)
840{
841 uint16_t val = 0x0102;
842 uint16_t i16 = 0xbfbf;
843 uint8_t bytes[2] = { 0x02, 0x01 };
844 int ret = ByteExtractUint16(&i16, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
845
846 if ((ret == 2) && (i16 == val)) {
847 return 1;
848 }
849
850 return 0;
851}
852
853static int ByteTest02 (void)
854{
855 uint16_t val = 0x0102;
856 uint16_t i16 = 0xbfbf;
857 uint8_t bytes[2] = { 0x01, 0x02 };
858 int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
859
860 if ((ret == 2) && (i16 == val)) {
861 return 1;
862 }
863
864 return 0;
865}
866
867static int ByteTest03 (void)
868{
869 uint32_t val = 0x01020304;
870 uint32_t i32 = 0xbfbfbfbf;
871 uint8_t bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
872 int ret = ByteExtractUint32(&i32, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
873
874 if ((ret == 4) && (i32 == val)) {
875 return 1;
876 }
877
878 return 0;
879}
880
881static int ByteTest04 (void)
882{
883 uint32_t val = 0x01020304;
884 uint32_t i32 = 0xbfbfbfbf;
885 uint8_t bytes[4] = { 0x01, 0x02, 0x03, 0x04 };
886 int ret = ByteExtractUint32(&i32, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
887
888 if ((ret == 4) && (i32 == val)) {
889 return 1;
890 }
891
892 return 0;
893}
894
895static int ByteTest05 (void)
896{
897 uint64_t val = 0x0102030405060708ULL;
898 uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
899 uint8_t bytes[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
900 int ret = ByteExtractUint64(&i64, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
901
902 if ((ret == 8) && (i64 == val)) {
903 return 1;
904 }
905
906 return 0;
907}
908
909static int ByteTest06 (void)
910{
911 uint64_t val = 0x0102030405060708ULL;
912 uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
913 uint8_t bytes[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
914 int ret = ByteExtractUint64(&i64, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
915
916 if ((ret == 8) && (i64 == val)) {
917 return 1;
918 }
919
920 return 0;
921}
922
923static int ByteTest07 (void)
924{
925 const char str[] = "1234567890";
926 uint64_t val = 1234567890;
927 uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
928 int ret = ByteExtractStringUint64(&i64, 10, sizeof(str) - 1, str);
929
930 if ((ret == 10) && (i64 == val)) {
931 return 1;
932 }
933
934 return 0;
935}
936
937static int ByteTest08 (void)
938{
939 const char str[] = "1234567890";
940 uint32_t val = 1234567890;
941 uint32_t i32 = 0xbfbfbfbf;
942 int ret = ByteExtractStringUint32(&i32, 10, sizeof(str) - 1, str);
943
944 if ((ret == 10) && (i32 == val)) {
945 return 1;
946 }
947
948 return 0;
949}
950
951static int ByteTest09 (void)
952{
953 const char str[] = "12345";
954 uint16_t val = 12345;
955 uint16_t i16 = 0xbfbf;
956 int ret = ByteExtractStringUint16(&i16, 10, sizeof(str) - 1, str);
957
958 if ((ret == 5) && (i16 == val)) {
959 return 1;
960 }
961
962 return 0;
963}
964
965static int ByteTest10 (void)
966{
967 const char str[] = "123";
968 uint8_t val = 123;
969 uint8_t i8 = 0xbf;
970 int ret = ByteExtractStringUint8(&i8, 10, sizeof(str) - 1, str);
971
972 if ((ret == 3) && (i8 == val)) {
973 return 1;
974 }
975
976 return 0;
977}
978
979static int ByteTest11 (void)
980{
981 const char str[] = "-1234567890";
982 int64_t val = -1234567890;
983 int64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
984 int ret = ByteExtractStringInt64(&i64, 10, sizeof(str) - 1, str);
985
986 if ((ret == 11) && (i64 == val)) {
987 return 1;
988 }
989
990 return 0;
991}
992
993static int ByteTest12 (void)
994{
995 const char str[] = "-1234567890";
996 int32_t val = -1234567890;
997 int32_t i32 = 0xbfbfbfbf;
998 int ret = ByteExtractStringInt32(&i32, 10, sizeof(str) - 1, str);
999
1000 if ((ret == 11) && (i32 == val)) {
1001 return 1;
1002 }
1003
1004 return 0;
1005}
1006
1007static int ByteTest13 (void)
1008{
1009 const char str[] = "-12345";
1010 int16_t val = -12345;
1011 int16_t i16 = 0xbfbf;
1012 int ret = ByteExtractStringInt16(&i16, 10, sizeof(str) - 1, str);
1013
1014 if ((ret == 6) && (i16 == val)) {
1015 return 1;
1016 }
1017
1018 return 0;
1019}
1020
1021static int ByteTest14 (void)
1022{
1023 const char str[] = "-123";
1024 int8_t val = -123;
1025 int8_t i8 = 0xbf;
1026 int ret = ByteExtractStringInt8(&i8, 10, sizeof(str) - 1, str);
1027
1028 if ((ret == 4) && (i8 == val)) {
1029 return 1;
1030 }
1031
1032 return 0;
1033}
1034
1035/** \test max u32 value */
1036static int ByteTest15 (void)
1037{
1038 const char str[] = "4294967295";
1039 uint32_t val = 4294967295UL;
1040 uint32_t u32 = 0xffffffff;
1041
1042 int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1043 if ((ret == 10) && (u32 == val)) {
1044 return 1;
1045 }
1046
1047 return 0;
1048}
1049
1050/** \test max u32 value + 1 */
1051static int ByteTest16 (void)
1052{
1053 const char str[] = "4294967296";
1054 uint32_t u32 = 0;
1055
1056 int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1057 if (ret != 0) {
1058 return 1;
1059 }
1060
1061 return 0;
1062}
1063
1065{
1066 UtRegisterTest("ByteTest01", ByteTest01);
1067 UtRegisterTest("ByteTest02", ByteTest02);
1068 UtRegisterTest("ByteTest03", ByteTest03);
1069 UtRegisterTest("ByteTest04", ByteTest04);
1070 UtRegisterTest("ByteTest05", ByteTest05);
1071 UtRegisterTest("ByteTest06", ByteTest06);
1072 UtRegisterTest("ByteTest07", ByteTest07);
1073 UtRegisterTest("ByteTest08", ByteTest08);
1074 UtRegisterTest("ByteTest09", ByteTest09);
1075 UtRegisterTest("ByteTest10", ByteTest10);
1076 UtRegisterTest("ByteTest11", ByteTest11);
1077 UtRegisterTest("ByteTest12", ByteTest12);
1078 UtRegisterTest("ByteTest13", ByteTest13);
1079 UtRegisterTest("ByteTest14", ByteTest14);
1080 UtRegisterTest("ByteTest15", ByteTest15);
1081 UtRegisterTest("ByteTest16", ByteTest16);
1082}
1083#endif /* UNITTESTS */
1084
uint8_t len
uint16_t dst
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define str(s)
size_t strlcpy(char *dst, const char *src, size_t siz)
int StringParseU64RangeCheck(uint64_t *res, int base, size_t len, const char *str, uint64_t min, uint64_t max)
Definition util-byte.c:385
int ByteExtractString(uint64_t *res, int base, size_t len, const char *str, bool strict)
Definition util-byte.c:185
int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition util-byte.c:143
void ByteRegisterTests(void)
Definition util-byte.c:1064
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition util-byte.c:462
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:337
int StringParseI8RangeCheck(int8_t *res, int base, size_t len, const char *str, int8_t min, int8_t max)
Definition util-byte.c:776
int StringParseU16RangeCheck(uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
Definition util-byte.c:433
int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition util-byte.c:164
int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
Definition util-byte.c:308
int StringParseI16RangeCheck(int16_t *res, int base, size_t len, const char *str, int16_t min, int16_t max)
Definition util-byte.c:746
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:313
int ByteExtractStringInt64(int64_t *res, int base, size_t len, const char *str)
Definition util-byte.c:537
int StringParseInt8(int8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:672
int ByteExtractStringInt8(int8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:592
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:361
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition util-byte.c:122
int ByteExtractStringUint8(uint8_t *res, int base, size_t len, const char *str)
Definition util-byte.c:285
int ByteExtractStringInt32(int32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:542
int ByteExtractStringUint32(uint32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:239
int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
Definition util-byte.c:806
int StringParseI32RangeCheck(int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
Definition util-byte.c:716
int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
Definition util-byte.c:617
int StringParseInt16(int16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:647
int StringParseU32RangeCheck(uint32_t *res, int base, size_t len, const char *str, uint32_t min, uint32_t max)
Definition util-byte.c:404
int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:622
int ByteExtractStringInt16(int16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:567
int ByteExtractStringSigned(int64_t *res, int base, size_t len, const char *str, bool strict)
Definition util-byte.c:491
void BytesToStringBuffer(const uint8_t *bytes, size_t nbytes, char *outstr, size_t outlen)
Turn byte array into string.
Definition util-byte.c:85
int StringParseI64RangeCheck(int64_t *res, int base, size_t len, const char *str, int64_t min, int64_t max)
Definition util-byte.c:697
char * BytesToString(const uint8_t *bytes, size_t nbytes)
Turn byte array into string.
Definition util-byte.c:41
int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
Definition util-byte.c:234
int ByteExtractStringUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:262
#define BYTE_BIG_ENDIAN
Definition util-byte.h:29
#define BYTE_LITTLE_ENDIAN
Definition util-byte.h:30
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define DEBUG_VALIDATE_BUG_ON(exp)