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, 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 (endptr - ptr);
232 }
233 
234 int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
235 {
236  return ByteExtractString(res, base, len, str, false);
237 }
238 
239 int 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 
262 int 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 
285 int 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 
308 int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
309 {
310  return ByteExtractString(res, base, len, str, true);
311 }
312 
313 int 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 
337 int 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 
361 int 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 
491 int 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 (endptr - ptr);
535 }
536 
537 int ByteExtractStringInt64(int64_t *res, int base, size_t len, const char *str)
538 {
539  return ByteExtractStringSigned(res, base, len, str, false);
540 }
541 
542 int 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 
567 int 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 
592 int 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 
617 int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
618 {
619  return ByteExtractStringSigned(res, base, len, str, true);
620 }
621 
622 int 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 
647 int 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 
672 int 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 
806 /* UNITTESTS */
807 #ifdef UNITTESTS
808 
809 static int ByteTest01 (void)
810 {
811  uint16_t val = 0x0102;
812  uint16_t i16 = 0xbfbf;
813  uint8_t bytes[2] = { 0x02, 0x01 };
814  int ret = ByteExtractUint16(&i16, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
815 
816  if ((ret == 2) && (i16 == val)) {
817  return 1;
818  }
819 
820  return 0;
821 }
822 
823 static int ByteTest02 (void)
824 {
825  uint16_t val = 0x0102;
826  uint16_t i16 = 0xbfbf;
827  uint8_t bytes[2] = { 0x01, 0x02 };
828  int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
829 
830  if ((ret == 2) && (i16 == val)) {
831  return 1;
832  }
833 
834  return 0;
835 }
836 
837 static int ByteTest03 (void)
838 {
839  uint32_t val = 0x01020304;
840  uint32_t i32 = 0xbfbfbfbf;
841  uint8_t bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
842  int ret = ByteExtractUint32(&i32, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
843 
844  if ((ret == 4) && (i32 == val)) {
845  return 1;
846  }
847 
848  return 0;
849 }
850 
851 static int ByteTest04 (void)
852 {
853  uint32_t val = 0x01020304;
854  uint32_t i32 = 0xbfbfbfbf;
855  uint8_t bytes[4] = { 0x01, 0x02, 0x03, 0x04 };
856  int ret = ByteExtractUint32(&i32, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
857 
858  if ((ret == 4) && (i32 == val)) {
859  return 1;
860  }
861 
862  return 0;
863 }
864 
865 static int ByteTest05 (void)
866 {
867  uint64_t val = 0x0102030405060708ULL;
868  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
869  uint8_t bytes[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
870  int ret = ByteExtractUint64(&i64, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
871 
872  if ((ret == 8) && (i64 == val)) {
873  return 1;
874  }
875 
876  return 0;
877 }
878 
879 static int ByteTest06 (void)
880 {
881  uint64_t val = 0x0102030405060708ULL;
882  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
883  uint8_t bytes[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
884  int ret = ByteExtractUint64(&i64, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
885 
886  if ((ret == 8) && (i64 == val)) {
887  return 1;
888  }
889 
890  return 0;
891 }
892 
893 static int ByteTest07 (void)
894 {
895  const char str[] = "1234567890";
896  uint64_t val = 1234567890;
897  uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
898  int ret = ByteExtractStringUint64(&i64, 10, sizeof(str) - 1, str);
899 
900  if ((ret == 10) && (i64 == val)) {
901  return 1;
902  }
903 
904  return 0;
905 }
906 
907 static int ByteTest08 (void)
908 {
909  const char str[] = "1234567890";
910  uint32_t val = 1234567890;
911  uint32_t i32 = 0xbfbfbfbf;
912  int ret = ByteExtractStringUint32(&i32, 10, sizeof(str) - 1, str);
913 
914  if ((ret == 10) && (i32 == val)) {
915  return 1;
916  }
917 
918  return 0;
919 }
920 
921 static int ByteTest09 (void)
922 {
923  const char str[] = "12345";
924  uint16_t val = 12345;
925  uint16_t i16 = 0xbfbf;
926  int ret = ByteExtractStringUint16(&i16, 10, sizeof(str) - 1, str);
927 
928  if ((ret == 5) && (i16 == val)) {
929  return 1;
930  }
931 
932  return 0;
933 }
934 
935 static int ByteTest10 (void)
936 {
937  const char str[] = "123";
938  uint8_t val = 123;
939  uint8_t i8 = 0xbf;
940  int ret = ByteExtractStringUint8(&i8, 10, sizeof(str) - 1, str);
941 
942  if ((ret == 3) && (i8 == val)) {
943  return 1;
944  }
945 
946  return 0;
947 }
948 
949 static int ByteTest11 (void)
950 {
951  const char str[] = "-1234567890";
952  int64_t val = -1234567890;
953  int64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
954  int ret = ByteExtractStringInt64(&i64, 10, sizeof(str) - 1, str);
955 
956  if ((ret == 11) && (i64 == val)) {
957  return 1;
958  }
959 
960  return 0;
961 }
962 
963 static int ByteTest12 (void)
964 {
965  const char str[] = "-1234567890";
966  int32_t val = -1234567890;
967  int32_t i32 = 0xbfbfbfbf;
968  int ret = ByteExtractStringInt32(&i32, 10, sizeof(str) - 1, str);
969 
970  if ((ret == 11) && (i32 == val)) {
971  return 1;
972  }
973 
974  return 0;
975 }
976 
977 static int ByteTest13 (void)
978 {
979  const char str[] = "-12345";
980  int16_t val = -12345;
981  int16_t i16 = 0xbfbf;
982  int ret = ByteExtractStringInt16(&i16, 10, sizeof(str) - 1, str);
983 
984  if ((ret == 6) && (i16 == val)) {
985  return 1;
986  }
987 
988  return 0;
989 }
990 
991 static int ByteTest14 (void)
992 {
993  const char str[] = "-123";
994  int8_t val = -123;
995  int8_t i8 = 0xbf;
996  int ret = ByteExtractStringInt8(&i8, 10, sizeof(str) - 1, str);
997 
998  if ((ret == 4) && (i8 == val)) {
999  return 1;
1000  }
1001 
1002  return 0;
1003 }
1004 
1005 /** \test max u32 value */
1006 static int ByteTest15 (void)
1007 {
1008  const char str[] = "4294967295";
1009  uint32_t val = 4294967295UL;
1010  uint32_t u32 = 0xffffffff;
1011 
1012  int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1013  if ((ret == 10) && (u32 == val)) {
1014  return 1;
1015  }
1016 
1017  return 0;
1018 }
1019 
1020 /** \test max u32 value + 1 */
1021 static int ByteTest16 (void)
1022 {
1023  const char str[] = "4294967296";
1024  uint32_t u32 = 0;
1025 
1026  int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1027  if (ret != 0) {
1028  return 1;
1029  }
1030 
1031  return 0;
1032 }
1033 
1035 {
1036  UtRegisterTest("ByteTest01", ByteTest01);
1037  UtRegisterTest("ByteTest02", ByteTest02);
1038  UtRegisterTest("ByteTest03", ByteTest03);
1039  UtRegisterTest("ByteTest04", ByteTest04);
1040  UtRegisterTest("ByteTest05", ByteTest05);
1041  UtRegisterTest("ByteTest06", ByteTest06);
1042  UtRegisterTest("ByteTest07", ByteTest07);
1043  UtRegisterTest("ByteTest08", ByteTest08);
1044  UtRegisterTest("ByteTest09", ByteTest09);
1045  UtRegisterTest("ByteTest10", ByteTest10);
1046  UtRegisterTest("ByteTest11", ByteTest11);
1047  UtRegisterTest("ByteTest12", ByteTest12);
1048  UtRegisterTest("ByteTest13", ByteTest13);
1049  UtRegisterTest("ByteTest14", ByteTest14);
1050  UtRegisterTest("ByteTest15", ByteTest15);
1051  UtRegisterTest("ByteTest16", ByteTest16);
1052 }
1053 #endif /* UNITTESTS */
1054 
util-byte.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
StringParseI64RangeCheck
int StringParseI64RangeCheck(int64_t *res, int base, size_t len, const char *str, int64_t min, int64_t max)
Definition: util-byte.c:697
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
ByteExtractStringInt8
int ByteExtractStringInt8(int8_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:592
ByteExtractStringInt16
int ByteExtractStringInt16(int16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:567
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ByteExtractStringUint16
int ByteExtractStringUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:262
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
StringParseI8RangeCheck
int StringParseI8RangeCheck(int8_t *res, int base, size_t len, const char *str, int8_t min, int8_t max)
Definition: util-byte.c:776
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:337
ByteExtractStringInt64
int ByteExtractStringInt64(int64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:537
ByteExtractStringUint32
int ByteExtractStringUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:239
StringParseInt32
int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:622
ByteExtractStringUint64
int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:234
util-unittest.h
StringParseU32RangeCheck
int StringParseU32RangeCheck(uint32_t *res, int base, size_t len, const char *str, uint32_t min, uint32_t max)
Definition: util-byte.c:404
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
StringParseI16RangeCheck
int StringParseI16RangeCheck(int16_t *res, int base, size_t len, const char *str, int16_t min, int16_t max)
Definition: util-byte.c:746
StringParseUint8
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:361
ByteRegisterTests
void ByteRegisterTests(void)
Definition: util-byte.c:1034
util-debug.h
StringParseI32RangeCheck
int StringParseI32RangeCheck(int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
Definition: util-byte.c:716
ByteExtractStringInt32
int ByteExtractStringInt32(int32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:542
ByteExtractUint32
int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:143
StringParseU16RangeCheck
int StringParseU16RangeCheck(uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
Definition: util-byte.c:433
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
BYTE_BIG_ENDIAN
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
StringParseInt64
int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:617
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:462
ByteExtractStringUint8
int ByteExtractStringUint8(uint8_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:285
BYTE_LITTLE_ENDIAN
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
StringParseUint64
int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:308
StringParseU64RangeCheck
int StringParseU64RangeCheck(uint64_t *res, int base, size_t len, const char *str, uint64_t min, uint64_t max)
Definition: util-byte.c:385
suricata-common.h
ByteExtractString
int ByteExtractString(uint64_t *res, int base, size_t len, const char *str, bool strict)
Definition: util-byte.c:185
StringParseInt16
int StringParseInt16(int16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:647
util-validate.h
str
#define str(s)
Definition: suricata-common.h:291
ByteExtractStringSigned
int ByteExtractStringSigned(int64_t *res, int base, size_t len, const char *str, bool strict)
Definition: util-byte.c:491
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
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
StringParseInt8
int StringParseInt8(int8_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:672
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103