2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 2001 Gerald Combs
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <ftypes-int.h>
24 #include <epan/to_str-int.h>
27 #include <epan/exceptions.h>
29 #define CMP_MATCHES cmp_matches
31 #define tvb_is_private fvalue_gboolean1
34 value_new(fvalue_t *fv)
36 fv->value.protocol.tvb = NULL;
37 fv->value.protocol.proto_string = NULL;
38 fv->tvb_is_private = FALSE;
42 value_free(fvalue_t *fv)
44 if (fv->value.protocol.tvb && fv->tvb_is_private) {
45 tvb_free_chain(fv->value.protocol.tvb);
47 g_free(fv->value.protocol.proto_string);
51 value_set(fvalue_t *fv, tvbuff_t *value, const gchar *name)
53 /* Free up the old value, if we have one */
56 fv->value.protocol.tvb = value;
57 fv->value.protocol.proto_string = g_strdup(name);
61 free_tvb_data(void *data)
67 val_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
72 /* Free up the old value, if we have one */
75 /* Make a tvbuff from the string. We can drop the
77 private_data = (guint8 *)g_memdup(s, (guint)strlen(s));
78 new_tvb = tvb_new_real_data(private_data,
79 (guint)strlen(s), (gint)strlen(s));
81 /* Let the tvbuff know how to delete the data. */
82 tvb_set_free_cb(new_tvb, free_tvb_data);
84 /* And let us know that we need to free the tvbuff */
85 fv->tvb_is_private = TRUE;
86 fv->value.protocol.tvb = new_tvb;
87 fv->value.protocol.proto_string = g_strdup(s);
92 val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
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.protocol.tvb = new_tvb;
120 /* Treat it as a string. */
121 return val_from_string(fv, s, err_msg);
125 val_repr_len(fvalue_t *fv, ftrepr_t rtype, int field_display _U_)
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_captured_length(fv->value.protocol.tvb) * 3 - 1;
145 val_to_repr(fvalue_t *fv, ftrepr_t rtype, int field_display _U_, char * volatile buf, unsigned int size _U_)
149 g_assert(rtype == FTREPR_DFILTER);
152 length = tvb_captured_length(fv->value.protocol.tvb);
155 buf = bytes_to_hexstr_punct(buf, tvb_get_ptr(fv->value.protocol.tvb, 0, length), length, ':');
165 value_get(fvalue_t *fv)
167 return fv->value.protocol.tvb;
173 volatile guint length = 0;
176 if (fv->value.protocol.tvb)
177 length = tvb_captured_length(fv->value.protocol.tvb);
188 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
192 if (fv->value.protocol.tvb) {
194 data = tvb_get_ptr(fv->value.protocol.tvb, offset, length);
195 g_byte_array_append(bytes, data, length);
206 cmp_eq(const fvalue_t *fv_a, const fvalue_t *fv_b)
208 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
209 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
210 volatile gboolean eq = FALSE;
213 if ((a->tvb != NULL) && (b->tvb != NULL)) {
214 guint a_len = tvb_captured_length(a->tvb);
216 if (a_len == tvb_captured_length(b->tvb))
217 eq = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) == 0);
219 eq = (strcmp(a->proto_string, b->proto_string) == 0);
231 cmp_ne(const fvalue_t *fv_a, const fvalue_t *fv_b)
233 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
234 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
235 volatile gboolean ne = TRUE;
238 if ((a->tvb != NULL) && (b->tvb != NULL)) {
239 guint a_len = tvb_captured_length(a->tvb);
241 if (a_len == tvb_captured_length(b->tvb))
242 ne = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) != 0);
244 ne = (strcmp(a->proto_string, b->proto_string) != 0);
256 cmp_gt(const fvalue_t *fv_a, const fvalue_t *fv_b)
258 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
259 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
260 volatile gboolean gt = FALSE;
263 if ((a->tvb != NULL) && (b->tvb != NULL)) {
264 guint a_len = tvb_captured_length(a->tvb);
265 guint b_len = tvb_captured_length(b->tvb);
269 } else if (a_len == b_len) {
270 gt = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) > 0);
273 return (strcmp(a->proto_string, b->proto_string) > 0);
285 cmp_ge(const fvalue_t *fv_a, const fvalue_t *fv_b)
287 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
288 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
289 volatile gboolean ge = FALSE;
292 if ((a->tvb != NULL) && (b->tvb != NULL)) {
293 guint a_len = tvb_captured_length(a->tvb);
294 guint b_len = tvb_captured_length(b->tvb);
298 } else if (a_len == b_len) {
299 ge = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) >= 0);
302 return (strcmp(a->proto_string, b->proto_string) >= 0);
314 cmp_lt(const fvalue_t *fv_a, const fvalue_t *fv_b)
316 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
317 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
318 volatile gboolean lt = FALSE;
321 if ((a->tvb != NULL) && (b->tvb != NULL)) {
322 guint a_len = tvb_captured_length(a->tvb);
323 guint b_len = tvb_captured_length(b->tvb);
327 } else if (a_len == b_len) {
328 lt = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) < 0);
331 return (strcmp(a->proto_string, b->proto_string) < 0);
343 cmp_le(const fvalue_t *fv_a, const fvalue_t *fv_b)
345 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
346 const protocol_value_t *b = (const protocol_value_t *)&fv_b->value.protocol;
347 volatile gboolean le = FALSE;
350 if ((a->tvb != NULL) && (b->tvb != NULL)) {
351 guint a_len = tvb_captured_length(a->tvb);
352 guint b_len = tvb_captured_length(b->tvb);
356 } else if (a_len == b_len) {
357 le = (memcmp(tvb_get_ptr(a->tvb, 0, a_len), tvb_get_ptr(b->tvb, 0, a_len), a_len) <= 0);
360 return (strcmp(a->proto_string, b->proto_string) <= 0);
372 cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b)
374 volatile gboolean contains = FALSE;
377 /* First see if tvb exists for both sides */
378 if ((fv_a->value.protocol.tvb != NULL) && (fv_b->value.protocol.tvb != NULL)) {
379 if (tvb_find_tvb(fv_a->value.protocol.tvb, fv_b->value.protocol.tvb, 0) > -1) {
383 /* Otherwise just compare strings */
384 if ((strlen(fv_b->value.protocol.proto_string) != 0) &&
385 strstr(fv_a->value.protocol.proto_string, fv_b->value.protocol.proto_string)) {
399 cmp_matches(const fvalue_t *fv_a, const fvalue_t *fv_b)
401 const protocol_value_t *a = (const protocol_value_t *)&fv_a->value.protocol;
402 GRegex *regex = fv_b->value.re;
403 volatile gboolean rc = FALSE;
404 const char *data = NULL; /* tvb data */
405 guint32 tvb_len; /* tvb length */
407 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
408 * warned us. For the same reason (and because we're using g_malloc()),
409 * fv_b->value.re is not NULL.
411 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
418 if (a->tvb != NULL) {
419 tvb_len = tvb_captured_length(a->tvb);
420 data = (const char *)tvb_get_ptr(a->tvb, 0, tvb_len);
421 rc = g_regex_match_full(
422 regex, /* Compiled PCRE */
423 data, /* The data to check for the pattern... */
424 tvb_len, /* ... and its length */
425 0, /* Start offset within data */
426 (GRegexMatchFlags)0, /* GRegexMatchFlags */
427 NULL, /* We are not interested in the match information */
428 NULL /* We don't want error information */
430 /* NOTE - DO NOT g_free(data) */
432 rc = g_regex_match_full(
433 regex, /* Compiled PCRE */
434 a->proto_string, /* The data to check for the pattern... */
435 (int)strlen(a->proto_string), /* ... and its length */
436 0, /* Start offset within data */
437 (GRegexMatchFlags)0, /* GRegexMatchFlags */
438 NULL, /* We are not interested in the match information */
439 NULL /* We don't want error information */
451 ftype_register_tvbuff(void)
454 static ftype_t protocol_type = {
455 FT_PROTOCOL, /* ftype */
456 "FT_PROTOCOL", /* name */
457 "Protocol", /* pretty_name */
459 value_new, /* new_value */
460 value_free, /* free_value */
461 val_from_unparsed, /* val_from_unparsed */
462 val_from_string, /* val_from_string */
463 val_to_repr, /* val_to_string_repr */
464 val_repr_len, /* len_string_repr */
466 { .set_value_protocol = value_set }, /* union set_value */
469 value_get, /* get_value */
470 NULL, /* get_value_uinteger */
471 NULL, /* get_value_sinteger */
472 NULL, /* get_value_uinteger64 */
473 NULL, /* get_value_sinteger64 */
474 NULL, /* get_value_floating */
482 NULL, /* cmp_bitwise_and */
492 ftype_register(FT_PROTOCOL, &protocol_type);
496 * Editor modelines - http://www.wireshark.org/tools/modelines.html
501 * indent-tabs-mode: t
504 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
505 * :indentSize=8:tabSize=8:noTabs=false: