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  */
41 char *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  */
85 void 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 
122 int 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 
143 int 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 
164 int 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 
185 int ByteExtractString(uint64_t *res, int base, uint16_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(SC_ERR_INVALID_NUMERIC_VALUE, "Extra characters following numeric value");
228  return -1;
229  }
230 
231  return (endptr - ptr);
232 }
233 
234 int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
235 {
236  return ByteExtractString(res, base, len, str, false);
237 }
238 
239 int ByteExtractStringUint32(uint32_t *res, int base, uint16_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 
262 int ByteExtractStringUint16(uint16_t *res, int base, uint16_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 
285 int ByteExtractStringUint8(uint8_t *res, int base, uint16_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 
308 int StringParseUint64(uint64_t *res, int base, uint16_t len, const char *str)
309 {
310  return ByteExtractString(res, base, len, str, true);
311 }
312 
313 int StringParseUint32(uint32_t *res, int base, uint16_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(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
329  "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)UINT_MAX);
330  return -1;
331  }
332 
333  return ret;
334 }
335 
336 int StringParseUint16(uint16_t *res, int base, uint16_t len, const char *str)
337 {
338  uint64_t i64;
339 
340  int ret = ByteExtractString(&i64, base, len, str, true);
341  if (ret <= 0) {
342  return ret;
343  }
344  if (i64 > UINT16_MAX) {
345  return -1;
346  }
347 
348  *res = (uint16_t)i64;
349 
350  if ((uint64_t)(*res) != i64) {
351  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
352  "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)USHRT_MAX);
353  return -1;
354  }
355 
356  return ret;
357 }
358 
359 int StringParseUint8(uint8_t *res, int base, uint16_t len, const char *str)
360 {
361  uint64_t i64;
362 
363  int ret = ByteExtractString(&i64, base, len, str, true);
364  if (ret <= 0) {
365  return ret;
366  }
367  if (i64 > UINT8_MAX) {
368  return -1;
369  }
370 
371  *res = (uint8_t)i64;
372 
373  if ((uint64_t)(*res) != i64) {
374  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
375  "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)UCHAR_MAX);
376  return -1;
377  }
378 
379  return ret;
380 }
381 
382 int StringParseU64RangeCheck(uint64_t *res, int base, uint16_t len, const char *str,
383  uint64_t min, uint64_t max)
384 {
385  uint64_t u64;
386 
387  int ret = ByteExtractString(&u64, base, len, str, true);
388  if (ret <= 0) {
389  return ret;
390  }
391 
392  *res = u64;
393 
394  if (*res < min || *res > max) {
395  return -1;
396  }
397 
398  return ret;
399 }
400 
401 int StringParseU32RangeCheck(uint32_t *res, int base, uint16_t len, const char *str,
402  uint32_t min, uint32_t max)
403 {
404  uint64_t u64;
405 
406  int ret = ByteExtractString(&u64, base, len, str, true);
407  if (ret <= 0) {
408  return ret;
409  }
410  if (u64 > UINT32_MAX) {
411  return -1;
412  }
413 
414  *res = (uint32_t)u64;
415 
416  if (*res < min || *res > max) {
417  return -1;
418  }
419 
420  if ((uint64_t)(*res) != u64) {
421  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
422  "(%" PRIu64 " > %" PRIuMAX ")", u64, (uintmax_t)UINT_MAX);
423  return -1;
424  }
425 
426  return ret;
427 }
428 
429 int StringParseU16RangeCheck(uint16_t *res, int base, uint16_t len, const char *str,
430  uint16_t min, uint16_t max)
431 {
432  uint64_t u64;
433 
434  int ret = ByteExtractString(&u64, base, len, str, true);
435  if (ret <= 0) {
436  return ret;
437  }
438  if (u64 > UINT16_MAX) {
439  return -1;
440  }
441 
442  *res = (uint16_t)u64;
443 
444  if (*res < min || *res > max) {
445  return -1;
446  }
447 
448  if ((uint64_t)(*res) != u64) {
449  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
450  "(%" PRIu64 " > %" PRIuMAX ")", u64, (uintmax_t)USHRT_MAX);
451  return -1;
452  }
453 
454  return ret;
455 }
456 
457 int StringParseU8RangeCheck(uint8_t *res, int base, uint16_t len, const char *str,
458  uint8_t min, uint8_t max)
459 {
460  uint64_t u64;
461 
462  int ret = ByteExtractString(&u64, base, len, str, true);
463  if (ret <= 0) {
464  return ret;
465  }
466  if (u64 > UINT8_MAX) {
467  return -1;
468  }
469 
470  *res = (uint8_t)u64;
471 
472  if (*res < min || *res > max) {
473  return -1;
474  }
475 
476  if ((uint64_t)(*res) != u64) {
477  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
478  "(%" PRIu64 " > %" PRIuMAX ")", u64, (uintmax_t)UCHAR_MAX);
479  return -1;
480  }
481 
482  return ret;
483 }
484 
485 int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str, bool strict)
486 {
487  const char *ptr = str;
488  char *endptr;
489 
490  /* 23 - This is the largest string (octal, with a zero prefix) that
491  * will not overflow int64_t. The only way this length
492  * could be over 23 and still not overflow is if it were zero
493  * prefixed and we only support 1 byte of zero prefix for octal.
494  *
495  * "-0777777777777777777777" = 0xffffffffffffffff
496  */
497  char strbuf[24];
498 
499  if (len > 23) {
500  SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)");
501  return -1;
502  }
503 
504  if (len) {
505  /* Extract out the string so it can be null terminated */
506  memcpy(strbuf, str, len);
507  strbuf[len] = '\0';
508  ptr = strbuf;
509  }
510 
511  errno = 0;
512  *res = strtoll(ptr, &endptr, base);
513 
514  if (errno == ERANGE) {
515  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range");
516  return -1;
517  } else if (endptr == str) {
518  SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value");
519  return -1;
520  }
521  else if (strict && len && *endptr != '\0') {
522  SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Extra characters following numeric value");
523  return -1;
524  }
525 
526  //fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res);
527 
528  return (endptr - ptr);
529 }
530 
531 int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str)
532 {
533  return ByteExtractStringSigned(res, base, len, str, false);
534 }
535 
536 int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
537 {
538  int64_t i64;
539  int ret;
540 
541  ret = ByteExtractStringSigned(&i64, base, len, str, false);
542  if (ret <= 0) {
543  return ret;
544  }
545  if (i64 < INT32_MIN || i64 > INT32_MAX) {
546  return -1;
547  }
548 
549  *res = (int32_t)i64;
550 
551  if ((int64_t)(*res) != i64) {
552  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
553  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)INT_MAX);
554  return -1;
555  }
556 
557  return ret;
558 }
559 
560 int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str)
561 {
562  int64_t i64;
563  int ret;
564 
565  ret = ByteExtractStringSigned(&i64, base, len, str, false);
566  if (ret <= 0) {
567  return ret;
568  }
569  if (i64 < INT16_MIN || i64 > INT16_MAX) {
570  return -1;
571  }
572 
573  *res = (int16_t)i64;
574 
575  if ((int64_t)(*res) != i64) {
576  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
577  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)SHRT_MAX);
578  return -1;
579  }
580 
581  return ret;
582 }
583 
584 int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str)
585 {
586  int64_t i64;
587  int ret;
588 
589  ret = ByteExtractStringSigned(&i64, base, len, str, false);
590  if (ret <= 0) {
591  return ret;
592  }
593  if (i64 < INT8_MIN || i64 > INT8_MAX) {
594  return -1;
595  }
596 
597  *res = (int8_t)i64;
598 
599  if ((int64_t)(*res) != i64) {
600  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
601  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)CHAR_MAX);
602  return -1;
603  }
604 
605  return ret;
606 }
607 
608 int StringParseInt64(int64_t *res, int base, uint16_t len, const char *str)
609 {
610  return ByteExtractStringSigned(res, base, len, str, true);
611 }
612 
613 int StringParseInt32(int32_t *res, int base, uint16_t len, const char *str)
614 {
615  int64_t i64;
616  int ret;
617 
618  ret = ByteExtractStringSigned(&i64, base, len, str, true);
619  if (ret <= 0) {
620  return ret;
621  }
622  if (i64 < INT32_MIN || i64 > INT32_MAX) {
623  return -1;
624  }
625 
626  *res = (int32_t)i64;
627 
628  if ((int64_t)(*res) != i64) {
629  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
630  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)INT_MAX);
631  return -1;
632  }
633 
634  return ret;
635 }
636 
637 int StringParseInt16(int16_t *res, int base, uint16_t len, const char *str)
638 {
639  int64_t i64;
640  int ret;
641 
642  ret = ByteExtractStringSigned(&i64, base, len, str, true);
643  if (ret <= 0) {
644  return ret;
645  }
646  if (i64 < INT16_MIN || i64 > INT16_MAX) {
647  return -1;
648  }
649 
650  *res = (int16_t)i64;
651 
652  if ((int64_t)(*res) != i64) {
653  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
654  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)SHRT_MAX);
655  return -1;
656  }
657 
658  return ret;
659 }
660 
661 int StringParseInt8(int8_t *res, int base, uint16_t len, const char *str)
662 {
663  int64_t i64;
664  int ret;
665 
666  ret = ByteExtractStringSigned(&i64, base, len, str, true);
667  if (ret <= 0) {
668  return ret;
669  }
670  if (i64 < INT8_MIN || i64 > INT8_MAX) {
671  return -1;
672  }
673 
674  *res = (int8_t)i64;
675 
676  if ((int64_t)(*res) != i64) {
677  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
678  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)CHAR_MAX);
679  return -1;
680  }
681 
682  return ret;
683 }
684 
685 int StringParseI64RangeCheck(int64_t *res, int base, uint16_t len, const char *str,
686  int64_t min, int64_t max)
687 {
688  int64_t i64;
689  int ret;
690 
691  ret = ByteExtractStringSigned(&i64, base, len, str, true);
692  if (ret <= 0) {
693  return ret;
694  }
695 
696  *res = i64;
697  if (*res < min || *res > max) {
698  return -1;
699  }
700 
701  return ret;
702 }
703 
704 int StringParseI32RangeCheck(int32_t *res, int base, uint16_t len, const char *str,
705  int32_t min, int32_t max)
706 {
707  int64_t i64;
708  int ret;
709 
710  ret = ByteExtractStringSigned(&i64, base, len, str, true);
711  if (ret <= 0) {
712  return ret;
713  }
714  if (i64 < INT32_MIN || i64 > INT32_MAX) {
715  return -1;
716  }
717 
718  *res = (int32_t)i64;
719 
720  if (*res < min || *res > max) {
721  return -1;
722  }
723 
724  if ((int64_t)(*res) != i64) {
725  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
726  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)INT_MAX);
727  return -1;
728  }
729 
730  return ret;
731 }
732 
733 int StringParseI16RangeCheck(int16_t *res, int base, uint16_t len, const char *str,
734  int16_t min, int16_t max)
735 {
736  int64_t i64;
737  int ret;
738 
739  ret = ByteExtractStringSigned(&i64, base, len, str, true);
740  if (ret <= 0) {
741  return ret;
742  }
743  if (i64 < INT16_MIN || i64 > INT16_MAX) {
744  return -1;
745  }
746 
747  *res = (int16_t)i64;
748 
749  if (*res < min || *res > max) {
750  return -1;
751  }
752 
753  if ((int64_t)(*res) != i64) {
754  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
755  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)SHRT_MAX);
756  return -1;
757  }
758 
759  return ret;
760 }
761 
762 int StringParseI8RangeCheck(int8_t *res, int base, uint16_t len, const char *str,
763  int8_t min, int8_t max)
764 {
765  int64_t i64;
766  int ret;
767 
768  ret = ByteExtractStringSigned(&i64, base, len, str, true);
769  if (ret <= 0) {
770  return ret;
771  }
772  if (i64 < INT8_MIN || i64 > INT8_MAX) {
773  return -1;
774  }
775 
776  *res = (int8_t)i64;
777 
778  if (*res < min || *res > max) {
779  return -1;
780  }
781 
782  if ((int64_t)(*res) != i64) {
783  SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range "
784  "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)CHAR_MAX);
785  return -1;
786  }
787 
788  return ret;
789 }
790 
791 /* UNITTESTS */
792 #ifdef UNITTESTS
793 
794 static int ByteTest01 (void)
795 {
796  uint16_t val = 0x0102;
797  uint16_t i16 = 0xbfbf;
798  uint8_t bytes[2] = { 0x02, 0x01 };
799  int ret = ByteExtractUint16(&i16, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
800 
801  if ((ret == 2) && (i16 == val)) {
802  return 1;
803  }
804 
805  return 0;
806 }
807 
808 static int ByteTest02 (void)
809 {
810  uint16_t val = 0x0102;
811  uint16_t i16 = 0xbfbf;
812  uint8_t bytes[2] = { 0x01, 0x02 };
813  int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
814 
815  if ((ret == 2) && (i16 == val)) {
816  return 1;
817  }
818 
819  return 0;
820 }
821 
822 static int ByteTest03 (void)
823 {
824  uint32_t val = 0x01020304;
825  uint32_t i32 = 0xbfbfbfbf;
826  uint8_t bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
827  int ret = ByteExtractUint32(&i32, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
828 
829  if ((ret == 4) && (i32 == val)) {
830  return 1;
831  }
832 
833  return 0;
834 }
835 
836 static int ByteTest04 (void)
837 {
838  uint32_t val = 0x01020304;
839  uint32_t i32 = 0xbfbfbfbf;
840  uint8_t bytes[4] = { 0x01, 0x02, 0x03, 0x04 };
841  int ret = ByteExtractUint32(&i32, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
842 
843  if ((ret == 4) && (i32 == val)) {
844  return 1;
845  }
846 
847  return 0;
848 }
849 
850 static int ByteTest05 (void)
851 {
852  uint64_t val = 0x0102030405060708ULL;
853  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
854  uint8_t bytes[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
855  int ret = ByteExtractUint64(&i64, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
856 
857  if ((ret == 8) && (i64 == val)) {
858  return 1;
859  }
860 
861  return 0;
862 }
863 
864 static int ByteTest06 (void)
865 {
866  uint64_t val = 0x0102030405060708ULL;
867  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
868  uint8_t bytes[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
869  int ret = ByteExtractUint64(&i64, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
870 
871  if ((ret == 8) && (i64 == val)) {
872  return 1;
873  }
874 
875  return 0;
876 }
877 
878 static int ByteTest07 (void)
879 {
880  const char *str = "1234567890";
881  uint64_t val = 1234567890;
882  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
883  int ret = ByteExtractStringUint64(&i64, 10, strlen(str), str);
884 
885  if ((ret == 10) && (i64 == val)) {
886  return 1;
887  }
888 
889  return 0;
890 }
891 
892 static int ByteTest08 (void)
893 {
894  const char *str = "1234567890";
895  uint32_t val = 1234567890;
896  uint32_t i32 = 0xbfbfbfbf;
897  int ret = ByteExtractStringUint32(&i32, 10, strlen(str), str);
898 
899  if ((ret == 10) && (i32 == val)) {
900  return 1;
901  }
902 
903  return 0;
904 }
905 
906 static int ByteTest09 (void)
907 {
908  const char *str = "12345";
909  uint16_t val = 12345;
910  uint16_t i16 = 0xbfbf;
911  int ret = ByteExtractStringUint16(&i16, 10, strlen(str), str);
912 
913  if ((ret == 5) && (i16 == val)) {
914  return 1;
915  }
916 
917  return 0;
918 }
919 
920 static int ByteTest10 (void)
921 {
922  const char *str = "123";
923  uint8_t val = 123;
924  uint8_t i8 = 0xbf;
925  int ret = ByteExtractStringUint8(&i8, 10, strlen(str), str);
926 
927  if ((ret == 3) && (i8 == val)) {
928  return 1;
929  }
930 
931  return 0;
932 }
933 
934 static int ByteTest11 (void)
935 {
936  const char *str = "-1234567890";
937  int64_t val = -1234567890;
938  int64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
939  int ret = ByteExtractStringInt64(&i64, 10, strlen(str), str);
940 
941  if ((ret == 11) && (i64 == val)) {
942  return 1;
943  }
944 
945  return 0;
946 }
947 
948 static int ByteTest12 (void)
949 {
950  const char *str = "-1234567890";
951  int32_t val = -1234567890;
952  int32_t i32 = 0xbfbfbfbf;
953  int ret = ByteExtractStringInt32(&i32, 10, strlen(str), str);
954 
955  if ((ret == 11) && (i32 == val)) {
956  return 1;
957  }
958 
959  return 0;
960 }
961 
962 static int ByteTest13 (void)
963 {
964  const char *str = "-12345";
965  int16_t val = -12345;
966  int16_t i16 = 0xbfbf;
967  int ret = ByteExtractStringInt16(&i16, 10, strlen(str), str);
968 
969  if ((ret == 6) && (i16 == val)) {
970  return 1;
971  }
972 
973  return 0;
974 }
975 
976 static int ByteTest14 (void)
977 {
978  const char *str = "-123";
979  int8_t val = -123;
980  int8_t i8 = 0xbf;
981  int ret = ByteExtractStringInt8(&i8, 10, strlen(str), str);
982 
983  if ((ret == 4) && (i8 == val)) {
984  return 1;
985  }
986 
987  return 0;
988 }
989 
990 /** \test max u32 value */
991 static int ByteTest15 (void)
992 {
993  const char *str = "4294967295";
994  uint32_t val = 4294967295UL;
995  uint32_t u32 = 0xffffffff;
996 
997  int ret = ByteExtractStringUint32(&u32, 10, strlen(str), str);
998  if ((ret == 10) && (u32 == val)) {
999  return 1;
1000  }
1001 
1002  return 0;
1003 }
1004 
1005 /** \test max u32 value + 1 */
1006 static int ByteTest16 (void)
1007 {
1008  const char *str = "4294967296";
1009  uint32_t u32 = 0;
1010 
1011  int ret = ByteExtractStringUint32(&u32, 10, strlen(str), str);
1012  if (ret != 0) {
1013  return 1;
1014  }
1015 
1016  return 0;
1017 }
1018 
1020 {
1021  UtRegisterTest("ByteTest01", ByteTest01);
1022  UtRegisterTest("ByteTest02", ByteTest02);
1023  UtRegisterTest("ByteTest03", ByteTest03);
1024  UtRegisterTest("ByteTest04", ByteTest04);
1025  UtRegisterTest("ByteTest05", ByteTest05);
1026  UtRegisterTest("ByteTest06", ByteTest06);
1027  UtRegisterTest("ByteTest07", ByteTest07);
1028  UtRegisterTest("ByteTest08", ByteTest08);
1029  UtRegisterTest("ByteTest09", ByteTest09);
1030  UtRegisterTest("ByteTest10", ByteTest10);
1031  UtRegisterTest("ByteTest11", ByteTest11);
1032  UtRegisterTest("ByteTest12", ByteTest12);
1033  UtRegisterTest("ByteTest13", ByteTest13);
1034  UtRegisterTest("ByteTest14", ByteTest14);
1035  UtRegisterTest("ByteTest15", ByteTest15);
1036  UtRegisterTest("ByteTest16", ByteTest16);
1037 }
1038 #endif /* UNITTESTS */
1039 
util-byte.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
StringParseUint16
int StringParseUint16(uint16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:336
StringParseInt8
int StringParseInt8(int8_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:661
ByteExtractUint64
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:122
BytesToString
char * BytesToString(const uint8_t *bytes, size_t nbytes)
Turn byte array into string.
Definition: util-byte.c:41
ByteExtractUint16
int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:164
ByteExtractString
int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str, bool strict)
Definition: util-byte.c:185
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
ByteExtractStringInt16
int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:560
StringParseInt32
int StringParseInt32(int32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:613
ByteExtractStringInt32
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:536
util-unittest.h
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
ByteRegisterTests
void ByteRegisterTests(void)
Definition: util-byte.c:1019
util-debug.h
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, uint16_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:457
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
StringParseU32RangeCheck
int StringParseU32RangeCheck(uint32_t *res, int base, uint16_t len, const char *str, uint32_t min, uint32_t max)
Definition: util-byte.c:401
ByteExtractUint32
int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:143
BYTE_BIG_ENDIAN
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
StringParseInt16
int StringParseInt16(int16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:637
ByteExtractStringInt64
int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:531
StringParseUint64
int StringParseUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:308
ByteExtractStringUint32
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:239
ByteExtractStringSigned
int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str, bool strict)
Definition: util-byte.c:485
StringParseU64RangeCheck
int StringParseU64RangeCheck(uint64_t *res, int base, uint16_t len, const char *str, uint64_t min, uint64_t max)
Definition: util-byte.c:382
StringParseInt64
int StringParseInt64(int64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:608
StringParseUint32
int StringParseUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:313
BYTE_LITTLE_ENDIAN
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
suricata-common.h
ByteExtractStringInt8
int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:584
StringParseI16RangeCheck
int StringParseI16RangeCheck(int16_t *res, int base, uint16_t len, const char *str, int16_t min, int16_t max)
Definition: util-byte.c:733
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
util-validate.h
ByteExtractStringUint8
int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:285
str
#define str(s)
Definition: suricata-common.h:273
SC_ERR_NUMERIC_VALUE_ERANGE
@ SC_ERR_NUMERIC_VALUE_ERANGE
Definition: util-error.h:91
BytesToStringBuffer
void BytesToStringBuffer(const uint8_t *bytes, size_t nbytes, char *outstr, size_t outlen)
Turn byte array into string.
Definition: util-byte.c:85
StringParseI8RangeCheck
int StringParseI8RangeCheck(int8_t *res, int base, uint16_t len, const char *str, int8_t min, int8_t max)
Definition: util-byte.c:762
StringParseUint8
int StringParseUint8(uint8_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:359
StringParseU16RangeCheck
int StringParseU16RangeCheck(uint16_t *res, int base, uint16_t len, const char *str, uint16_t min, uint16_t max)
Definition: util-byte.c:429
ByteExtractStringUint64
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:234
ByteExtractStringUint16
int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:262
SC_ERR_ARG_LEN_LONG
@ SC_ERR_ARG_LEN_LONG
Definition: util-error.h:93
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SC_ERR_INVALID_NUMERIC_VALUE
@ SC_ERR_INVALID_NUMERIC_VALUE
Definition: util-error.h:90
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
StringParseI32RangeCheck
int StringParseI32RangeCheck(int32_t *res, int base, uint16_t len, const char *str, int32_t min, int32_t max)
Definition: util-byte.c:704
StringParseI64RangeCheck
int StringParseI64RangeCheck(int64_t *res, int base, uint16_t len, const char *str, int64_t min, int64_t max)
Definition: util-byte.c:685