4 * Ethereal - Network traffic analyzer
5 * By Gerald Combs <gerald@ethereal.com>
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.
27 #include <ftypes-int.h>
32 #define CMP_MATCHES cmp_matches
34 #define CMP_MATCHES NULL
40 string_fvalue_new(fvalue_t *fv)
42 fv->value.string = NULL;
46 string_fvalue_free(fvalue_t *fv)
48 if (fv->value.string) {
49 g_free(fv->value.string);
54 string_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
56 g_assert(value != NULL);
58 /* Free up the old value, if we have one */
59 string_fvalue_free(fv);
62 fv->value.string = value;
65 fv->value.string = g_strdup(value);
70 string_repr_len(fvalue_t *fv, ftrepr_t rtype)
77 return strlen(fv->value.string);
80 for (p = fv->value.string; (c = *p) != '\0'; p++) {
81 /* Backslashes and double-quotes must
83 if (c == '\\' || c == '"') {
86 /* Values that can't nicely be represented
87 * in ASCII need to be escaped. */
88 else if (!isprint((unsigned char)c)) {
92 /* Other characters are just passed through. */
97 return repr_len + 2; /* string plus leading and trailing quotes */
99 g_assert_not_reached();
104 string_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf)
110 if (rtype == FTREPR_DFILTER) {
113 for (p = fv->value.string; (c = *p) != '\0'; p++) {
114 /* Backslashes and double-quotes must
116 if (c == '\\' || c == '"') {
120 /* Values that can't nicely be represented
121 * in ASCII need to be escaped. */
122 else if (!isprint((unsigned char)c)) {
124 sprintf(hex, "%02x", (unsigned char) c);
130 /* Other characters are just passed through. */
139 strcpy(buf, fv->value.string);
145 value_get(fvalue_t *fv)
147 return fv->value.string;
151 val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
153 /* Free up the old value, if we have one */
154 string_fvalue_free(fv);
156 fv->value.string = g_strdup(s);
161 val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
165 /* Free up the old value, if we have one */
166 string_fvalue_free(fv);
168 /* Does this look like a byte-string? */
169 fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
171 /* Copy the bytes over to a string and terminate it
172 * with a NUL. XXX - what if the user embeds a NUL
173 * in the middle of the byte string? */
174 int num_bytes = fv_bytes->value.bytes->len;
176 fv->value.string = g_malloc(num_bytes + 1);
177 memcpy(fv->value.string, fv_bytes->value.bytes->data, num_bytes);
178 fv->value.string[num_bytes] = '\0';
180 FVALUE_FREE(fv_bytes);
184 /* Just turn it into a string */
185 return val_from_string(fv, s, logfunc);
187 g_assert_not_reached();
193 return strlen(fv->value.string);
197 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
201 data = fv->value.ustring + offset;
203 g_byte_array_append(bytes, data, length);
208 cmp_eq(fvalue_t *a, fvalue_t *b)
210 return (strcmp(a->value.string, b->value.string) == 0);
214 cmp_ne(fvalue_t *a, fvalue_t *b)
216 return (strcmp(a->value.string, b->value.string) != 0);
220 cmp_gt(fvalue_t *a, fvalue_t *b)
222 return (strcmp(a->value.string, b->value.string) > 0);
226 cmp_ge(fvalue_t *a, fvalue_t *b)
228 return (strcmp(a->value.string, b->value.string) >= 0);
232 cmp_lt(fvalue_t *a, fvalue_t *b)
234 return (strcmp(a->value.string, b->value.string) < 0);
238 cmp_le(fvalue_t *a, fvalue_t *b)
240 return (strcmp(a->value.string, b->value.string) <= 0);
244 cmp_contains(fvalue_t *fv_a, fvalue_t *fv_b)
247 * http://www.introl.com/introl-demo/Libraries/C/ANSI_C/string/strstr.html
248 * strstr() returns a non-NULL value if needle is an empty
249 * string. We don't that behavior for cmp_contains. */
250 if (strlen(fv_b->value.string) == 0) {
254 if (strstr(fv_a->value.string, fv_b->value.string)) {
264 cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
266 char *str = fv_a->value.string;
267 pcre_tuple_t *pcre = fv_b->value.re;
271 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
272 * warned us. For the same reason (and because we're using g_malloc()),
273 * fv_b->value.re is not NULL.
275 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
282 pcre->re, /* Compiled PCRE */
283 pcre->ex, /* PCRE extra from pcre_study() */
284 str, /* The data to check for the pattern... */
285 (int)strlen(str), /* ... and its length */
286 0, /* Start offset within data */
287 options, /* PCRE options */
288 NULL, /* We are not interested in the matched string */
289 0 /* of the pattern; only in success or failure. */
299 ftype_register_string(void)
302 static ftype_t string_type = {
303 "FT_STRING", /* name */
304 "character string", /* pretty_name */
306 string_fvalue_new, /* new_value */
307 string_fvalue_free, /* free_value */
308 val_from_unparsed, /* val_from_unparsed */
309 val_from_string, /* val_from_string */
310 string_to_repr, /* val_to_string_repr */
311 string_repr_len, /* len_string_repr */
313 string_fvalue_set, /* set_value */
314 NULL, /* set_value_integer */
315 NULL, /* set_value_integer64 */
316 NULL, /* set_value_floating */
318 value_get, /* get_value */
319 NULL, /* get_value_integer */
320 NULL, /* get_value_integer64 */
321 NULL, /* get_value_floating */
329 NULL, /* cmp_bitwise_and */
336 static ftype_t stringz_type = {
337 "FT_STRINGZ", /* name */
338 "character string", /* pretty name */
340 string_fvalue_new, /* new_value */
341 string_fvalue_free, /* free_value */
342 val_from_unparsed, /* val_from_unparsed */
343 val_from_string, /* val_from_string */
344 NULL, /* val_to_string_repr */
345 NULL, /* len_string_repr */
347 string_fvalue_set, /* set_value */
348 NULL, /* set_value_integer */
349 NULL, /* set_value_integer64 */
350 NULL, /* set_value_floating */
352 value_get, /* get_value */
353 NULL, /* get_value_integer */
354 NULL, /* get_value_integer64 */
355 NULL, /* get_value_floating */
363 NULL, /* cmp_bitwise_and */
364 cmp_contains, /* cmp_contains */
370 static ftype_t uint_string_type = {
371 "FT_UINT_STRING", /* name */
372 "character string", /* pretty_name */
374 string_fvalue_new, /* new_value */
375 string_fvalue_free, /* free_value */
376 val_from_unparsed, /* val_from_unparsed */
377 val_from_string, /* val_from_string */
378 NULL, /* val_to_string_repr */
379 NULL, /* len_string_repr */
381 string_fvalue_set, /* set_value */
382 NULL, /* set_value_integer */
383 NULL, /* set_value_integer64 */
384 NULL, /* set_value_floating */
386 value_get, /* get_value */
387 NULL, /* get_value_integer */
388 NULL, /* get_value_integer64 */
389 NULL, /* get_value_floating */
397 NULL, /* cmp_bitwise_and */
398 cmp_contains, /* cmp_contains */
405 ftype_register(FT_STRING, &string_type);
406 ftype_register(FT_STRINGZ, &stringz_type);
407 ftype_register(FT_UINT_STRING, &uint_string_type);