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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <ftypes-int.h>
29 #include <epan/addr_resolv.h>
30 #include <epan/strutil.h>
31 #include <epan/oids.h>
33 #define CMP_MATCHES cmp_matches
36 bytes_fvalue_new(fvalue_t *fv)
38 fv->value.bytes = NULL;
42 bytes_fvalue_free(fvalue_t *fv)
44 if (fv->value.bytes) {
45 g_byte_array_free(fv->value.bytes, TRUE);
52 bytes_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
54 g_assert(already_copied);
56 /* Free up the old value, if we have one */
57 bytes_fvalue_free(fv);
59 fv->value.bytes = (GByteArray *)value;
63 bytes_repr_len(fvalue_t *fv, ftrepr_t rtype _U_)
65 if (fv->value.bytes->len == 0) {
66 /* Empty array of bytes, so the representation
67 * is an empty string. */
70 /* 3 bytes for each byte of the byte "NN:" minus 1 byte
71 * as there's no trailing ":". */
72 return fv->value.bytes->len * 3 - 1;
79 * 5 for the first byte ([0-2].[0-39].)
80 * for each extra byte if the sub-id is:
81 * 1 byte it can be at most "127." (4 bytes we give it 4)
82 * 2 bytes it can be at most "16383." (6 bytes we give it 8)
83 * 3 bytes it can be at most "2097151." (8 bytes we give it 12)
84 * 4 bytes it can be at most "268435456." (10 bytes we give it 16)
85 * 5 bytes it can be at most "34359738368." (12 bytes we give it 20)
87 * a 5 bytes encoded subid can already overflow the guint32 that holds a sub-id,
88 * making it a completely different issue!
90 #define OID_REPR_LEN(fv) (5 + (4 * ((fv)->value.bytes->len-1)))
93 oid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
95 return OID_REPR_LEN(fv);
99 oid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
101 const char* oid_str = oid_encoded2string(fv->value.bytes->data,fv->value.bytes->len);
104 * I'm assuming that oid_repr_len is going to be called before to set buf's size.
105 * or else we might have a BO.
106 * I guess that is why this callback is not passed a length.
109 strncpy(buf,oid_str,OID_REPR_LEN(fv));
113 bytes_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
119 c = fv->value.bytes->data;
122 for (i = 0; i < fv->value.bytes->len; i++) {
124 sprintf(write_cursor, "%02x", *c++);
128 sprintf(write_cursor, ":%02x", *c++);
135 common_fvalue_set(fvalue_t *fv, guint8* data, guint len)
137 /* Free up the old value, if we have one */
138 bytes_fvalue_free(fv);
140 fv->value.bytes = g_byte_array_new();
141 g_byte_array_append(fv->value.bytes, data, len);
145 ax25_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
147 g_assert(!already_copied);
148 common_fvalue_set(fv, value, FT_AX25_ADDR_LEN);
152 ether_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
154 g_assert(!already_copied);
155 common_fvalue_set(fv, (guint8*)value, FT_ETHER_LEN);
159 oid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
161 g_assert(already_copied);
163 /* Free up the old value, if we have one */
164 bytes_fvalue_free(fv);
166 fv->value.bytes = (GByteArray *)value;
171 value_get(fvalue_t *fv)
173 return fv->value.bytes->data;
177 bytes_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
181 bytes = g_byte_array_new();
183 g_byte_array_append(bytes, (guint8 *)s, (guint)strlen(s));
185 /* Free up the old value, if we have one */
186 bytes_fvalue_free(fv);
187 fv->value.bytes = bytes;
193 bytes_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
198 bytes = g_byte_array_new();
200 res = hex_str_to_bytes(s, bytes, TRUE);
204 logfunc("\"%s\" is not a valid byte string.", s);
205 g_byte_array_free(bytes, TRUE);
209 /* Free up the old value, if we have one */
210 bytes_fvalue_free(fv);
212 fv->value.bytes = bytes;
218 ax25_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
223 * Don't log a message if this fails; we'll try looking it
224 * up as another way if it does, and if that fails,
225 * we'll log a message.
227 if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
228 if (fv->value.bytes->len > FT_AX25_ADDR_LEN) {
229 logfunc("\"%s\" contains too many bytes to be a valid AX.25 address.",
233 else if (fv->value.bytes->len < FT_AX25_ADDR_LEN && !allow_partial_value) {
234 logfunc("\"%s\" contains too few bytes to be a valid AX.25 address.",
242 mac = get_ax25_name(s);
244 logfunc("\"%s\" is not a valid AX.25 address.",
249 ax25_fvalue_set(fv, mac, FALSE);
254 ether_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
259 * Don't log a message if this fails; we'll try looking it
260 * up as an Ethernet host name if it does, and if that fails,
261 * we'll log a message.
263 if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
264 if (fv->value.bytes->len > FT_ETHER_LEN) {
265 logfunc("\"%s\" contains too many bytes to be a valid Ethernet address.",
269 else if (fv->value.bytes->len < FT_ETHER_LEN && !allow_partial_value) {
270 logfunc("\"%s\" contains too few bytes to be a valid Ethernet address.",
278 mac = get_ether_addr(s);
280 logfunc("\"%s\" is not a valid hostname or Ethernet address.",
285 ether_fvalue_set(fv, mac, FALSE);
290 oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
297 * Don't log a message if this fails; we'll try looking it
298 * up as an OID if it does, and if that fails,
299 * we'll log a message.
301 /* do not try it as '.' is handled as valid separator for hexbytes :(
302 if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
307 bytes = g_byte_array_new();
308 res = oid_str_to_bytes(s, bytes);
311 logfunc("\"%s\" is not a valid OBJECT IDENTIFIER.", s);
312 g_byte_array_free(bytes, TRUE);
316 /* Free up the old value, if we have one */
317 bytes_fvalue_free(fv);
318 fv->value.bytes = bytes;
326 return fv->value.bytes->len;
330 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
334 data = fv->value.bytes->data + offset;
336 g_byte_array_append(bytes, data, length);
341 cmp_eq(fvalue_t *fv_a, fvalue_t *fv_b)
343 GByteArray *a = fv_a->value.bytes;
344 GByteArray *b = fv_b->value.bytes;
346 if (a->len != b->len) {
350 return (memcmp(a->data, b->data, a->len) == 0);
355 cmp_ne(fvalue_t *fv_a, fvalue_t *fv_b)
357 GByteArray *a = fv_a->value.bytes;
358 GByteArray *b = fv_b->value.bytes;
360 if (a->len != b->len) {
364 return (memcmp(a->data, b->data, a->len) != 0);
369 cmp_gt(fvalue_t *fv_a, fvalue_t *fv_b)
371 GByteArray *a = fv_a->value.bytes;
372 GByteArray *b = fv_b->value.bytes;
374 if (a->len > b->len) {
378 if (a->len < b->len) {
382 return (memcmp(a->data, b->data, a->len) > 0);
386 cmp_ge(fvalue_t *fv_a, fvalue_t *fv_b)
388 GByteArray *a = fv_a->value.bytes;
389 GByteArray *b = fv_b->value.bytes;
391 if (a->len > b->len) {
395 if (a->len < b->len) {
399 return (memcmp(a->data, b->data, a->len) >= 0);
403 cmp_lt(fvalue_t *fv_a, fvalue_t *fv_b)
405 GByteArray *a = fv_a->value.bytes;
406 GByteArray *b = fv_b->value.bytes;
408 if (a->len < b->len) {
412 if (a->len > b->len) {
416 return (memcmp(a->data, b->data, a->len) < 0);
420 cmp_le(fvalue_t *fv_a, fvalue_t *fv_b)
422 GByteArray *a = fv_a->value.bytes;
423 GByteArray *b = fv_b->value.bytes;
425 if (a->len < b->len) {
429 if (a->len > b->len) {
433 return (memcmp(a->data, b->data, a->len) <= 0);
437 cmp_bitwise_and(fvalue_t *fv_a, fvalue_t *fv_b)
439 GByteArray *a = fv_a->value.bytes;
440 GByteArray *b = fv_b->value.bytes;
442 unsigned char *p_a, *p_b;
444 if (b->len != a->len) {
459 cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
461 GByteArray *a = fv_a->value.bytes;
462 GByteArray *b = fv_b->value.bytes;
464 if (epan_memmem(a->data, a->len, b->data, b->len)) {
473 cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
475 GByteArray *a = fv_a->value.bytes;
476 GRegex *regex = fv_b->value.re;
478 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
479 * warned us. For the same reason (and because we're using g_malloc()),
480 * fv_b->value.re is not NULL.
482 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
488 return g_regex_match_full(
489 regex, /* Compiled PCRE */
490 a->data, /* The data to check for the pattern... */
491 (int)a->len, /* ... and its length */
492 0, /* Start offset within data */
493 0, /* GRegexMatchFlags */
494 NULL, /* We are not interested in the match information */
495 NULL /* We don't want error information */
497 /* NOTE - DO NOT g_free(data) */
501 ftype_register_bytes(void)
504 static ftype_t bytes_type = {
505 FT_BYTES, /* ftype */
506 "FT_BYTES", /* name */
507 "Sequence of bytes", /* pretty_name */
509 bytes_fvalue_new, /* new_value */
510 bytes_fvalue_free, /* free_value */
511 bytes_from_unparsed, /* val_from_unparsed */
512 bytes_from_string, /* val_from_string */
513 bytes_to_repr, /* val_to_string_repr */
514 bytes_repr_len, /* len_string_repr */
516 bytes_fvalue_set, /* set_value */
517 NULL, /* set_value_uinteger */
518 NULL, /* set_value_sinteger */
519 NULL, /* set_value_integer64 */
520 NULL, /* set_value_floating */
522 value_get, /* get_value */
523 NULL, /* get_value_uinteger */
524 NULL, /* get_value_sinteger */
525 NULL, /* get_value_integer64 */
526 NULL, /* get_value_floating */
542 static ftype_t uint_bytes_type = {
543 FT_UINT_BYTES, /* ftype */
544 "FT_UINT_BYTES", /* name */
545 "Sequence of bytes", /* pretty_name */
547 bytes_fvalue_new, /* new_value */
548 bytes_fvalue_free, /* free_value */
549 bytes_from_unparsed, /* val_from_unparsed */
550 NULL, /* val_from_string */
551 bytes_to_repr, /* val_to_string_repr */
552 bytes_repr_len, /* len_string_repr */
554 bytes_fvalue_set, /* set_value */
555 NULL, /* set_value_uinteger */
556 NULL, /* set_value_sinteger */
557 NULL, /* set_value_integer64 */
558 NULL, /* set_value_floating */
560 value_get, /* get_value */
561 NULL, /* get_value_uinteger */
562 NULL, /* get_value_sinteger */
563 NULL, /* get_value_integer64 */
564 NULL, /* get_value_floating */
574 NULL, /* cmp_matches */
580 static ftype_t ax25_type = {
582 "FT_AX25", /* name */
583 "AX.25 address", /* pretty_name */
584 FT_AX25_ADDR_LEN, /* wire_size */
585 bytes_fvalue_new, /* new_value */
586 bytes_fvalue_free, /* free_value */
587 ax25_from_unparsed, /* val_from_unparsed */
588 NULL, /* val_from_string */
589 bytes_to_repr, /* val_to_string_repr */
590 bytes_repr_len, /* len_string_repr */
592 ax25_fvalue_set, /* set_value */
593 NULL, /* set_value_uinteger */
594 NULL, /* set_value_integer */
595 NULL, /* set_value_integer64 */
596 NULL, /* set_value_floating */
598 value_get, /* get_value */
599 NULL, /* set_value_uinteger */
600 NULL, /* get_value_integer */
601 NULL, /* get_value_integer64 */
602 NULL, /* get_value_floating */
618 static ftype_t ether_type = {
619 FT_ETHER, /* ftype */
620 "FT_ETHER", /* name */
621 "Ethernet or other MAC address",/* pretty_name */
622 FT_ETHER_LEN, /* wire_size */
623 bytes_fvalue_new, /* new_value */
624 bytes_fvalue_free, /* free_value */
625 ether_from_unparsed, /* val_from_unparsed */
626 NULL, /* val_from_string */
627 bytes_to_repr, /* val_to_string_repr */
628 bytes_repr_len, /* len_string_repr */
630 ether_fvalue_set, /* set_value */
631 NULL, /* set_value_uinteger */
632 NULL, /* set_value_sinteger */
633 NULL, /* set_value_integer64 */
634 NULL, /* set_value_floating */
636 value_get, /* get_value */
637 NULL, /* get_value_uinteger */
638 NULL, /* get_value_sinteger */
639 NULL, /* get_value_integer64 */
640 NULL, /* get_value_floating */
656 static ftype_t oid_type = {
659 "ASN.1 object identifier", /* pretty_name */
661 bytes_fvalue_new, /* new_value */
662 bytes_fvalue_free, /* free_value */
663 oid_from_unparsed, /* val_from_unparsed */
664 NULL, /* val_from_string */
665 oid_to_repr, /* val_to_string_repr */
666 oid_repr_len, /* len_string_repr */
668 oid_fvalue_set, /* set_value */
669 NULL, /* set_value_uinteger */
670 NULL, /* set_value_sinteger */
671 NULL, /* set_value_integer64 */
672 NULL, /* set_value_floating */
674 value_get, /* get_value */
675 NULL, /* get_value_uinteger */
676 NULL, /* get_value_sinteger */
677 NULL, /* get_value_integer64 */
678 NULL, /* get_value_floating */
688 NULL, /* cmp_matches */
694 ftype_register(FT_BYTES, &bytes_type);
695 ftype_register(FT_UINT_BYTES, &uint_bytes_type);
696 ftype_register(FT_AX25, &ax25_type);
697 ftype_register(FT_ETHER, ðer_type);
698 ftype_register(FT_OID, &oid_type);