/* * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 2001 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include #include #include #include #include #include #include #include static void bytes_fvalue_new(fvalue_t *fv) { fv->value.bytes = NULL; } static void bytes_fvalue_copy(fvalue_t *dst, const fvalue_t *src) { dst->value.bytes = g_bytes_ref(src->value.bytes); } static void bytes_fvalue_free(fvalue_t *fv) { if (fv->value.bytes) { g_bytes_unref(fv->value.bytes); fv->value.bytes = NULL; } } static void bytes_fvalue_set(fvalue_t *fv, GBytes *value) { /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_bytes_ref(value); } static GBytes * bytes_fvalue_get(fvalue_t *fv) { return g_bytes_ref(fv->value.bytes); } static char * oid_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_) { return oid_encoded2string(scope, g_bytes_get_data(fv->value.bytes, NULL), (unsigned)g_bytes_get_size(fv->value.bytes)); } static char * rel_oid_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_) { return rel_oid_encoded2string(scope, g_bytes_get_data(fv->value.bytes, NULL), (unsigned)g_bytes_get_size(fv->value.bytes)); } static char * system_id_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_) { return print_system_id(scope, g_bytes_get_data(fv->value.bytes, NULL), (unsigned)g_bytes_get_size(fv->value.bytes)); } char * bytes_to_dfilter_repr(wmem_allocator_t *scope, const uint8_t *src, size_t src_size) { char *buf; size_t max_char_size; char *buf_ptr; /* Include space for extra punct and '\0'. */ max_char_size = src_size * 3 + 1; buf = wmem_alloc(scope, max_char_size); buf_ptr = bytes_to_hexstr_punct(buf, src, src_size, ':'); if (src_size == 1) *buf_ptr++ = ':'; *buf_ptr = '\0'; return buf; } static char * bytes_to_repr(wmem_allocator_t *scope, const fvalue_t *fv, ftrepr_t rtype, int field_display) { char separator; const uint8_t *bytes; size_t bytes_size; bytes = g_bytes_get_data(fv->value.bytes, &bytes_size); if (rtype == FTREPR_DFILTER) { if (bytes_size == 0) { /* An empty byte array in a display filter is represented as "" */ return wmem_strdup(scope, "\"\""); } return bytes_to_dfilter_repr(scope, bytes, bytes_size); } switch(FIELD_DISPLAY(field_display)) { case SEP_DOT: separator = '.'; break; case SEP_DASH: separator = '-'; break; case SEP_SPACE: case SEP_COLON: case BASE_NONE: default: separator = ':'; break; } if (bytes_size) { return bytes_to_str_punct_maxlen(scope, bytes, bytes_size, separator, 0); } return wmem_strdup(scope, ""); } static bool bytes_from_string(fvalue_t *fv, const char *s, size_t len, char **err_msg _U_) { GByteArray *bytes; bytes = g_byte_array_new(); if (len == 0) len = strlen(s); g_byte_array_append(bytes, (const uint8_t *)s, (unsigned)len); /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_byte_array_free_to_bytes(bytes); return true; } GByteArray * byte_array_from_literal(const char *s, char **err_msg) { GByteArray *bytes; bool res; /* Skip leading colon if any. */ if (*s == ':') s++; /* * Special case where the byte string is specified using a one byte * hex literal. We can't allow this for byte strings that are longer * than one byte, because then we'd have to know which endianness the * byte string should be in. */ if (strlen(s) == 4 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s = s + 2; bytes = g_byte_array_new(); /* Hack: If we have a binary number 0bXXXXXXXX use that as a byte array * of length one. This is ambiguous because it can also be * parsed (without separators) as a byte array of length 5: * 0bXXXXXXXX = 0b:XX:XX:XX:XX = { 0x0b, 0xXX, 0xXX, 0xXX, 0xXX } */ if (strlen(s) == 10 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B') && (s[2] == '0' || s[2] == '1')) { errno = 0; char *endptr; long number = strtol(s + 2, &endptr, 2); if (errno == 0 && *endptr == '\0' && number >= 0x0 && number <= 0xff) { uint8_t byte = (uint8_t)number; g_byte_array_append(bytes, &byte, 1); return bytes; } } res = hex_str_to_bytes(s, bytes, false); if (!res) { if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid byte string.", s); g_byte_array_free(bytes, true); return NULL; } return bytes; } static bool bytes_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value _U_, char **err_msg) { GByteArray *bytes; bytes = byte_array_from_literal(s, err_msg); if (bytes == NULL) return false; /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_byte_array_free_to_bytes(bytes); return true; } GByteArray * byte_array_from_charconst(unsigned long num, char **err_msg) { if (num > UINT8_MAX) { if (err_msg) { *err_msg = ws_strdup_printf("%lu is too large for a byte value", num); } return NULL; } GByteArray *bytes = g_byte_array_new(); uint8_t one_byte = (uint8_t)num; g_byte_array_append(bytes, &one_byte, 1); return bytes; } static bool bytes_from_charconst(fvalue_t *fv, unsigned long num, char **err_msg) { GByteArray *bytes; bytes = byte_array_from_charconst(num, err_msg); if (bytes == NULL) return false; /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_byte_array_free_to_bytes(bytes); return true; } static bool ax25_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value, char **err_msg) { /* * Don't request an error message if bytes_from_literal fails; * if it does, we'll report an error specific to this address * type. */ if (bytes_from_literal(fv, s, true, NULL)) { if (g_bytes_get_size(fv->value.bytes) > FT_AX25_ADDR_LEN) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too many bytes to be a valid AX.25 address.", s); } return false; } else if (g_bytes_get_size(fv->value.bytes) < FT_AX25_ADDR_LEN && !allow_partial_value) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too few bytes to be a valid AX.25 address.", s); } return false; } return true; } /* * XXX - what needs to be done here is something such as: * * Look for a "-" in the string. * * If we find it, make sure that there are 1-6 alphanumeric * ASCII characters before it, and that there are 2 decimal * digits after it, from 00 to 15; if we don't find it, make * sure that there are 1-6 alphanumeric ASCII characters * in the string. * * If so, make the first 6 octets of the address the ASCII * characters, with lower-case letters mapped to upper-case * letters, shifted left by 1 bit, padded to 6 octets with * spaces, also shifted left by 1 bit, and, if we found a * "-", convert what's after it to a number and make the 7th * octet the number, shifted left by 1 bit, otherwise make the * 7th octet zero. * * We should also change all the comparison functions for * AX.25 addresses check the upper 7 bits of all but the last * octet of the address, ignoring the "end of address" bit, * and compare only the 4 bits above the low-order bit for * the last octet, ignoring the "end of address" bit and * various reserved bits and bits used for other purposes. * * See section 3.12 "Address-Field Encoding" of the AX.25 * spec and * * http://www.itu.int/ITU-R/terrestrial/docs/fixedmobile/fxm-art19-sec3.pdf */ if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid AX.25 address.", s); return false; } static bool vines_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value, char **err_msg) { /* * Don't request an error message if bytes_from_literal fails; * if it does, we'll report an error specific to this address * type. */ if (bytes_from_literal(fv, s, true, NULL)) { if (g_bytes_get_size(fv->value.bytes) > FT_VINES_ADDR_LEN) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too many bytes to be a valid Vines address.", s); } return false; } else if (g_bytes_get_size(fv->value.bytes) < FT_VINES_ADDR_LEN && !allow_partial_value) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too few bytes to be a valid Vines address.", s); } return false; } return true; } /* XXX - need better validation of Vines address */ if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid Vines address.", s); return false; } static bool ether_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value, char **err_msg) { /* * Don't request an error message if bytes_from_literal fails; * if it does, we'll report an error specific to this address * type. */ if (bytes_from_literal(fv, s, true, NULL)) { if (g_bytes_get_size(fv->value.bytes) > FT_ETHER_LEN) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too many bytes to be a valid Ethernet address.", s); } return false; } else if (g_bytes_get_size(fv->value.bytes) < FT_ETHER_LEN && !allow_partial_value) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too few bytes to be a valid Ethernet address.", s); } return false; } return true; } /* XXX - Try resolving as an Ethernet host name and parse that? */ if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid Ethernet address.", s); return false; } static bool oid_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value _U_, char **err_msg) { GByteArray *bytes; bool res; #if 0 /* * Don't log a message if this fails; we'll try looking it * up as an OID if it does, and if that fails, * we'll log a message. */ /* do not try it as '.' is handled as valid separator for hexbytes :( */ if (bytes_from_literal(fv, s, true, NULL)) { return true; } #endif bytes = g_byte_array_new(); res = oid_str_to_bytes(s, bytes); if (!res) { if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid OBJECT IDENTIFIER.", s); g_byte_array_free(bytes, true); return false; } /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_byte_array_free_to_bytes(bytes); return true; } static bool rel_oid_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value _U_, char **err_msg) { GByteArray *bytes; bool res; bytes = g_byte_array_new(); res = rel_oid_str_to_bytes(s, bytes, false); if (!res) { if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid RELATIVE-OID.", s); g_byte_array_free(bytes, true); return false; } /* Free up the old value, if we have one */ bytes_fvalue_free(fv); fv->value.bytes = g_byte_array_free_to_bytes(bytes); return true; } static bool system_id_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value _U_, char **err_msg) { /* * Don't request an error message if bytes_from_literal fails; * if it does, we'll report an error specific to this address * type. */ if (bytes_from_literal(fv, s, true, NULL)) { if (g_bytes_get_size(fv->value.bytes) > MAX_SYSTEMID_LEN) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too many bytes to be a valid OSI System-ID.", s); } return false; } return true; } /* XXX - need better validation of OSI System-ID address */ if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid OSI System-ID.", s); return false; } static bool fcwwn_from_literal(fvalue_t *fv, const char *s, bool allow_partial_value _U_, char **err_msg) { /* * Don't request an error message if bytes_from_literal fails; * if it does, we'll report an error specific to this address * type. */ if (bytes_from_literal(fv, s, true, NULL)) { if (g_bytes_get_size(fv->value.bytes) > FT_FCWWN_LEN) { if (err_msg != NULL) { *err_msg = ws_strdup_printf("\"%s\" contains too many bytes to be a valid FCWWN.", s); } return false; } return true; } /* XXX - need better validation of FCWWN address */ if (err_msg != NULL) *err_msg = ws_strdup_printf("\"%s\" is not a valid FCWWN.", s); return false; } static unsigned len(fvalue_t *fv) { return (unsigned)g_bytes_get_size(fv->value.bytes); } static void slice(fvalue_t *fv, GByteArray *bytes, unsigned offset, unsigned length) { const uint8_t *data = (const uint8_t *)g_bytes_get_data(fv->value.bytes, NULL) + offset; g_byte_array_append(bytes, data, length); } static enum ft_result cmp_order(const fvalue_t *fv_a, const fvalue_t *fv_b, int *cmp) { *cmp = g_bytes_compare(fv_a->value.bytes, fv_b->value.bytes); return FT_OK; } static enum ft_result bytes_bitwise_and(fvalue_t *fv_dst, const fvalue_t *fv_a, const fvalue_t *fv_b, char **err_ptr _U_) { GByteArray *dst; const uint8_t *p_a, *p_b; size_t size_a, size_b; p_a = g_bytes_get_data(fv_a->value.bytes, &size_a); p_b = g_bytes_get_data(fv_b->value.bytes, &size_b); size_t len = MIN(size_a, size_b); if (len == 0) { fv_dst->value.bytes = g_bytes_new(NULL, 0); return FT_OK; } dst = g_byte_array_sized_new((unsigned)len); for (size_t i = 0; i < len; i++) { uint8_t byte = p_a[i] & p_b[i]; g_byte_array_append(dst, &byte, 1); } fv_dst->value.bytes = g_byte_array_free_to_bytes(dst); return FT_OK; } static enum ft_result cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b, bool *contains) { const void *data_a, *data_b; size_t size_a, size_b; data_a = g_bytes_get_data(fv_a->value.bytes, &size_a); data_b = g_bytes_get_data(fv_b->value.bytes, &size_b); if (ws_memmem(data_a, size_a, data_b, size_b)) { *contains = true; } else { *contains = false; } return FT_OK; } static enum ft_result cmp_matches(const fvalue_t *fv, const ws_regex_t *regex, bool *matches) { const void *data; size_t data_size; data = g_bytes_get_data(fv->value.bytes, &data_size); *matches = ws_regex_matches_length(regex, data, data_size); return FT_OK; } static unsigned bytes_hash(const fvalue_t *fv) { return g_bytes_hash(fv->value.bytes); } static bool bytes_is_zero(const fvalue_t *fv) { const uint8_t *data; size_t data_size; data = g_bytes_get_data(fv->value.bytes, &data_size); if (data_size == 0) return true; for (size_t i = 0; i < data_size; i++) { if (data[i] != 0) { return false; } } return true; } void ftype_register_bytes(void) { static ftype_t bytes_type = { FT_BYTES, /* ftype */ "FT_BYTES", /* name */ "Byte sequence", /* pretty_name */ 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ bytes_from_literal, /* val_from_literal */ bytes_from_string, /* val_from_string */ bytes_from_charconst, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, cmp_matches, bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t uint_bytes_type = { FT_UINT_BYTES, /* ftype */ "FT_UINT_BYTES", /* name */ "Byte sequence", /* pretty_name */ 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ bytes_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, NULL, /* cmp_matches */ bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t ax25_type = { FT_AX25, /* ftype */ "FT_AX25", /* name */ "AX.25 address", /* pretty_name */ FT_AX25_ADDR_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ ax25_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, cmp_matches, bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t vines_type = { FT_VINES, /* ftype */ "FT_VINES", /* name */ "VINES address", /* pretty_name */ FT_VINES_ADDR_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ vines_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, cmp_matches, bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t ether_type = { FT_ETHER, /* ftype */ "FT_ETHER", /* name */ "Ethernet or other MAC address",/* pretty_name */ FT_ETHER_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ ether_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, cmp_matches, bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t oid_type = { FT_OID, /* ftype */ "FT_OID", /* name */ "ASN.1 object identifier", /* pretty_name */ 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ oid_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ oid_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, NULL, /* cmp_matches */ bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t rel_oid_type = { FT_REL_OID, /* ftype */ "FT_REL_OID", /* name */ "ASN.1 relative object identifier", /* pretty_name */ 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ rel_oid_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ rel_oid_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, NULL, /* cmp_matches */ bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t system_id_type = { FT_SYSTEM_ID, /* ftype */ "FT_SYSTEM_ID", /* name */ "OSI System-ID", /* pretty_name */ 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ system_id_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ system_id_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, NULL, /* cmp_matches */ bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; static ftype_t fcwwn_type = { FT_FCWWN, /* ftype */ "FT_FCWWN", /* name */ "Fibre Channel WWN", /* pretty_name */ FT_FCWWN_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_copy, /* copy_value */ bytes_fvalue_free, /* free_value */ fcwwn_from_literal, /* val_from_literal */ NULL, /* val_from_string */ NULL, /* val_from_charconst */ bytes_to_repr, /* val_to_string_repr */ NULL, /* val_to_uinteger64 */ NULL, /* val_to_sinteger64 */ { .set_value_bytes = bytes_fvalue_set }, /* union set_value */ { .get_value_bytes = bytes_fvalue_get }, /* union get_value */ cmp_order, cmp_contains, cmp_matches, bytes_hash, /* hash */ bytes_is_zero, /* is_zero */ NULL, /* is_negative */ len, (FvalueSlice)slice, bytes_bitwise_and, /* bitwise_and */ NULL, /* unary_minus */ NULL, /* add */ NULL, /* subtract */ NULL, /* multiply */ NULL, /* divide */ NULL, /* modulo */ }; ftype_register(FT_BYTES, &bytes_type); ftype_register(FT_UINT_BYTES, &uint_bytes_type); ftype_register(FT_AX25, &ax25_type); ftype_register(FT_VINES, &vines_type); ftype_register(FT_ETHER, ðer_type); ftype_register(FT_OID, &oid_type); ftype_register(FT_REL_OID, &rel_oid_type); ftype_register(FT_SYSTEM_ID, &system_id_type); ftype_register(FT_FCWWN, &fcwwn_type); } void ftype_register_pseudofields_bytes(int proto) { static int hf_ft_bytes; static int hf_ft_uint_bytes; static int hf_ft_ax25; static int hf_ft_vines; static int hf_ft_ether; static int hf_ft_oid; static int hf_ft_rel_oid; static int hf_ft_system_id; static hf_register_info hf_ftypes[] = { { &hf_ft_bytes, { "FT_BYTES", "_ws.ftypes.bytes", FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_uint_bytes, { "FT_UINT_BYTES", "_ws.ftypes.uint_bytes", FT_UINT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_ax25, { "FT_AX25", "_ws.ftypes.ax25", FT_AX25, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_vines, { "FT_VINES", "_ws.ftypes.vines", FT_VINES, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_ether, { "FT_ETHER", "_ws.ftypes.ether", FT_ETHER, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_oid, { "FT_OID", "_ws.ftypes.oid", FT_OID, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_rel_oid, { "FT_REL_OID", "_ws.ftypes.rel_oid", FT_REL_OID, BASE_NONE, NULL, 0x00, NULL, HFILL } }, { &hf_ft_system_id, { "FT_SYSTEM_ID", "_ws.ftypes.system_id", FT_SYSTEM_ID, BASE_NONE, NULL, 0x00, NULL, HFILL } }, }; proto_register_field_array(proto, hf_ftypes, array_length(hf_ftypes)); } /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 8 * tab-width: 8 * indent-tabs-mode: t * End: * * vi: set shiftwidth=8 tabstop=8 noexpandtab: * :indentSize=8:tabSize=8:noTabs=false: */