2 * Routines for gnutella dissection
3 * Copyright 2001, B. Johannessen <bob@havoq.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include "packet-tcp.h"
17 void proto_register_gnutella(void);
18 void proto_reg_handoff_gnutella(void);
20 static dissector_handle_t gnutella_handle
;
25 * http://rfc-gnutella.sourceforge.net/developer/index.html
28 static int proto_gnutella
;
30 static int hf_gnutella_stream
;
32 static int hf_gnutella_header
;
33 static int hf_gnutella_header_id
;
34 static int hf_gnutella_header_payload
;
35 static int hf_gnutella_header_ttl
;
36 static int hf_gnutella_header_hops
;
37 static int hf_gnutella_header_size
;
39 static int hf_gnutella_pong_payload
;
40 static int hf_gnutella_pong_port
;
41 static int hf_gnutella_pong_ip
;
42 static int hf_gnutella_pong_files
;
43 static int hf_gnutella_pong_kbytes
;
45 static int hf_gnutella_query_payload
;
46 static int hf_gnutella_query_min_speed
;
47 static int hf_gnutella_query_search
;
49 static int hf_gnutella_queryhit_payload
;
50 static int hf_gnutella_queryhit_count
;
51 static int hf_gnutella_queryhit_port
;
52 static int hf_gnutella_queryhit_ip
;
53 static int hf_gnutella_queryhit_speed
;
54 static int hf_gnutella_queryhit_extra
;
55 static int hf_gnutella_queryhit_servent_id
;
57 static int hf_gnutella_queryhit_hit
;
58 static int hf_gnutella_queryhit_hit_index
;
59 static int hf_gnutella_queryhit_hit_size
;
60 static int hf_gnutella_queryhit_hit_name
;
61 static int hf_gnutella_queryhit_hit_extra
;
63 static int hf_gnutella_push_payload
;
64 static int hf_gnutella_push_servent_id
;
65 static int hf_gnutella_push_index
;
66 static int hf_gnutella_push_ip
;
67 static int hf_gnutella_push_port
;
69 static int ett_gnutella
;
71 #define GNUTELLA_TCP_PORT 6346
74 * Used to determine whether a chunk of data looks like a Gnutella packet
75 * or not - it might be a transfer stream, or it might be part of a
76 * Gnutella packet that starts in an earlier missing TCP segment.
78 * One Gnutella spec says packets SHOULD be no bigger than 4K, although
79 * that's SHOULD, not MUST.
81 #define GNUTELLA_MAX_SNAP_SIZE 4096
83 #define GNUTELLA_UNKNOWN_NAME "Unknown"
84 #define GNUTELLA_PING 0x00
85 #define GNUTELLA_PING_NAME "Ping"
86 #define GNUTELLA_PONG 0x01
87 #define GNUTELLA_PONG_NAME "Pong"
88 #define GNUTELLA_PUSH 0x40
89 #define GNUTELLA_PUSH_NAME "Push"
90 #define GNUTELLA_QUERY 0x80
91 #define GNUTELLA_QUERY_NAME "Query"
92 #define GNUTELLA_QUERYHIT 0x81
93 #define GNUTELLA_QUERYHIT_NAME "QueryHit"
95 #define GNUTELLA_HEADER_LENGTH 23
96 #define GNUTELLA_SERVENT_ID_LENGTH 16
97 #define GNUTELLA_PORT_LENGTH 2
98 #define GNUTELLA_IP_LENGTH 4
99 #define GNUTELLA_LONG_LENGTH 4
100 #define GNUTELLA_SHORT_LENGTH 2
101 #define GNUTELLA_BYTE_LENGTH 1
103 #define GNUTELLA_PONG_LENGTH 14
104 #define GNUTELLA_PONG_PORT_OFFSET 0
105 #define GNUTELLA_PONG_IP_OFFSET 2
106 #define GNUTELLA_PONG_FILES_OFFSET 6
107 #define GNUTELLA_PONG_KBYTES_OFFSET 10
109 #define GNUTELLA_QUERY_SPEED_OFFSET 0
110 #define GNUTELLA_QUERY_SEARCH_OFFSET 2
112 #define GNUTELLA_QUERYHIT_HEADER_LENGTH 11
113 #define GNUTELLA_QUERYHIT_COUNT_OFFSET 0
114 #define GNUTELLA_QUERYHIT_PORT_OFFSET 1
115 #define GNUTELLA_QUERYHIT_IP_OFFSET 3
116 #define GNUTELLA_QUERYHIT_SPEED_OFFSET 7
117 #define GNUTELLA_QUERYHIT_FIRST_HIT_OFFSET 11
118 #define GNUTELLA_QUERYHIT_HIT_INDEX_OFFSET 0
119 #define GNUTELLA_QUERYHIT_HIT_SIZE_OFFSET 4
120 #define GNUTELLA_QUERYHIT_END_OF_STRING_LENGTH 2
122 #define GNUTELLA_PUSH_SERVENT_ID_OFFSET 0
123 #define GNUTELLA_PUSH_INDEX_OFFSET 16
124 #define GNUTELLA_PUSH_IP_OFFSET 20
125 #define GNUTELLA_PUSH_PORT_OFFSET 24
127 #define GNUTELLA_HEADER_ID_OFFSET 0
128 #define GNUTELLA_HEADER_PAYLOAD_OFFSET 16
129 #define GNUTELLA_HEADER_TTL_OFFSET 17
130 #define GNUTELLA_HEADER_HOPS_OFFSET 18
131 #define GNUTELLA_HEADER_SIZE_OFFSET 19
133 static void dissect_gnutella_pong(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
) {
135 proto_tree_add_item(tree
,
136 hf_gnutella_pong_port
,
138 offset
+ GNUTELLA_PONG_PORT_OFFSET
,
139 GNUTELLA_PORT_LENGTH
,
142 proto_tree_add_item(tree
,
145 offset
+ GNUTELLA_PONG_IP_OFFSET
,
149 proto_tree_add_item(tree
,
150 hf_gnutella_pong_files
,
152 offset
+ GNUTELLA_PONG_FILES_OFFSET
,
153 GNUTELLA_LONG_LENGTH
,
156 proto_tree_add_item(tree
,
157 hf_gnutella_pong_kbytes
,
159 offset
+ GNUTELLA_PONG_KBYTES_OFFSET
,
160 GNUTELLA_LONG_LENGTH
,
165 static void dissect_gnutella_query(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, unsigned size
) {
167 proto_tree_add_item(tree
,
168 hf_gnutella_query_min_speed
,
170 offset
+ GNUTELLA_QUERY_SPEED_OFFSET
,
171 GNUTELLA_SHORT_LENGTH
,
174 if (size
> GNUTELLA_SHORT_LENGTH
) {
176 * XXX - the 0.4 spec says, of this field:
178 * It SHOULD use an ASCII-compatible encoding and
179 * charset. In this version of the protocol, no
180 * encoding was specified, but most servents use
181 * the ISO-8859-1 character set, but other encodings
182 * such as UTF-8 MAY also be used (possibly in
183 * conjonction with Query Data), as well as other
184 * international character sets (ISO-8859-*, KOI-8,
187 * No obvious mechanism is provided to indicate what
188 * encoding is being used; perhaps this should be
189 * made a preference, defaulting to ISO 8859-1.
191 proto_tree_add_item(tree
,
192 hf_gnutella_query_search
,
194 offset
+ GNUTELLA_QUERY_SEARCH_OFFSET
,
195 size
- GNUTELLA_SHORT_LENGTH
,
199 proto_tree_add_string_format(tree
,
200 hf_gnutella_query_search
, tvb
,
201 offset
+ GNUTELLA_QUERY_SEARCH_OFFSET
,
202 0, "", "Missing data for Query Search.");
206 static void dissect_gnutella_queryhit(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
, unsigned size
) {
208 proto_tree
*qhi
, *hit_tree
;
211 int name_length
, extra_length
;
212 int idx_at_offset
, size_at_offset
;
213 int servent_id_at_offset
;
214 int name_at_offset
, extra_at_offset
;
215 int cur_char
, remaining
, used
;
217 hit_count
= tvb_get_uint8(tvb
, offset
+ GNUTELLA_QUERYHIT_COUNT_OFFSET
);
219 proto_tree_add_uint(tree
,
220 hf_gnutella_queryhit_count
,
222 offset
+ GNUTELLA_QUERYHIT_COUNT_OFFSET
,
223 GNUTELLA_BYTE_LENGTH
,
226 proto_tree_add_item(tree
,
227 hf_gnutella_queryhit_port
,
229 offset
+ GNUTELLA_QUERYHIT_PORT_OFFSET
,
230 GNUTELLA_PORT_LENGTH
,
233 proto_tree_add_item(tree
,
234 hf_gnutella_queryhit_ip
,
236 offset
+ GNUTELLA_QUERYHIT_IP_OFFSET
,
240 proto_tree_add_item(tree
,
241 hf_gnutella_queryhit_speed
,
243 offset
+ GNUTELLA_QUERYHIT_SPEED_OFFSET
,
244 GNUTELLA_LONG_LENGTH
,
247 hit_offset
= offset
+ GNUTELLA_QUERYHIT_FIRST_HIT_OFFSET
;
249 for(i
= 0; i
< hit_count
; i
++) {
250 idx_at_offset
= hit_offset
;
251 size_at_offset
= hit_offset
+ GNUTELLA_QUERYHIT_HIT_SIZE_OFFSET
;
253 hit_offset
+= (GNUTELLA_LONG_LENGTH
* 2);
258 name_at_offset
= hit_offset
;
260 while(hit_offset
- offset
< size
) {
261 cur_char
= tvb_get_uint8(tvb
, hit_offset
);
271 extra_at_offset
= hit_offset
;
273 while(hit_offset
- offset
< size
) {
274 cur_char
= tvb_get_uint8(tvb
, hit_offset
);
284 qhi
= proto_tree_add_item(tree
,
285 hf_gnutella_queryhit_hit
,
288 (GNUTELLA_LONG_LENGTH
* 2) +
289 name_length
+ extra_length
+
290 GNUTELLA_QUERYHIT_END_OF_STRING_LENGTH
,
293 hit_tree
= proto_item_add_subtree(qhi
, ett_gnutella
);
295 proto_tree_add_item(hit_tree
,
296 hf_gnutella_queryhit_hit_index
,
299 GNUTELLA_LONG_LENGTH
,
302 proto_tree_add_item(hit_tree
,
303 hf_gnutella_queryhit_hit_size
,
306 GNUTELLA_LONG_LENGTH
,
309 proto_tree_add_item(hit_tree
,
310 hf_gnutella_queryhit_hit_name
,
317 proto_tree_add_item(hit_tree
,
318 hf_gnutella_queryhit_hit_extra
,
326 used
= hit_offset
- offset
;
327 remaining
= size
- used
;
329 if(remaining
> GNUTELLA_SERVENT_ID_LENGTH
) {
330 servent_id_at_offset
= hit_offset
+ remaining
- GNUTELLA_SERVENT_ID_LENGTH
;
332 proto_tree_add_item(tree
,
333 hf_gnutella_queryhit_extra
,
336 servent_id_at_offset
- hit_offset
,
340 servent_id_at_offset
= hit_offset
;
343 proto_tree_add_item(tree
,
344 hf_gnutella_queryhit_servent_id
,
346 servent_id_at_offset
,
347 GNUTELLA_SERVENT_ID_LENGTH
,
352 static void dissect_gnutella_push(tvbuff_t
*tvb
, unsigned offset
, proto_tree
*tree
) {
354 proto_tree_add_item(tree
,
355 hf_gnutella_push_servent_id
,
357 offset
+ GNUTELLA_PUSH_SERVENT_ID_OFFSET
,
358 GNUTELLA_SERVENT_ID_LENGTH
,
361 proto_tree_add_item(tree
,
362 hf_gnutella_push_index
,
364 offset
+ GNUTELLA_PUSH_INDEX_OFFSET
,
365 GNUTELLA_LONG_LENGTH
,
368 proto_tree_add_item(tree
,
371 offset
+ GNUTELLA_PUSH_IP_OFFSET
,
375 proto_tree_add_item(tree
,
376 hf_gnutella_push_port
,
378 offset
+ GNUTELLA_PUSH_PORT_OFFSET
,
379 GNUTELLA_PORT_LENGTH
,
385 get_gnutella_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
386 int offset
, void *data _U_
)
390 size
= tvb_get_letohl(
392 offset
+ GNUTELLA_HEADER_SIZE_OFFSET
);
393 if (size
> GNUTELLA_MAX_SNAP_SIZE
) {
395 * XXX - arbitrary limit, preventing overflows and
396 * attempts to reassemble 4GB of data.
398 size
= GNUTELLA_MAX_SNAP_SIZE
;
401 /* The size doesn't include the header */
402 return GNUTELLA_HEADER_LENGTH
+ size
;
405 static int dissect_gnutella_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
407 proto_item
*ti
, *hi
, *pi
;
408 proto_tree
*gnutella_tree
= NULL
;
409 proto_tree
*gnutella_header_tree
, *gnutella_pong_tree
;
410 proto_tree
*gnutella_queryhit_tree
, *gnutella_push_tree
;
411 proto_tree
*gnutella_query_tree
;
412 uint8_t payload_descriptor
;
414 const char *payload_descriptor_text
;
417 ti
= proto_tree_add_item(tree
,
423 gnutella_tree
= proto_item_add_subtree(ti
, ett_gnutella
);
425 size
= tvb_get_letohl(
427 GNUTELLA_HEADER_SIZE_OFFSET
);
430 payload_descriptor
= tvb_get_uint8(
432 GNUTELLA_HEADER_PAYLOAD_OFFSET
);
434 switch(payload_descriptor
) {
436 payload_descriptor_text
= GNUTELLA_PING_NAME
;
439 payload_descriptor_text
= GNUTELLA_PONG_NAME
;
442 payload_descriptor_text
= GNUTELLA_PUSH_NAME
;
445 payload_descriptor_text
= GNUTELLA_QUERY_NAME
;
447 case GNUTELLA_QUERYHIT
:
448 payload_descriptor_text
= GNUTELLA_QUERYHIT_NAME
;
451 payload_descriptor_text
= GNUTELLA_UNKNOWN_NAME
;
455 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
456 payload_descriptor_text
);
459 hi
= proto_tree_add_item(gnutella_tree
,
463 GNUTELLA_HEADER_LENGTH
,
465 gnutella_header_tree
= proto_item_add_subtree(hi
, ett_gnutella
);
467 proto_tree_add_item(gnutella_header_tree
,
468 hf_gnutella_header_id
,
470 GNUTELLA_HEADER_ID_OFFSET
,
471 GNUTELLA_SERVENT_ID_LENGTH
,
474 proto_tree_add_uint_format_value(gnutella_header_tree
,
475 hf_gnutella_header_payload
,
477 GNUTELLA_HEADER_PAYLOAD_OFFSET
,
478 GNUTELLA_BYTE_LENGTH
,
482 payload_descriptor_text
);
484 proto_tree_add_item(gnutella_header_tree
,
485 hf_gnutella_header_ttl
,
487 GNUTELLA_HEADER_TTL_OFFSET
,
488 GNUTELLA_BYTE_LENGTH
,
491 proto_tree_add_item(gnutella_header_tree
,
492 hf_gnutella_header_hops
,
494 GNUTELLA_HEADER_HOPS_OFFSET
,
495 GNUTELLA_BYTE_LENGTH
,
498 proto_tree_add_uint(gnutella_header_tree
,
499 hf_gnutella_header_size
,
501 GNUTELLA_HEADER_SIZE_OFFSET
,
502 GNUTELLA_LONG_LENGTH
,
506 switch(payload_descriptor
) {
508 pi
= proto_tree_add_item(
509 gnutella_header_tree
,
510 hf_gnutella_pong_payload
,
512 GNUTELLA_HEADER_LENGTH
,
515 gnutella_pong_tree
= proto_item_add_subtree(
518 dissect_gnutella_pong(
520 GNUTELLA_HEADER_LENGTH
,
524 pi
= proto_tree_add_item(
525 gnutella_header_tree
,
526 hf_gnutella_push_payload
,
528 GNUTELLA_HEADER_LENGTH
,
531 gnutella_push_tree
= proto_item_add_subtree(
534 dissect_gnutella_push(
536 GNUTELLA_HEADER_LENGTH
,
540 pi
= proto_tree_add_item(
541 gnutella_header_tree
,
542 hf_gnutella_query_payload
,
544 GNUTELLA_HEADER_LENGTH
,
547 gnutella_query_tree
= proto_item_add_subtree(
550 dissect_gnutella_query(
552 GNUTELLA_HEADER_LENGTH
,
556 case GNUTELLA_QUERYHIT
:
557 pi
= proto_tree_add_item(
558 gnutella_header_tree
,
559 hf_gnutella_queryhit_payload
,
561 GNUTELLA_HEADER_LENGTH
,
564 gnutella_queryhit_tree
= proto_item_add_subtree(
567 dissect_gnutella_queryhit(
569 GNUTELLA_HEADER_LENGTH
,
570 gnutella_queryhit_tree
,
577 return tvb_captured_length(tvb
);
581 static int dissect_gnutella(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
) {
584 proto_tree
*gnutella_tree
= NULL
;
587 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Gnutella");
589 col_clear(pinfo
->cinfo
, COL_INFO
);
592 * OK, do we have enough data to determine whether this
593 * is Gnutella messages or just a transfer stream?
595 if (tvb_bytes_exist(tvb
, GNUTELLA_HEADER_SIZE_OFFSET
, 4)) {
597 * Yes - fetch the length and see if it's bigger
598 * than GNUTELLA_MAX_SNAP_SIZE; if it is, we assume
599 * it's a transfer stream.
601 * Should we also check the payload descriptor?
603 size
= tvb_get_letohl(
605 GNUTELLA_HEADER_SIZE_OFFSET
);
606 if (size
> GNUTELLA_MAX_SNAP_SIZE
) {
608 ti
= proto_tree_add_item(tree
,
614 gnutella_tree
= proto_item_add_subtree(ti
,
617 proto_tree_add_item(gnutella_tree
,
624 return tvb_captured_length(tvb
);
628 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, GNUTELLA_HEADER_SIZE_OFFSET
+4,
629 get_gnutella_pdu_len
, dissect_gnutella_pdu
, data
);
630 return tvb_captured_length(tvb
);
633 void proto_register_gnutella(void) {
635 static hf_register_info hf
[] = {
636 { &hf_gnutella_header
,
637 { "Descriptor Header", "gnutella.header",
638 FT_NONE
, BASE_NONE
, NULL
, 0,
639 "Gnutella Descriptor Header", HFILL
}
641 { &hf_gnutella_pong_payload
,
642 { "Pong", "gnutella.pong.payload",
643 FT_NONE
, BASE_NONE
, NULL
, 0,
644 "Gnutella Pong Payload", HFILL
}
646 { &hf_gnutella_push_payload
,
647 { "Push", "gnutella.push.payload",
648 FT_NONE
, BASE_NONE
, NULL
, 0,
649 "Gnutella Push Payload", HFILL
}
651 { &hf_gnutella_query_payload
,
652 { "Query", "gnutella.query.payload",
653 FT_NONE
, BASE_NONE
, NULL
, 0,
654 "Gnutella Query Payload", HFILL
}
656 { &hf_gnutella_queryhit_payload
,
657 { "QueryHit", "gnutella.queryhit.payload",
658 FT_NONE
, BASE_NONE
, NULL
, 0,
659 "Gnutella QueryHit Payload", HFILL
}
661 { &hf_gnutella_stream
,
662 { "Gnutella Upload / Download Stream", "gnutella.stream",
663 FT_NONE
, BASE_NONE
, NULL
, 0,
666 { &hf_gnutella_header_id
,
667 { "ID", "gnutella.header.id",
668 FT_BYTES
, BASE_NONE
, NULL
, 0,
669 "Gnutella Descriptor ID", HFILL
}
671 { &hf_gnutella_header_payload
,
672 { "Payload", "gnutella.header.payload",
673 FT_UINT8
, BASE_DEC
, NULL
, 0,
674 "Gnutella Descriptor Payload", HFILL
}
676 { &hf_gnutella_header_ttl
,
677 { "TTL", "gnutella.header.ttl",
678 FT_UINT8
, BASE_DEC
, NULL
, 0,
679 "Gnutella Descriptor Time To Live", HFILL
}
681 { &hf_gnutella_header_hops
,
682 { "Hops", "gnutella.header.hops",
683 FT_UINT8
, BASE_DEC
, NULL
, 0,
684 "Gnutella Descriptor Hop Count", HFILL
}
686 { &hf_gnutella_header_size
,
687 { "Length", "gnutella.header.size",
688 FT_UINT8
, BASE_DEC
, NULL
, 0,
689 "Gnutella Descriptor Payload Length", HFILL
}
691 { &hf_gnutella_pong_port
,
692 { "Port", "gnutella.pong.port",
693 FT_UINT16
, BASE_DEC
, NULL
, 0,
694 "Gnutella Pong TCP Port", HFILL
}
696 { &hf_gnutella_pong_ip
,
697 { "IP", "gnutella.pong.ip",
698 FT_IPv4
, BASE_NONE
, NULL
, 0,
699 "Gnutella Pong IP Address", HFILL
}
701 { &hf_gnutella_pong_files
,
702 { "Files Shared", "gnutella.pong.files",
703 FT_UINT32
, BASE_DEC
, NULL
, 0,
704 "Gnutella Pong Files Shared", HFILL
}
706 { &hf_gnutella_pong_kbytes
,
707 { "KBytes Shared", "gnutella.pong.kbytes",
708 FT_UINT32
, BASE_DEC
, NULL
, 0,
709 "Gnutella Pong KBytes Shared", HFILL
}
711 { &hf_gnutella_query_min_speed
,
712 { "Min Speed", "gnutella.query.min_speed",
713 FT_UINT32
, BASE_DEC
, NULL
, 0,
714 "Gnutella Query Minimum Speed", HFILL
}
716 { &hf_gnutella_query_search
,
717 { "Search", "gnutella.query.search",
718 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
719 "Gnutella Query Search", HFILL
}
721 { &hf_gnutella_queryhit_hit
,
722 { "Hit", "gnutella.queryhit.hit",
723 FT_NONE
, BASE_NONE
, NULL
, 0,
724 "Gnutella QueryHit", HFILL
}
726 { &hf_gnutella_queryhit_hit_index
,
727 { "Index", "gnutella.queryhit.hit.index",
728 FT_UINT32
, BASE_DEC
, NULL
, 0,
729 "Gnutella QueryHit Index", HFILL
}
731 { &hf_gnutella_queryhit_hit_size
,
732 { "Size", "gnutella.queryhit.hit.size",
733 FT_UINT32
, BASE_DEC
, NULL
, 0,
734 "Gnutella QueryHit Size", HFILL
}
736 { &hf_gnutella_queryhit_hit_name
,
737 { "Name", "gnutella.queryhit.hit.name",
738 FT_STRING
, BASE_NONE
, NULL
, 0,
739 "Gnutella Query Name", HFILL
}
741 { &hf_gnutella_queryhit_hit_extra
,
742 { "Extra", "gnutella.queryhit.hit.extra",
743 FT_BYTES
, BASE_NONE
, NULL
, 0,
744 "Gnutella Query Extra", HFILL
}
746 { &hf_gnutella_queryhit_count
,
747 { "Count", "gnutella.queryhit.count",
748 FT_UINT8
, BASE_DEC
, NULL
, 0,
749 "Gnutella QueryHit Count", HFILL
}
751 { &hf_gnutella_queryhit_port
,
752 { "Port", "gnutella.queryhit.port",
753 FT_UINT16
, BASE_DEC
, NULL
, 0,
754 "Gnutella QueryHit Port", HFILL
}
756 { &hf_gnutella_queryhit_ip
,
757 { "IP", "gnutella.queryhit.ip",
758 FT_IPv4
, BASE_NONE
, NULL
, 0,
759 "Gnutella QueryHit IP Address", HFILL
}
761 { &hf_gnutella_queryhit_speed
,
762 { "Speed", "gnutella.queryhit.speed",
763 FT_UINT32
, BASE_DEC
, NULL
, 0,
764 "Gnutella QueryHit Speed", HFILL
}
766 { &hf_gnutella_queryhit_extra
,
767 { "Extra", "gnutella.queryhit.extra",
768 FT_BYTES
, BASE_NONE
, NULL
, 0,
769 "Gnutella QueryHit Extra", HFILL
}
771 { &hf_gnutella_queryhit_servent_id
,
772 { "Servent ID", "gnutella.queryhit.servent_id",
773 FT_BYTES
, BASE_NONE
, NULL
, 0,
774 "Gnutella QueryHit Servent ID", HFILL
}
776 { &hf_gnutella_push_servent_id
,
777 { "Servent ID", "gnutella.push.servent_id",
778 FT_BYTES
, BASE_NONE
, NULL
, 0,
779 "Gnutella Push Servent ID", HFILL
}
781 { &hf_gnutella_push_ip
,
782 { "IP", "gnutella.push.ip",
783 FT_IPv4
, BASE_NONE
, NULL
, 0,
784 "Gnutella Push IP Address", HFILL
}
786 { &hf_gnutella_push_index
,
787 { "Index", "gnutella.push.index",
788 FT_UINT32
, BASE_DEC
, NULL
, 0,
789 "Gnutella Push Index", HFILL
}
791 { &hf_gnutella_push_port
,
792 { "Port", "gnutella.push.port",
793 FT_UINT16
, BASE_DEC
, NULL
, 0,
794 "Gnutella Push Port", HFILL
}
798 static int *ett
[] = {
802 proto_gnutella
= proto_register_protocol("Gnutella Protocol", "GNUTELLA", "gnutella");
804 proto_register_field_array(proto_gnutella
, hf
, array_length(hf
));
806 proto_register_subtree_array(ett
, array_length(ett
));
808 gnutella_handle
= register_dissector("gnutella", dissect_gnutella
, proto_gnutella
);
811 void proto_reg_handoff_gnutella(void) {
812 dissector_add_uint_with_preference("tcp.port", GNUTELLA_TCP_PORT
, gnutella_handle
);
816 * Editor modelines - https://www.wireshark.org/tools/modelines.html
821 * indent-tabs-mode: t
824 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
825 * :indentSize=8:tabSize=8:noTabs=false: