diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-gnutella.c | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-gnutella.c')
-rw-r--r-- | epan/dissectors/packet-gnutella.c | 826 |
1 files changed, 826 insertions, 0 deletions
diff --git a/epan/dissectors/packet-gnutella.c b/epan/dissectors/packet-gnutella.c new file mode 100644 index 00000000..c060d38a --- /dev/null +++ b/epan/dissectors/packet-gnutella.c @@ -0,0 +1,826 @@ +/* packet-gnutella.c + * Routines for gnutella dissection + * Copyright 2001, B. Johannessen <bob@havoq.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <epan/packet.h> +#include "packet-tcp.h" + +void proto_register_gnutella(void); +void proto_reg_handoff_gnutella(void); + +static dissector_handle_t gnutella_handle; + +/* + * See + * + * http://rfc-gnutella.sourceforge.net/developer/index.html + */ + +static int proto_gnutella = -1; + +static int hf_gnutella_stream = -1; + +static int hf_gnutella_header = -1; +static int hf_gnutella_header_id = -1; +static int hf_gnutella_header_payload = -1; +static int hf_gnutella_header_ttl = -1; +static int hf_gnutella_header_hops = -1; +static int hf_gnutella_header_size = -1; + +static int hf_gnutella_pong_payload = -1; +static int hf_gnutella_pong_port = -1; +static int hf_gnutella_pong_ip = -1; +static int hf_gnutella_pong_files = -1; +static int hf_gnutella_pong_kbytes = -1; + +static int hf_gnutella_query_payload = -1; +static int hf_gnutella_query_min_speed = -1; +static int hf_gnutella_query_search = -1; + +static int hf_gnutella_queryhit_payload = -1; +static int hf_gnutella_queryhit_count = -1; +static int hf_gnutella_queryhit_port = -1; +static int hf_gnutella_queryhit_ip = -1; +static int hf_gnutella_queryhit_speed = -1; +static int hf_gnutella_queryhit_extra = -1; +static int hf_gnutella_queryhit_servent_id = -1; + +static int hf_gnutella_queryhit_hit = -1; +static int hf_gnutella_queryhit_hit_index = -1; +static int hf_gnutella_queryhit_hit_size = -1; +static int hf_gnutella_queryhit_hit_name = -1; +static int hf_gnutella_queryhit_hit_extra = -1; + +static int hf_gnutella_push_payload = -1; +static int hf_gnutella_push_servent_id = -1; +static int hf_gnutella_push_index = -1; +static int hf_gnutella_push_ip = -1; +static int hf_gnutella_push_port = -1; + +static gint ett_gnutella = -1; + +#define GNUTELLA_TCP_PORT 6346 + +/* + * Used to determine whether a chunk of data looks like a Gnutella packet + * or not - it might be a transfer stream, or it might be part of a + * Gnutella packet that starts in an earlier missing TCP segment. + * + * One Gnutella spec says packets SHOULD be no bigger than 4K, although + * that's SHOULD, not MUST. + */ +#define GNUTELLA_MAX_SNAP_SIZE 4096 + +#define GNUTELLA_UNKNOWN_NAME "Unknown" +#define GNUTELLA_PING 0x00 +#define GNUTELLA_PING_NAME "Ping" +#define GNUTELLA_PONG 0x01 +#define GNUTELLA_PONG_NAME "Pong" +#define GNUTELLA_PUSH 0x40 +#define GNUTELLA_PUSH_NAME "Push" +#define GNUTELLA_QUERY 0x80 +#define GNUTELLA_QUERY_NAME "Query" +#define GNUTELLA_QUERYHIT 0x81 +#define GNUTELLA_QUERYHIT_NAME "QueryHit" + +#define GNUTELLA_HEADER_LENGTH 23 +#define GNUTELLA_SERVENT_ID_LENGTH 16 +#define GNUTELLA_PORT_LENGTH 2 +#define GNUTELLA_IP_LENGTH 4 +#define GNUTELLA_LONG_LENGTH 4 +#define GNUTELLA_SHORT_LENGTH 2 +#define GNUTELLA_BYTE_LENGTH 1 + +#define GNUTELLA_PONG_LENGTH 14 +#define GNUTELLA_PONG_PORT_OFFSET 0 +#define GNUTELLA_PONG_IP_OFFSET 2 +#define GNUTELLA_PONG_FILES_OFFSET 6 +#define GNUTELLA_PONG_KBYTES_OFFSET 10 + +#define GNUTELLA_QUERY_SPEED_OFFSET 0 +#define GNUTELLA_QUERY_SEARCH_OFFSET 2 + +#define GNUTELLA_QUERYHIT_HEADER_LENGTH 11 +#define GNUTELLA_QUERYHIT_COUNT_OFFSET 0 +#define GNUTELLA_QUERYHIT_PORT_OFFSET 1 +#define GNUTELLA_QUERYHIT_IP_OFFSET 3 +#define GNUTELLA_QUERYHIT_SPEED_OFFSET 7 +#define GNUTELLA_QUERYHIT_FIRST_HIT_OFFSET 11 +#define GNUTELLA_QUERYHIT_HIT_INDEX_OFFSET 0 +#define GNUTELLA_QUERYHIT_HIT_SIZE_OFFSET 4 +#define GNUTELLA_QUERYHIT_END_OF_STRING_LENGTH 2 + +#define GNUTELLA_PUSH_SERVENT_ID_OFFSET 0 +#define GNUTELLA_PUSH_INDEX_OFFSET 16 +#define GNUTELLA_PUSH_IP_OFFSET 20 +#define GNUTELLA_PUSH_PORT_OFFSET 24 + +#define GNUTELLA_HEADER_ID_OFFSET 0 +#define GNUTELLA_HEADER_PAYLOAD_OFFSET 16 +#define GNUTELLA_HEADER_TTL_OFFSET 17 +#define GNUTELLA_HEADER_HOPS_OFFSET 18 +#define GNUTELLA_HEADER_SIZE_OFFSET 19 + +static void dissect_gnutella_pong(tvbuff_t *tvb, guint offset, proto_tree *tree) { + + proto_tree_add_item(tree, + hf_gnutella_pong_port, + tvb, + offset + GNUTELLA_PONG_PORT_OFFSET, + GNUTELLA_PORT_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_pong_ip, + tvb, + offset + GNUTELLA_PONG_IP_OFFSET, + GNUTELLA_IP_LENGTH, + ENC_BIG_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_pong_files, + tvb, + offset + GNUTELLA_PONG_FILES_OFFSET, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_pong_kbytes, + tvb, + offset + GNUTELLA_PONG_KBYTES_OFFSET, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + +} + +static void dissect_gnutella_query(tvbuff_t *tvb, guint offset, proto_tree *tree, guint size) { + + proto_tree_add_item(tree, + hf_gnutella_query_min_speed, + tvb, + offset + GNUTELLA_QUERY_SPEED_OFFSET, + GNUTELLA_SHORT_LENGTH, + ENC_LITTLE_ENDIAN); + + if (size > GNUTELLA_SHORT_LENGTH) { + /* + * XXX - the 0.4 spec says, of this field: + * + * It SHOULD use an ASCII-compatible encoding and + * charset. In this version of the protocol, no + * encoding was specified, but most servents use + * the ISO-8859-1 character set, but other encodings + * such as UTF-8 MAY also be used (possibly in + * conjonction with Query Data), as well as other + * international character sets (ISO-8859-*, KOI-8, + * S-JIS, Big5, ...). + * + * No obvious mechanism is provided to indicate what + * encoding is being used; perhaps this should be + * made a preference, defaulting to ISO 8859-1. + */ + proto_tree_add_item(tree, + hf_gnutella_query_search, + tvb, + offset + GNUTELLA_QUERY_SEARCH_OFFSET, + size - GNUTELLA_SHORT_LENGTH, + ENC_ASCII); + } + else { + proto_tree_add_string_format(tree, + hf_gnutella_query_search, tvb, + offset + GNUTELLA_QUERY_SEARCH_OFFSET, + 0, "", "Missing data for Query Search."); + } +} + +static void dissect_gnutella_queryhit(tvbuff_t *tvb, guint offset, proto_tree *tree, guint size) { + + proto_tree *qhi, *hit_tree; + int hit_count, i; + int hit_offset; + int name_length, extra_length; + int idx_at_offset, size_at_offset; + int servent_id_at_offset; + int name_at_offset, extra_at_offset; + int cur_char, remaining, used; + + hit_count = tvb_get_guint8(tvb, offset + GNUTELLA_QUERYHIT_COUNT_OFFSET); + + proto_tree_add_uint(tree, + hf_gnutella_queryhit_count, + tvb, + offset + GNUTELLA_QUERYHIT_COUNT_OFFSET, + GNUTELLA_BYTE_LENGTH, + hit_count); + + proto_tree_add_item(tree, + hf_gnutella_queryhit_port, + tvb, + offset + GNUTELLA_QUERYHIT_PORT_OFFSET, + GNUTELLA_PORT_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_queryhit_ip, + tvb, + offset + GNUTELLA_QUERYHIT_IP_OFFSET, + GNUTELLA_IP_LENGTH, + ENC_BIG_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_queryhit_speed, + tvb, + offset + GNUTELLA_QUERYHIT_SPEED_OFFSET, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + + hit_offset = offset + GNUTELLA_QUERYHIT_FIRST_HIT_OFFSET; + + for(i = 0; i < hit_count; i++) { + idx_at_offset = hit_offset; + size_at_offset = hit_offset + GNUTELLA_QUERYHIT_HIT_SIZE_OFFSET; + + hit_offset += (GNUTELLA_LONG_LENGTH * 2); + + name_length = 0; + extra_length = 0; + + name_at_offset = hit_offset; + + while(hit_offset - offset < size) { + cur_char = tvb_get_guint8(tvb, hit_offset); + if(cur_char == '\0') + break; + + hit_offset++; + name_length++; + } + + hit_offset++; + + extra_at_offset = hit_offset; + + while(hit_offset - offset < size) { + cur_char = tvb_get_guint8(tvb, hit_offset); + if(cur_char == '\0') + break; + + hit_offset++; + extra_length++; + } + + hit_offset++; + + qhi = proto_tree_add_item(tree, + hf_gnutella_queryhit_hit, + tvb, + idx_at_offset, + (GNUTELLA_LONG_LENGTH * 2) + + name_length + extra_length + + GNUTELLA_QUERYHIT_END_OF_STRING_LENGTH, + ENC_NA); + + hit_tree = proto_item_add_subtree(qhi, ett_gnutella); + + proto_tree_add_item(hit_tree, + hf_gnutella_queryhit_hit_index, + tvb, + idx_at_offset, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(hit_tree, + hf_gnutella_queryhit_hit_size, + tvb, + size_at_offset, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(hit_tree, + hf_gnutella_queryhit_hit_name, + tvb, + name_at_offset, + name_length, + ENC_ASCII); + + if(extra_length) { + proto_tree_add_item(hit_tree, + hf_gnutella_queryhit_hit_extra, + tvb, + extra_at_offset, + extra_length, + ENC_NA); + } + } + + used = hit_offset - offset; + remaining = size - used; + + if(remaining > GNUTELLA_SERVENT_ID_LENGTH) { + servent_id_at_offset = hit_offset + remaining - GNUTELLA_SERVENT_ID_LENGTH; + + proto_tree_add_item(tree, + hf_gnutella_queryhit_extra, + tvb, + hit_offset, + servent_id_at_offset - hit_offset, + ENC_NA); + } + else { + servent_id_at_offset = hit_offset; + } + + proto_tree_add_item(tree, + hf_gnutella_queryhit_servent_id, + tvb, + servent_id_at_offset, + GNUTELLA_SERVENT_ID_LENGTH, + ENC_NA); + +} + +static void dissect_gnutella_push(tvbuff_t *tvb, guint offset, proto_tree *tree) { + + proto_tree_add_item(tree, + hf_gnutella_push_servent_id, + tvb, + offset + GNUTELLA_PUSH_SERVENT_ID_OFFSET, + GNUTELLA_SERVENT_ID_LENGTH, + ENC_NA); + + proto_tree_add_item(tree, + hf_gnutella_push_index, + tvb, + offset + GNUTELLA_PUSH_INDEX_OFFSET, + GNUTELLA_LONG_LENGTH, + ENC_LITTLE_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_push_ip, + tvb, + offset + GNUTELLA_PUSH_IP_OFFSET, + GNUTELLA_IP_LENGTH, + ENC_BIG_ENDIAN); + + proto_tree_add_item(tree, + hf_gnutella_push_port, + tvb, + offset + GNUTELLA_PUSH_PORT_OFFSET, + GNUTELLA_PORT_LENGTH, + ENC_LITTLE_ENDIAN); + +} + +static guint +get_gnutella_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, + int offset, void *data _U_) +{ + guint32 size; + + size = tvb_get_letohl( + tvb, + offset + GNUTELLA_HEADER_SIZE_OFFSET); + if (size > GNUTELLA_MAX_SNAP_SIZE) { + /* + * XXX - arbitrary limit, preventing overflows and + * attempts to reassemble 4GB of data. + */ + size = GNUTELLA_MAX_SNAP_SIZE; + } + + /* The size doesn't include the header */ + return GNUTELLA_HEADER_LENGTH + size; +} + +static int dissect_gnutella_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { + + proto_item *ti, *hi, *pi; + proto_tree *gnutella_tree = NULL; + proto_tree *gnutella_header_tree, *gnutella_pong_tree; + proto_tree *gnutella_queryhit_tree, *gnutella_push_tree; + proto_tree *gnutella_query_tree; + guint8 payload_descriptor; + guint32 size = 0; + const char *payload_descriptor_text; + + if (tree) { + ti = proto_tree_add_item(tree, + proto_gnutella, + tvb, + 0, + -1, + ENC_NA); + gnutella_tree = proto_item_add_subtree(ti, ett_gnutella); + + size = tvb_get_letohl( + tvb, + GNUTELLA_HEADER_SIZE_OFFSET); + } + + payload_descriptor = tvb_get_guint8( + tvb, + GNUTELLA_HEADER_PAYLOAD_OFFSET); + + switch(payload_descriptor) { + case GNUTELLA_PING: + payload_descriptor_text = GNUTELLA_PING_NAME; + break; + case GNUTELLA_PONG: + payload_descriptor_text = GNUTELLA_PONG_NAME; + break; + case GNUTELLA_PUSH: + payload_descriptor_text = GNUTELLA_PUSH_NAME; + break; + case GNUTELLA_QUERY: + payload_descriptor_text = GNUTELLA_QUERY_NAME; + break; + case GNUTELLA_QUERYHIT: + payload_descriptor_text = GNUTELLA_QUERYHIT_NAME; + break; + default: + payload_descriptor_text = GNUTELLA_UNKNOWN_NAME; + break; + } + + col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, + payload_descriptor_text); + + if (tree) { + hi = proto_tree_add_item(gnutella_tree, + hf_gnutella_header, + tvb, + 0, + GNUTELLA_HEADER_LENGTH, + ENC_NA); + gnutella_header_tree = proto_item_add_subtree(hi, ett_gnutella); + + proto_tree_add_item(gnutella_header_tree, + hf_gnutella_header_id, + tvb, + GNUTELLA_HEADER_ID_OFFSET, + GNUTELLA_SERVENT_ID_LENGTH, + ENC_NA); + + proto_tree_add_uint_format_value(gnutella_header_tree, + hf_gnutella_header_payload, + tvb, + GNUTELLA_HEADER_PAYLOAD_OFFSET, + GNUTELLA_BYTE_LENGTH, + payload_descriptor, + "%i (%s)", + payload_descriptor, + payload_descriptor_text); + + proto_tree_add_item(gnutella_header_tree, + hf_gnutella_header_ttl, + tvb, + GNUTELLA_HEADER_TTL_OFFSET, + GNUTELLA_BYTE_LENGTH, + ENC_BIG_ENDIAN); + + proto_tree_add_item(gnutella_header_tree, + hf_gnutella_header_hops, + tvb, + GNUTELLA_HEADER_HOPS_OFFSET, + GNUTELLA_BYTE_LENGTH, + ENC_BIG_ENDIAN); + + proto_tree_add_uint(gnutella_header_tree, + hf_gnutella_header_size, + tvb, + GNUTELLA_HEADER_SIZE_OFFSET, + GNUTELLA_LONG_LENGTH, + size); + + if (size > 0) { + switch(payload_descriptor) { + case GNUTELLA_PONG: + pi = proto_tree_add_item( + gnutella_header_tree, + hf_gnutella_pong_payload, + tvb, + GNUTELLA_HEADER_LENGTH, + size, + ENC_NA); + gnutella_pong_tree = proto_item_add_subtree( + pi, + ett_gnutella); + dissect_gnutella_pong( + tvb, + GNUTELLA_HEADER_LENGTH, + gnutella_pong_tree); + break; + case GNUTELLA_PUSH: + pi = proto_tree_add_item( + gnutella_header_tree, + hf_gnutella_push_payload, + tvb, + GNUTELLA_HEADER_LENGTH, + size, + ENC_NA); + gnutella_push_tree = proto_item_add_subtree( + pi, + ett_gnutella); + dissect_gnutella_push( + tvb, + GNUTELLA_HEADER_LENGTH, + gnutella_push_tree); + break; + case GNUTELLA_QUERY: + pi = proto_tree_add_item( + gnutella_header_tree, + hf_gnutella_query_payload, + tvb, + GNUTELLA_HEADER_LENGTH, + size, + ENC_NA); + gnutella_query_tree = proto_item_add_subtree( + pi, + ett_gnutella); + dissect_gnutella_query( + tvb, + GNUTELLA_HEADER_LENGTH, + gnutella_query_tree, + size); + break; + case GNUTELLA_QUERYHIT: + pi = proto_tree_add_item( + gnutella_header_tree, + hf_gnutella_queryhit_payload, + tvb, + GNUTELLA_HEADER_LENGTH, + size, + ENC_NA); + gnutella_queryhit_tree = proto_item_add_subtree( + pi, + ett_gnutella); + dissect_gnutella_queryhit( + tvb, + GNUTELLA_HEADER_LENGTH, + gnutella_queryhit_tree, + size); + break; + } + } + } + + return tvb_captured_length(tvb); +} + + +static int dissect_gnutella(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { + + proto_item *ti; + proto_tree *gnutella_tree = NULL; + guint32 size; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gnutella"); + + col_clear(pinfo->cinfo, COL_INFO); + + /* + * OK, do we have enough data to determine whether this + * is Gnutella messages or just a transfer stream? + */ + if (tvb_bytes_exist(tvb, GNUTELLA_HEADER_SIZE_OFFSET, 4)) { + /* + * Yes - fetch the length and see if it's bigger + * than GNUTELLA_MAX_SNAP_SIZE; if it is, we assume + * it's a transfer stream. + * + * Should we also check the payload descriptor? + */ + size = tvb_get_letohl( + tvb, + GNUTELLA_HEADER_SIZE_OFFSET); + if (size > GNUTELLA_MAX_SNAP_SIZE) { + if (tree) { + ti = proto_tree_add_item(tree, + proto_gnutella, + tvb, + 0, + -1, + ENC_NA); + gnutella_tree = proto_item_add_subtree(ti, + ett_gnutella); + + proto_tree_add_item(gnutella_tree, + hf_gnutella_stream, + tvb, + 0, + -1, + ENC_NA); + } + return tvb_captured_length(tvb); + } + } + + tcp_dissect_pdus(tvb, pinfo, tree, TRUE, GNUTELLA_HEADER_SIZE_OFFSET+4, + get_gnutella_pdu_len, dissect_gnutella_pdu, data); + return tvb_captured_length(tvb); +} + +void proto_register_gnutella(void) { + + static hf_register_info hf[] = { + { &hf_gnutella_header, + { "Descriptor Header", "gnutella.header", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella Descriptor Header", HFILL } + }, + { &hf_gnutella_pong_payload, + { "Pong", "gnutella.pong.payload", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella Pong Payload", HFILL } + }, + { &hf_gnutella_push_payload, + { "Push", "gnutella.push.payload", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella Push Payload", HFILL } + }, + { &hf_gnutella_query_payload, + { "Query", "gnutella.query.payload", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella Query Payload", HFILL } + }, + { &hf_gnutella_queryhit_payload, + { "QueryHit", "gnutella.queryhit.payload", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella QueryHit Payload", HFILL } + }, + { &hf_gnutella_stream, + { "Gnutella Upload / Download Stream", "gnutella.stream", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL } + }, + { &hf_gnutella_header_id, + { "ID", "gnutella.header.id", + FT_BYTES, BASE_NONE, NULL, 0, + "Gnutella Descriptor ID", HFILL } + }, + { &hf_gnutella_header_payload, + { "Payload", "gnutella.header.payload", + FT_UINT8, BASE_DEC, NULL, 0, + "Gnutella Descriptor Payload", HFILL } + }, + { &hf_gnutella_header_ttl, + { "TTL", "gnutella.header.ttl", + FT_UINT8, BASE_DEC, NULL, 0, + "Gnutella Descriptor Time To Live", HFILL } + }, + { &hf_gnutella_header_hops, + { "Hops", "gnutella.header.hops", + FT_UINT8, BASE_DEC, NULL, 0, + "Gnutella Descriptor Hop Count", HFILL } + }, + { &hf_gnutella_header_size, + { "Length", "gnutella.header.size", + FT_UINT8, BASE_DEC, NULL, 0, + "Gnutella Descriptor Payload Length", HFILL } + }, + { &hf_gnutella_pong_port, + { "Port", "gnutella.pong.port", + FT_UINT16, BASE_DEC, NULL, 0, + "Gnutella Pong TCP Port", HFILL } + }, + { &hf_gnutella_pong_ip, + { "IP", "gnutella.pong.ip", + FT_IPv4, BASE_NONE, NULL, 0, + "Gnutella Pong IP Address", HFILL } + }, + { &hf_gnutella_pong_files, + { "Files Shared", "gnutella.pong.files", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella Pong Files Shared", HFILL } + }, + { &hf_gnutella_pong_kbytes, + { "KBytes Shared", "gnutella.pong.kbytes", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella Pong KBytes Shared", HFILL } + }, + { &hf_gnutella_query_min_speed, + { "Min Speed", "gnutella.query.min_speed", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella Query Minimum Speed", HFILL } + }, + { &hf_gnutella_query_search, + { "Search", "gnutella.query.search", + FT_STRINGZ, BASE_NONE, NULL, 0, + "Gnutella Query Search", HFILL } + }, + { &hf_gnutella_queryhit_hit, + { "Hit", "gnutella.queryhit.hit", + FT_NONE, BASE_NONE, NULL, 0, + "Gnutella QueryHit", HFILL } + }, + { &hf_gnutella_queryhit_hit_index, + { "Index", "gnutella.queryhit.hit.index", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella QueryHit Index", HFILL } + }, + { &hf_gnutella_queryhit_hit_size, + { "Size", "gnutella.queryhit.hit.size", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella QueryHit Size", HFILL } + }, + { &hf_gnutella_queryhit_hit_name, + { "Name", "gnutella.queryhit.hit.name", + FT_STRING, BASE_NONE, NULL, 0, + "Gnutella Query Name", HFILL } + }, + { &hf_gnutella_queryhit_hit_extra, + { "Extra", "gnutella.queryhit.hit.extra", + FT_BYTES, BASE_NONE, NULL, 0, + "Gnutella Query Extra", HFILL } + }, + { &hf_gnutella_queryhit_count, + { "Count", "gnutella.queryhit.count", + FT_UINT8, BASE_DEC, NULL, 0, + "Gnutella QueryHit Count", HFILL } + }, + { &hf_gnutella_queryhit_port, + { "Port", "gnutella.queryhit.port", + FT_UINT16, BASE_DEC, NULL, 0, + "Gnutella QueryHit Port", HFILL } + }, + { &hf_gnutella_queryhit_ip, + { "IP", "gnutella.queryhit.ip", + FT_IPv4, BASE_NONE, NULL, 0, + "Gnutella QueryHit IP Address", HFILL } + }, + { &hf_gnutella_queryhit_speed, + { "Speed", "gnutella.queryhit.speed", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella QueryHit Speed", HFILL } + }, + { &hf_gnutella_queryhit_extra, + { "Extra", "gnutella.queryhit.extra", + FT_BYTES, BASE_NONE, NULL, 0, + "Gnutella QueryHit Extra", HFILL } + }, + { &hf_gnutella_queryhit_servent_id, + { "Servent ID", "gnutella.queryhit.servent_id", + FT_BYTES, BASE_NONE, NULL, 0, + "Gnutella QueryHit Servent ID", HFILL } + }, + { &hf_gnutella_push_servent_id, + { "Servent ID", "gnutella.push.servent_id", + FT_BYTES, BASE_NONE, NULL, 0, + "Gnutella Push Servent ID", HFILL } + }, + { &hf_gnutella_push_ip, + { "IP", "gnutella.push.ip", + FT_IPv4, BASE_NONE, NULL, 0, + "Gnutella Push IP Address", HFILL } + }, + { &hf_gnutella_push_index, + { "Index", "gnutella.push.index", + FT_UINT32, BASE_DEC, NULL, 0, + "Gnutella Push Index", HFILL } + }, + { &hf_gnutella_push_port, + { "Port", "gnutella.push.port", + FT_UINT16, BASE_DEC, NULL, 0, + "Gnutella Push Port", HFILL } + }, + }; + + static gint *ett[] = { + &ett_gnutella, + }; + + proto_gnutella = proto_register_protocol("Gnutella Protocol", "GNUTELLA", "gnutella"); + + proto_register_field_array(proto_gnutella, hf, array_length(hf)); + + proto_register_subtree_array(ett, array_length(ett)); + + gnutella_handle = register_dissector("gnutella", dissect_gnutella, proto_gnutella); +} + +void proto_reg_handoff_gnutella(void) { + dissector_add_uint_with_preference("tcp.port", GNUTELLA_TCP_PORT, gnutella_handle); +} + +/* + * 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: + */ |