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 (int)(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 (int)(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 int 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 
839 static 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 
853 static 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 
867 static 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 
881 static 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 
895 static 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 
909 static 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 
923 static 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 
937 static 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 
951 static 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 
965 static 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 
979 static 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 
993 static 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 
1007 static 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 
1021 static 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 */
1036 static 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 */
1051 static 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 
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:275
HexToRaw
int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
Definition: util-byte.c:806
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:1064
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:308
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:267
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:102