4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 2001 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <ftypes-int.h>
31 #include <epan/addr_resolv.h>
32 #include <epan/strutil.h>
33 #include <epan/oids.h>
38 #define CMP_MATCHES cmp_matches
41 bytes_fvalue_new(fvalue_t *fv)
43 fv->value.bytes = NULL;
47 bytes_fvalue_free(fvalue_t *fv)
49 if (fv->value.bytes) {
50 g_byte_array_free(fv->value.bytes, TRUE);
57 bytes_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
59 g_assert(already_copied);
61 /* Free up the old value, if we have one */
62 bytes_fvalue_free(fv);
64 fv->value.bytes = value;
68 bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
70 if (fv->value.bytes->len == 0) {
71 /* Empty array of bytes, so the representation
72 * is an empty string. */
75 /* 3 bytes for each byte of the byte "NN:" minus 1 byte
76 * as there's no trailing ":". */
77 return fv->value.bytes->len * 3 - 1;
84 * 5 for the first byte ([0-2].[0-39].)
85 * for each extra byte if the sub-id is:
86 * 1 byte it can be at most "127." (4 bytes we give it 4)
87 * 2 bytes it can be at most "16383." (6 bytes we give it 8)
88 * 3 bytes it can be at most "2097151." (8 bytes we give it 12)
89 * 4 bytes it can be at most "268435456." (10 bytes we give it 16)
90 * 5 bytes it can be at most "34359738368." (12 bytes we give it 20)
92 * a 5 bytes encoded subid can already overflow the guint32 that holds a sub-id,
93 * making it a completely different issue!
95 #define OID_REPR_LEN(fv) (5 + (4 * ((fv)->value.bytes->len-1)))
98 oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
100 return OID_REPR_LEN(fv);
104 oid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
106 const char* oid_str = oid_encoded2string(fv->value.bytes->data,fv->value.bytes->len);
109 * I'm assuming that oid_repr_len is going to be called before to set buf's size.
110 * or else we might have a BO.
111 * I guess that is why this callback is not passed a length.
114 strncpy(buf,oid_str,OID_REPR_LEN(fv));
118 bytes_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
124 c = fv->value.bytes->data;
127 for (i = 0; i < fv->value.bytes->len; i++) {
129 sprintf(write_cursor, "%02x", *c++);
133 sprintf(write_cursor, ":%02x", *c++);
140 common_fvalue_set(fvalue_t *fv, guint8* data, guint len)
142 /* Free up the old value, if we have one */
143 bytes_fvalue_free(fv);
145 fv->value.bytes = g_byte_array_new();
146 g_byte_array_append(fv->value.bytes, data, len);
150 ether_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
152 g_assert(!already_copied);
153 common_fvalue_set(fv, value, FT_ETHER_LEN);
157 ipv6_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
159 g_assert(!already_copied);
160 common_fvalue_set(fv, value, FT_IPv6_LEN);
164 oid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
166 g_assert(already_copied);
168 /* Free up the old value, if we have one */
169 bytes_fvalue_free(fv);
171 fv->value.bytes = value;
176 value_get(fvalue_t *fv)
178 return fv->value.bytes->data;
182 bytes_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
186 bytes = g_byte_array_new();
188 g_byte_array_append(bytes, (guint8 *)s, (guint)strlen(s));
190 /* Free up the old value, if we have one */
191 bytes_fvalue_free(fv);
192 fv->value.bytes = bytes;
198 bytes_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
203 bytes = g_byte_array_new();
205 res = hex_str_to_bytes(s, bytes, TRUE);
209 logfunc("\"%s\" is not a valid byte string.", s);
210 g_byte_array_free(bytes, TRUE);
214 /* Free up the old value, if we have one */
215 bytes_fvalue_free(fv);
217 fv->value.bytes = bytes;
223 ether_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
228 * Don't log a message if this fails; we'll try looking it
229 * up as an Ethernet host name if it does, and if that fails,
230 * we'll log a message.
232 if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
233 if (fv->value.bytes->len > FT_ETHER_LEN) {
234 logfunc("\"%s\" contains too many bytes to be a valid Ethernet address.",
238 else if (fv->value.bytes->len < FT_ETHER_LEN && !allow_partial_value) {
239 logfunc("\"%s\" contains too few bytes to be a valid Ethernet address.",
247 mac = get_ether_addr(s);
249 logfunc("\"%s\" is not a valid hostname or Ethernet address.",
254 ether_fvalue_set(fv, mac, FALSE);
259 ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
263 if (!get_host_ipaddr6(s, (struct e_in6_addr*)buffer)) {
264 logfunc("\"%s\" is not a valid hostname or IPv6 address.", s);
268 ipv6_fvalue_set(fv, buffer, FALSE);
273 ipv6_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
276 * 39 characters for "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX".
282 ipv6_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
284 ip6_to_str_buf((struct e_in6_addr *)fv->value.bytes->data, buf);
288 oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
295 * Don't log a message if this fails; we'll try looking it
296 * up as an OID if it does, and if that fails,
297 * we'll log a message.
299 /* do not try it as '.' is handled as valid separator for hexbytes :(
300 if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
305 bytes = g_byte_array_new();
306 res = oid_str_to_bytes(s, bytes);
309 logfunc("\"%s\" is not a valid OBJECT IDENTIFIER.", s);
310 g_byte_array_free(bytes, TRUE);
314 /* Free up the old value, if we have one */
315 bytes_fvalue_free(fv);
316 fv->value.bytes = bytes;
324 return fv->value.bytes->len;
328 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
332 data = fv->value.bytes->data + offset;
334 g_byte_array_append(bytes, data, length);
339 cmp_eq(fvalue_t *fv_a, fvalue_t *fv_b)
341 GByteArray *a = fv_a->value.bytes;
342 GByteArray *b = fv_b->value.bytes;
344 if (a->len != b->len) {
348 return (memcmp(a->data, b->data, a->len) == 0);
353 cmp_ne(fvalue_t *fv_a, fvalue_t *fv_b)
355 GByteArray *a = fv_a->value.bytes;
356 GByteArray *b = fv_b->value.bytes;
358 if (a->len != b->len) {
362 return (memcmp(a->data, b->data, a->len) != 0);
367 cmp_gt(fvalue_t *fv_a, fvalue_t *fv_b)
369 GByteArray *a = fv_a->value.bytes;
370 GByteArray *b = fv_b->value.bytes;
372 if (a->len > b->len) {
376 if (a->len < b->len) {
380 return (memcmp(a->data, b->data, a->len) > 0);
384 cmp_ge(fvalue_t *fv_a, fvalue_t *fv_b)
386 GByteArray *a = fv_a->value.bytes;
387 GByteArray *b = fv_b->value.bytes;
389 if (a->len > b->len) {
393 if (a->len < b->len) {
397 return (memcmp(a->data, b->data, a->len) >= 0);
401 cmp_lt(fvalue_t *fv_a, fvalue_t *fv_b)
403 GByteArray *a = fv_a->value.bytes;
404 GByteArray *b = fv_b->value.bytes;
406 if (a->len < b->len) {
410 if (a->len > b->len) {
414 return (memcmp(a->data, b->data, a->len) < 0);
418 cmp_le(fvalue_t *fv_a, fvalue_t *fv_b)
420 GByteArray *a = fv_a->value.bytes;
421 GByteArray *b = fv_b->value.bytes;
423 if (a->len < b->len) {
427 if (a->len > b->len) {
431 return (memcmp(a->data, b->data, a->len) <= 0);
435 cmp_bitwise_and(fvalue_t *fv_a, fvalue_t *fv_b)
437 GByteArray *a = fv_a->value.bytes;
438 GByteArray *b = fv_b->value.bytes;
440 unsigned char *p_a, *p_b;
442 if (b->len != a->len) {
457 cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
459 GByteArray *a = fv_a->value.bytes;
460 GByteArray *b = fv_b->value.bytes;
462 if (epan_memmem(a->data, a->len, b->data, b->len)) {
472 cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
474 GByteArray *a = fv_a->value.bytes;
475 pcre_tuple_t *pcre_t = fv_b->value.re;
479 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
480 * warned us. For the same reason (and because we're using g_malloc()),
481 * fv_b->value.re is not NULL.
483 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
490 pcre_t->re, /* Compiled PCRE */
491 pcre_t->ex, /* PCRE extra from pcre_study() */
492 a->data, /* The data to check for the pattern... */
493 (int)a->len, /* ... and its length */
494 0, /* Start offset within data */
495 options, /* PCRE options */
496 NULL, /* We are not interested in the matched string */
497 0 /* of the pattern; only in success or failure. */
499 /* NOTE - DO NOT g_free(data) */
507 cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
509 GByteArray *a = fv_a->value.bytes;
510 GRegex *regex = fv_b->value.re;
512 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
513 * warned us. For the same reason (and because we're using g_malloc()),
514 * fv_b->value.re is not NULL.
516 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
522 return g_regex_match_full(
523 regex, /* Compiled PCRE */
524 a->data, /* The data to check for the pattern... */
525 (int)a->len, /* ... and its length */
526 0, /* Start offset within data */
527 0, /* GRegexMatchFlags */
528 NULL, /* We are not interested in the match information */
529 NULL /* We don't want error information */
531 /* NOTE - DO NOT g_free(data) */
533 #endif /* HAVE_LIBPCRE / GRegex */
536 ftype_register_bytes(void)
539 static ftype_t bytes_type = {
540 FT_BYTES, /* ftype */
541 "FT_BYTES", /* name */
542 "sequence of bytes", /* pretty_name */
544 bytes_fvalue_new, /* new_value */
545 bytes_fvalue_free, /* free_value */
546 bytes_from_unparsed, /* val_from_unparsed */
547 bytes_from_string, /* val_from_string */
548 bytes_to_repr, /* val_to_string_repr */
549 bytes_repr_len, /* len_string_repr */
551 bytes_fvalue_set, /* set_value */
552 NULL, /* set_value_uinteger */
553 NULL, /* set_value_sinteger */
554 NULL, /* set_value_integer64 */
555 NULL, /* set_value_floating */
557 value_get, /* get_value */
558 NULL, /* get_value_uinteger */
559 NULL, /* get_value_sinteger */
560 NULL, /* get_value_integer64 */
561 NULL, /* get_value_floating */
577 static ftype_t uint_bytes_type = {
578 FT_UINT_BYTES, /* ftype */
579 "FT_UINT_BYTES", /* name */
580 "sequence of bytes", /* pretty_name */
582 bytes_fvalue_new, /* new_value */
583 bytes_fvalue_free, /* free_value */
584 bytes_from_unparsed, /* val_from_unparsed */
585 NULL, /* val_from_string */
586 bytes_to_repr, /* val_to_string_repr */
587 bytes_repr_len, /* len_string_repr */
589 bytes_fvalue_set, /* set_value */
590 NULL, /* set_value_uinteger */
591 NULL, /* set_value_sinteger */
592 NULL, /* set_value_integer64 */
593 NULL, /* set_value_floating */
595 value_get, /* get_value */
596 NULL, /* get_value_uinteger */
597 NULL, /* get_value_sinteger */
598 NULL, /* get_value_integer64 */
599 NULL, /* get_value_floating */
609 NULL, /* cmp_matches */
615 static ftype_t ether_type = {
616 FT_ETHER, /* ftype */
617 "FT_ETHER", /* name */
618 "Ethernet or other MAC address",/* pretty_name */
619 FT_ETHER_LEN, /* wire_size */
620 bytes_fvalue_new, /* new_value */
621 bytes_fvalue_free, /* free_value */
622 ether_from_unparsed, /* val_from_unparsed */
623 NULL, /* val_from_string */
624 bytes_to_repr, /* val_to_string_repr */
625 bytes_repr_len, /* len_string_repr */
627 ether_fvalue_set, /* set_value */
628 NULL, /* set_value_uinteger */
629 NULL, /* set_value_sinteger */
630 NULL, /* set_value_integer64 */
631 NULL, /* set_value_floating */
633 value_get, /* get_value */
634 NULL, /* get_value_uinteger */
635 NULL, /* get_value_sinteger */
636 NULL, /* get_value_integer64 */
637 NULL, /* get_value_floating */
653 static ftype_t ipv6_type = {
655 "FT_IPv6", /* name */
656 "IPv6 address", /* pretty_name */
657 FT_IPv6_LEN, /* wire_size */
658 bytes_fvalue_new, /* new_value */
659 bytes_fvalue_free, /* free_value */
660 ipv6_from_unparsed, /* val_from_unparsed */
661 NULL, /* val_from_string */
662 ipv6_to_repr, /* val_to_string_repr */
663 ipv6_repr_len, /* len_string_repr */
665 ipv6_fvalue_set, /* set_value */
666 NULL, /* set_value_uinteger */
667 NULL, /* set_value_sinteger */
668 NULL, /* set_value_integer64 */
669 NULL, /* set_value_floating */
671 value_get, /* get_value */
672 NULL, /* get_value_uinteger */
673 NULL, /* get_value_sinteger */
674 NULL, /* get_value_integer64 */
675 NULL, /* get_value_floating */
685 NULL, /* cmp_matches */
691 static ftype_t oid_type = {
694 "OBJECT IDENTIFIER", /* pretty_name */
696 bytes_fvalue_new, /* new_value */
697 bytes_fvalue_free, /* free_value */
698 oid_from_unparsed, /* val_from_unparsed */
699 NULL, /* val_from_string */
700 oid_to_repr, /* val_to_string_repr */
701 oid_repr_len, /* len_string_repr */
703 oid_fvalue_set, /* set_value */
704 NULL, /* set_value_uinteger */
705 NULL, /* set_value_sinteger */
706 NULL, /* set_value_integer64 */
707 NULL, /* set_value_floating */
709 value_get, /* get_value */
710 NULL, /* get_value_uinteger */
711 NULL, /* get_value_sinteger */
712 NULL, /* get_value_integer64 */
713 NULL, /* get_value_floating */
723 NULL, /* cmp_matches */
729 ftype_register(FT_BYTES, &bytes_type);
730 ftype_register(FT_UINT_BYTES, &uint_bytes_type);
731 ftype_register(FT_ETHER, ðer_type);
732 ftype_register(FT_IPv6, &ipv6_type);
733 ftype_register(FT_OID, &oid_type);