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.
28 #include <ftypes-int.h>
31 #define CMP_MATCHES cmp_matches
33 #define tvb_is_private fvalue_gboolean1
36 value_new(fvalue_t *fv)
39 fv->tvb_is_private = FALSE;
43 value_free(fvalue_t *fv)
45 if (fv->value.tvb && fv->tvb_is_private) {
46 tvb_free_chain(fv->value.tvb);
51 value_set(fvalue_t *fv, gpointer value, gboolean already_copied)
53 g_assert(already_copied);
55 /* Free up the old value, if we have one */
58 fv->value.tvb = (tvbuff_t *)value;
62 free_tvb_data(void *data)
68 val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
73 /* Free up the old value, if we have one */
76 /* Make a tvbuff from the string. We can drop the
78 private_data = (guint8 *)g_memdup(s, (guint)strlen(s));
79 new_tvb = tvb_new_real_data(private_data,
80 (guint)strlen(s), (gint)strlen(s));
82 /* Let the tvbuff know how to delete the data. */
83 tvb_set_free_cb(new_tvb, free_tvb_data);
85 /* And let us know that we need to free the tvbuff */
86 fv->tvb_is_private = TRUE;
87 fv->value.tvb = new_tvb;
92 val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
98 /* Free up the old value, if we have one */
101 /* Does this look like a byte string? */
102 fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
104 /* Make a tvbuff from the bytes */
105 private_data = (guint8 *)g_memdup(fv_bytes->value.bytes->data,
106 fv_bytes->value.bytes->len);
107 new_tvb = tvb_new_real_data(private_data,
108 fv_bytes->value.bytes->len,
109 fv_bytes->value.bytes->len);
111 /* Let the tvbuff know how to delete the data. */
112 tvb_set_free_cb(new_tvb, free_tvb_data);
114 /* And let us know that we need to free the tvbuff */
115 fv->tvb_is_private = TRUE;
116 fv->value.tvb = new_tvb;
120 /* Treat it as a string. */
121 return val_from_string(fv, s, logfunc);
125 val_repr_len(fvalue_t *fv, ftrepr_t rtype)
127 volatile guint length = 0;
129 if (rtype != FTREPR_DFILTER) return -1;
132 /* 3 bytes for each byte of the byte "NN:" minus 1 byte
133 * as there's no trailing ":". */
134 length = tvb_length(fv->value.tvb) * 3 - 1;
145 val_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf)
152 g_assert(rtype == FTREPR_DFILTER);
155 length = tvb_length(fv->value.tvb);
156 c = tvb_get_ptr(fv->value.tvb, 0, length);
159 for (i = 0; i < length; i++) {
161 sprintf(write_cursor, "%02x", *c++);
165 sprintf(write_cursor, ":%02x", *c++);
177 value_get(fvalue_t *fv)
179 return fv->value.tvb;
185 volatile guint length = 0;
189 length = tvb_length(fv->value.tvb);
200 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
206 data = tvb_get_ptr(fv->value.tvb, offset, length);
207 g_byte_array_append(bytes, data, length);
218 cmp_eq(fvalue_t *fv_a, fvalue_t *fv_b)
220 tvbuff_t *a = fv_a->value.tvb;
221 tvbuff_t *b = fv_b->value.tvb;
222 volatile gboolean eq = FALSE;
225 guint a_len = tvb_length(a);
227 if (a_len == tvb_length(b))
228 eq = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) == 0);
239 cmp_ne(fvalue_t *fv_a, fvalue_t *fv_b)
241 tvbuff_t *a = fv_a->value.tvb;
242 tvbuff_t *b = fv_b->value.tvb;
243 volatile gboolean ne = TRUE;
246 guint a_len = tvb_length(a);
248 if (a_len == tvb_length(b)) {
249 ne = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) != 0);
261 cmp_gt(fvalue_t *fv_a, fvalue_t *fv_b)
263 tvbuff_t *a = fv_a->value.tvb;
264 tvbuff_t *b = fv_b->value.tvb;
265 volatile gboolean gt = FALSE;
268 guint a_len = tvb_length(a);
269 guint b_len = tvb_length(b);
273 } else if (a_len == b_len) {
274 gt = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) > 0);
286 cmp_ge(fvalue_t *fv_a, fvalue_t *fv_b)
288 tvbuff_t *a = fv_a->value.tvb;
289 tvbuff_t *b = fv_b->value.tvb;
290 volatile gboolean ge = FALSE;
293 guint a_len = tvb_length(a);
294 guint b_len = tvb_length(b);
298 } else if (a_len == b_len) {
299 ge = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) >= 0);
311 cmp_lt(fvalue_t *fv_a, fvalue_t *fv_b)
313 tvbuff_t *a = fv_a->value.tvb;
314 tvbuff_t *b = fv_b->value.tvb;
315 volatile gboolean lt = FALSE;
318 guint a_len = tvb_length(a);
319 guint b_len = tvb_length(b);
323 } else if (a_len == b_len) {
324 lt = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) < 0);
336 cmp_le(fvalue_t *fv_a, fvalue_t *fv_b)
338 tvbuff_t *a = fv_a->value.tvb;
339 tvbuff_t *b = fv_b->value.tvb;
340 volatile gboolean le = FALSE;
343 guint a_len = tvb_length(a);
344 guint b_len = tvb_length(b);
348 } else if (a_len == b_len) {
349 le = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) <= 0);
361 cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
363 volatile gboolean contains = FALSE;
366 if (tvb_find_tvb(fv_a->value.tvb, fv_b->value.tvb, 0) > -1) {
379 cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
381 tvbuff_t *tvb = fv_a->value.tvb;
382 GRegex *regex = fv_b->value.re;
383 volatile gboolean rc = FALSE;
384 const char *data = NULL; /* tvb data */
385 guint32 tvb_len; /* tvb length */
387 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
388 * warned us. For the same reason (and because we're using g_malloc()),
389 * fv_b->value.re is not NULL.
391 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
398 tvb_len = tvb_length(tvb);
399 data = (const char *)tvb_get_ptr(tvb, 0, tvb_len);
400 rc = g_regex_match_full(
401 regex, /* Compiled PCRE */
402 data, /* The data to check for the pattern... */
403 tvb_len, /* ... and its length */
404 0, /* Start offset within data */
405 0, /* GRegexMatchFlags */
406 NULL, /* We are not interested in the match information */
407 NULL /* We don't want error information */
409 /* NOTE - DO NOT g_free(data) */
419 ftype_register_tvbuff(void)
422 static ftype_t protocol_type = {
423 FT_PROTOCOL, /* ftype */
424 "FT_PROTOCOL", /* name */
425 "Protocol", /* pretty_name */
427 value_new, /* new_value */
428 value_free, /* free_value */
429 val_from_unparsed, /* val_from_unparsed */
430 val_from_string, /* val_from_string */
431 val_to_repr, /* val_to_string_repr */
432 val_repr_len, /* len_string_repr */
434 value_set, /* set_value */
435 NULL, /* set_value_uinteger */
436 NULL, /* set_value_sinteger */
437 NULL, /* set_value_integer64 */
438 NULL, /* set_value_floating */
440 value_get, /* get_value */
441 NULL, /* get_value_uinteger */
442 NULL, /* get_value_sinteger */
443 NULL, /* get_value_integer64 */
444 NULL, /* get_value_floating */
452 NULL, /* cmp_bitwise_and */
462 ftype_register(FT_PROTOCOL, &protocol_type);