MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-gnutella.c
blobdf7890dacd053421a4a1c02543191392913e6043
1 /* packet-gnutella.c
2 * Routines for gnutella dissection
3 * Copyright 2001, B. Johannessen <bob@havoq.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <glib.h>
30 #include <epan/packet.h>
31 #include "packet-gnutella.h"
32 #include "packet-tcp.h"
35 * See
37 * http://rfc-gnutella.sourceforge.net/developer/index.html
40 static int proto_gnutella = -1;
42 static int hf_gnutella_stream = -1;
44 static int hf_gnutella_header = -1;
45 static int hf_gnutella_header_id = -1;
46 static int hf_gnutella_header_payload = -1;
47 static int hf_gnutella_header_ttl = -1;
48 static int hf_gnutella_header_hops = -1;
49 static int hf_gnutella_header_size = -1;
51 static int hf_gnutella_pong_payload = -1;
52 static int hf_gnutella_pong_port = -1;
53 static int hf_gnutella_pong_ip = -1;
54 static int hf_gnutella_pong_files = -1;
55 static int hf_gnutella_pong_kbytes = -1;
57 static int hf_gnutella_query_payload = -1;
58 static int hf_gnutella_query_min_speed = -1;
59 static int hf_gnutella_query_search = -1;
61 static int hf_gnutella_queryhit_payload = -1;
62 static int hf_gnutella_queryhit_count = -1;
63 static int hf_gnutella_queryhit_port = -1;
64 static int hf_gnutella_queryhit_ip = -1;
65 static int hf_gnutella_queryhit_speed = -1;
66 static int hf_gnutella_queryhit_extra = -1;
67 static int hf_gnutella_queryhit_servent_id = -1;
69 static int hf_gnutella_queryhit_hit = -1;
70 static int hf_gnutella_queryhit_hit_index = -1;
71 static int hf_gnutella_queryhit_hit_size = -1;
72 static int hf_gnutella_queryhit_hit_name = -1;
73 static int hf_gnutella_queryhit_hit_extra = -1;
75 static int hf_gnutella_push_payload = -1;
76 static int hf_gnutella_push_servent_id = -1;
77 static int hf_gnutella_push_index = -1;
78 static int hf_gnutella_push_ip = -1;
79 static int hf_gnutella_push_port = -1;
81 static gint ett_gnutella = -1;
83 static void dissect_gnutella_pong(tvbuff_t *tvb, guint offset, proto_tree *tree) {
85 proto_tree_add_item(tree,
86 hf_gnutella_pong_port,
87 tvb,
88 offset + GNUTELLA_PONG_PORT_OFFSET,
89 GNUTELLA_PORT_LENGTH,
90 ENC_LITTLE_ENDIAN);
92 proto_tree_add_item(tree,
93 hf_gnutella_pong_ip,
94 tvb,
95 offset + GNUTELLA_PONG_IP_OFFSET,
96 GNUTELLA_IP_LENGTH,
97 ENC_BIG_ENDIAN);
99 proto_tree_add_item(tree,
100 hf_gnutella_pong_files,
101 tvb,
102 offset + GNUTELLA_PONG_FILES_OFFSET,
103 GNUTELLA_LONG_LENGTH,
104 ENC_LITTLE_ENDIAN);
106 proto_tree_add_item(tree,
107 hf_gnutella_pong_kbytes,
108 tvb,
109 offset + GNUTELLA_PONG_KBYTES_OFFSET,
110 GNUTELLA_LONG_LENGTH,
111 ENC_LITTLE_ENDIAN);
115 static void dissect_gnutella_query(tvbuff_t *tvb, guint offset, proto_tree *tree, guint size) {
117 proto_tree_add_item(tree,
118 hf_gnutella_query_min_speed,
119 tvb,
120 offset + GNUTELLA_QUERY_SPEED_OFFSET,
121 GNUTELLA_SHORT_LENGTH,
122 ENC_LITTLE_ENDIAN);
124 if (size > GNUTELLA_SHORT_LENGTH) {
125 proto_tree_add_item(tree,
126 hf_gnutella_query_search,
127 tvb,
128 offset + GNUTELLA_QUERY_SEARCH_OFFSET,
129 size - GNUTELLA_SHORT_LENGTH,
130 ENC_ASCII|ENC_NA);
132 else {
133 proto_tree_add_text(tree,
134 tvb,
135 offset + GNUTELLA_QUERY_SEARCH_OFFSET,
137 "Missing data for Query Search.");
141 static void dissect_gnutella_queryhit(tvbuff_t *tvb, guint offset, proto_tree *tree, guint size) {
143 proto_tree *qhi, *hit_tree;
144 int hit_count, i;
145 int hit_offset;
146 int name_length, extra_length;
147 int idx_at_offset, size_at_offset;
148 int servent_id_at_offset;
149 int name_at_offset, extra_at_offset;
150 int cur_char, remaining, used;
152 hit_count = tvb_get_guint8(tvb, offset + GNUTELLA_QUERYHIT_COUNT_OFFSET);
154 proto_tree_add_uint(tree,
155 hf_gnutella_queryhit_count,
156 tvb,
157 offset + GNUTELLA_QUERYHIT_COUNT_OFFSET,
158 GNUTELLA_BYTE_LENGTH,
159 hit_count);
161 proto_tree_add_item(tree,
162 hf_gnutella_queryhit_port,
163 tvb,
164 offset + GNUTELLA_QUERYHIT_PORT_OFFSET,
165 GNUTELLA_PORT_LENGTH,
166 ENC_LITTLE_ENDIAN);
168 proto_tree_add_item(tree,
169 hf_gnutella_queryhit_ip,
170 tvb,
171 offset + GNUTELLA_QUERYHIT_IP_OFFSET,
172 GNUTELLA_IP_LENGTH,
173 ENC_BIG_ENDIAN);
175 proto_tree_add_item(tree,
176 hf_gnutella_queryhit_speed,
177 tvb,
178 offset + GNUTELLA_QUERYHIT_SPEED_OFFSET,
179 GNUTELLA_LONG_LENGTH,
180 ENC_LITTLE_ENDIAN);
182 hit_offset = offset + GNUTELLA_QUERYHIT_FIRST_HIT_OFFSET;
184 for(i = 0; i < hit_count; i++) {
185 idx_at_offset = hit_offset;
186 size_at_offset = hit_offset + GNUTELLA_QUERYHIT_HIT_SIZE_OFFSET;
188 hit_offset += (GNUTELLA_LONG_LENGTH * 2);
190 name_length = 0;
191 extra_length = 0;
193 name_at_offset = hit_offset;
195 while(hit_offset - offset < size) {
196 cur_char = tvb_get_guint8(tvb, hit_offset);
197 if(cur_char == '\0')
198 break;
200 hit_offset++;
201 name_length++;
204 hit_offset++;
206 extra_at_offset = hit_offset;
208 while(hit_offset - offset < size) {
209 cur_char = tvb_get_guint8(tvb, hit_offset);
210 if(cur_char == '\0')
211 break;
213 hit_offset++;
214 extra_length++;
217 hit_offset++;
219 qhi = proto_tree_add_item(tree,
220 hf_gnutella_queryhit_hit,
221 tvb,
222 idx_at_offset,
223 (GNUTELLA_LONG_LENGTH * 2) +
224 name_length + extra_length +
225 GNUTELLA_QUERYHIT_END_OF_STRING_LENGTH,
226 ENC_NA);
228 hit_tree = proto_item_add_subtree(qhi, ett_gnutella);
230 proto_tree_add_item(hit_tree,
231 hf_gnutella_queryhit_hit_index,
232 tvb,
233 idx_at_offset,
234 GNUTELLA_LONG_LENGTH,
235 ENC_LITTLE_ENDIAN);
237 proto_tree_add_item(hit_tree,
238 hf_gnutella_queryhit_hit_size,
239 tvb,
240 size_at_offset,
241 GNUTELLA_LONG_LENGTH,
242 ENC_LITTLE_ENDIAN);
244 proto_tree_add_item(hit_tree,
245 hf_gnutella_queryhit_hit_name,
246 tvb,
247 name_at_offset,
248 name_length,
249 ENC_ASCII|ENC_NA);
251 if(extra_length) {
252 proto_tree_add_item(hit_tree,
253 hf_gnutella_queryhit_hit_extra,
254 tvb,
255 extra_at_offset,
256 extra_length,
257 ENC_NA);
261 used = hit_offset - offset;
262 remaining = size - used;
264 if(remaining > GNUTELLA_SERVENT_ID_LENGTH) {
265 servent_id_at_offset = hit_offset + remaining - GNUTELLA_SERVENT_ID_LENGTH;
267 proto_tree_add_item(tree,
268 hf_gnutella_queryhit_extra,
269 tvb,
270 hit_offset,
271 servent_id_at_offset - hit_offset,
272 ENC_NA);
274 else {
275 servent_id_at_offset = hit_offset;
278 proto_tree_add_item(tree,
279 hf_gnutella_queryhit_servent_id,
280 tvb,
281 servent_id_at_offset,
282 GNUTELLA_SERVENT_ID_LENGTH,
283 ENC_NA);
287 static void dissect_gnutella_push(tvbuff_t *tvb, guint offset, proto_tree *tree) {
289 proto_tree_add_item(tree,
290 hf_gnutella_push_servent_id,
291 tvb,
292 offset + GNUTELLA_PUSH_SERVENT_ID_OFFSET,
293 GNUTELLA_SERVENT_ID_LENGTH,
294 ENC_NA);
296 proto_tree_add_item(tree,
297 hf_gnutella_push_index,
298 tvb,
299 offset + GNUTELLA_PUSH_INDEX_OFFSET,
300 GNUTELLA_LONG_LENGTH,
301 ENC_LITTLE_ENDIAN);
303 proto_tree_add_item(tree,
304 hf_gnutella_push_ip,
305 tvb,
306 offset + GNUTELLA_PUSH_IP_OFFSET,
307 GNUTELLA_IP_LENGTH,
308 ENC_BIG_ENDIAN);
310 proto_tree_add_item(tree,
311 hf_gnutella_push_port,
312 tvb,
313 offset + GNUTELLA_PUSH_PORT_OFFSET,
314 GNUTELLA_PORT_LENGTH,
315 ENC_LITTLE_ENDIAN);
319 static guint
320 get_gnutella_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) {
321 guint32 size;
323 size = tvb_get_letohl(
324 tvb,
325 offset + GNUTELLA_HEADER_SIZE_OFFSET);
326 if (size > GNUTELLA_MAX_SNAP_SIZE) {
328 * XXX - arbitrary limit, preventing overflows and
329 * attempts to reassemble 4GB of data.
331 size = GNUTELLA_MAX_SNAP_SIZE;
334 /* The size doesn't include the header */
335 return GNUTELLA_HEADER_LENGTH + size;
338 static int dissect_gnutella_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
340 proto_item *ti, *hi, *pi;
341 proto_tree *gnutella_tree = NULL;
342 proto_tree *gnutella_header_tree, *gnutella_pong_tree;
343 proto_tree *gnutella_queryhit_tree, *gnutella_push_tree;
344 proto_tree *gnutella_query_tree;
345 guint8 payload_descriptor;
346 guint32 size = 0;
347 const char *payload_descriptor_text;
349 if (tree) {
350 ti = proto_tree_add_item(tree,
351 proto_gnutella,
352 tvb,
355 ENC_NA);
356 gnutella_tree = proto_item_add_subtree(ti, ett_gnutella);
358 size = tvb_get_letohl(
359 tvb,
360 GNUTELLA_HEADER_SIZE_OFFSET);
363 payload_descriptor = tvb_get_guint8(
364 tvb,
365 GNUTELLA_HEADER_PAYLOAD_OFFSET);
367 switch(payload_descriptor) {
368 case GNUTELLA_PING:
369 payload_descriptor_text = GNUTELLA_PING_NAME;
370 break;
371 case GNUTELLA_PONG:
372 payload_descriptor_text = GNUTELLA_PONG_NAME;
373 break;
374 case GNUTELLA_PUSH:
375 payload_descriptor_text = GNUTELLA_PUSH_NAME;
376 break;
377 case GNUTELLA_QUERY:
378 payload_descriptor_text = GNUTELLA_QUERY_NAME;
379 break;
380 case GNUTELLA_QUERYHIT:
381 payload_descriptor_text = GNUTELLA_QUERYHIT_NAME;
382 break;
383 default:
384 payload_descriptor_text = GNUTELLA_UNKNOWN_NAME;
385 break;
388 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
389 payload_descriptor_text);
391 if (tree) {
392 hi = proto_tree_add_item(gnutella_tree,
393 hf_gnutella_header,
394 tvb,
396 GNUTELLA_HEADER_LENGTH,
397 ENC_NA);
398 gnutella_header_tree = proto_item_add_subtree(hi, ett_gnutella);
400 proto_tree_add_item(gnutella_header_tree,
401 hf_gnutella_header_id,
402 tvb,
403 GNUTELLA_HEADER_ID_OFFSET,
404 GNUTELLA_SERVENT_ID_LENGTH,
405 ENC_NA);
407 proto_tree_add_uint_format_value(gnutella_header_tree,
408 hf_gnutella_header_payload,
409 tvb,
410 GNUTELLA_HEADER_PAYLOAD_OFFSET,
411 GNUTELLA_BYTE_LENGTH,
412 payload_descriptor,
413 "%i (%s)",
414 payload_descriptor,
415 payload_descriptor_text);
417 proto_tree_add_item(gnutella_header_tree,
418 hf_gnutella_header_ttl,
419 tvb,
420 GNUTELLA_HEADER_TTL_OFFSET,
421 GNUTELLA_BYTE_LENGTH,
422 ENC_BIG_ENDIAN);
424 proto_tree_add_item(gnutella_header_tree,
425 hf_gnutella_header_hops,
426 tvb,
427 GNUTELLA_HEADER_HOPS_OFFSET,
428 GNUTELLA_BYTE_LENGTH,
429 ENC_BIG_ENDIAN);
431 proto_tree_add_uint(gnutella_header_tree,
432 hf_gnutella_header_size,
433 tvb,
434 GNUTELLA_HEADER_SIZE_OFFSET,
435 GNUTELLA_LONG_LENGTH,
436 size);
438 if (size > 0) {
439 switch(payload_descriptor) {
440 case GNUTELLA_PONG:
441 pi = proto_tree_add_item(
442 gnutella_header_tree,
443 hf_gnutella_pong_payload,
444 tvb,
445 GNUTELLA_HEADER_LENGTH,
446 size,
447 ENC_NA);
448 gnutella_pong_tree = proto_item_add_subtree(
450 ett_gnutella);
451 dissect_gnutella_pong(
452 tvb,
453 GNUTELLA_HEADER_LENGTH,
454 gnutella_pong_tree);
455 break;
456 case GNUTELLA_PUSH:
457 pi = proto_tree_add_item(
458 gnutella_header_tree,
459 hf_gnutella_push_payload,
460 tvb,
461 GNUTELLA_HEADER_LENGTH,
462 size,
463 ENC_NA);
464 gnutella_push_tree = proto_item_add_subtree(
466 ett_gnutella);
467 dissect_gnutella_push(
468 tvb,
469 GNUTELLA_HEADER_LENGTH,
470 gnutella_push_tree);
471 break;
472 case GNUTELLA_QUERY:
473 pi = proto_tree_add_item(
474 gnutella_header_tree,
475 hf_gnutella_query_payload,
476 tvb,
477 GNUTELLA_HEADER_LENGTH,
478 size,
479 ENC_NA);
480 gnutella_query_tree = proto_item_add_subtree(
482 ett_gnutella);
483 dissect_gnutella_query(
484 tvb,
485 GNUTELLA_HEADER_LENGTH,
486 gnutella_query_tree,
487 size);
488 break;
489 case GNUTELLA_QUERYHIT:
490 pi = proto_tree_add_item(
491 gnutella_header_tree,
492 hf_gnutella_queryhit_payload,
493 tvb,
494 GNUTELLA_HEADER_LENGTH,
495 size,
496 ENC_NA);
497 gnutella_queryhit_tree = proto_item_add_subtree(
499 ett_gnutella);
500 dissect_gnutella_queryhit(
501 tvb,
502 GNUTELLA_HEADER_LENGTH,
503 gnutella_queryhit_tree,
504 size);
505 break;
510 return tvb_length(tvb);
514 static int dissect_gnutella(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) {
516 proto_item *ti;
517 proto_tree *gnutella_tree = NULL;
518 guint32 size;
520 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gnutella");
522 col_clear(pinfo->cinfo, COL_INFO);
525 * OK, do we have enough data to determine whether this
526 * is Gnutella messages or just a transfer stream?
528 if (tvb_bytes_exist(tvb, GNUTELLA_HEADER_SIZE_OFFSET, 4)) {
530 * Yes - fetch the length and see if it's bigger
531 * than GNUTELLA_MAX_SNAP_SIZE; if it is, we assume
532 * it's a transfer stream.
534 * Should we also check the payload descriptor?
536 size = tvb_get_letohl(
537 tvb,
538 GNUTELLA_HEADER_SIZE_OFFSET);
539 if (size > GNUTELLA_MAX_SNAP_SIZE) {
540 if (tree) {
541 ti = proto_tree_add_item(tree,
542 proto_gnutella,
543 tvb,
546 ENC_NA);
547 gnutella_tree = proto_item_add_subtree(ti,
548 ett_gnutella);
550 proto_tree_add_item(gnutella_tree,
551 hf_gnutella_stream,
552 tvb,
555 ENC_NA);
557 return tvb_length(tvb);
561 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, GNUTELLA_HEADER_SIZE_OFFSET+4,
562 get_gnutella_pdu_len, dissect_gnutella_pdu, data);
563 return tvb_length(tvb);
566 void proto_register_gnutella(void) {
568 static hf_register_info hf[] = {
569 { &hf_gnutella_header,
570 { "Descriptor Header", "gnutella.header",
571 FT_NONE, BASE_NONE, NULL, 0,
572 "Gnutella Descriptor Header", HFILL }
574 { &hf_gnutella_pong_payload,
575 { "Pong", "gnutella.pong.payload",
576 FT_NONE, BASE_NONE, NULL, 0,
577 "Gnutella Pong Payload", HFILL }
579 { &hf_gnutella_push_payload,
580 { "Push", "gnutella.push.payload",
581 FT_NONE, BASE_NONE, NULL, 0,
582 "Gnutella Push Payload", HFILL }
584 { &hf_gnutella_query_payload,
585 { "Query", "gnutella.query.payload",
586 FT_NONE, BASE_NONE, NULL, 0,
587 "Gnutella Query Payload", HFILL }
589 { &hf_gnutella_queryhit_payload,
590 { "QueryHit", "gnutella.queryhit.payload",
591 FT_NONE, BASE_NONE, NULL, 0,
592 "Gnutella QueryHit Payload", HFILL }
594 { &hf_gnutella_stream,
595 { "Gnutella Upload / Download Stream", "gnutella.stream",
596 FT_NONE, BASE_NONE, NULL, 0,
597 NULL, HFILL }
599 { &hf_gnutella_header_id,
600 { "ID", "gnutella.header.id",
601 FT_BYTES, BASE_NONE, NULL, 0,
602 "Gnutella Descriptor ID", HFILL }
604 { &hf_gnutella_header_payload,
605 { "Payload", "gnutella.header.payload",
606 FT_UINT8, BASE_DEC, NULL, 0,
607 "Gnutella Descriptor Payload", HFILL }
609 { &hf_gnutella_header_ttl,
610 { "TTL", "gnutella.header.ttl",
611 FT_UINT8, BASE_DEC, NULL, 0,
612 "Gnutella Descriptor Time To Live", HFILL }
614 { &hf_gnutella_header_hops,
615 { "Hops", "gnutella.header.hops",
616 FT_UINT8, BASE_DEC, NULL, 0,
617 "Gnutella Descriptor Hop Count", HFILL }
619 { &hf_gnutella_header_size,
620 { "Length", "gnutella.header.size",
621 FT_UINT8, BASE_DEC, NULL, 0,
622 "Gnutella Descriptor Payload Length", HFILL }
624 { &hf_gnutella_pong_port,
625 { "Port", "gnutella.pong.port",
626 FT_UINT16, BASE_DEC, NULL, 0,
627 "Gnutella Pong TCP Port", HFILL }
629 { &hf_gnutella_pong_ip,
630 { "IP", "gnutella.pong.ip",
631 FT_IPv4, BASE_NONE, NULL, 0,
632 "Gnutella Pong IP Address", HFILL }
634 { &hf_gnutella_pong_files,
635 { "Files Shared", "gnutella.pong.files",
636 FT_UINT32, BASE_DEC, NULL, 0,
637 "Gnutella Pong Files Shared", HFILL }
639 { &hf_gnutella_pong_kbytes,
640 { "KBytes Shared", "gnutella.pong.kbytes",
641 FT_UINT32, BASE_DEC, NULL, 0,
642 "Gnutella Pong KBytes Shared", HFILL }
644 { &hf_gnutella_query_min_speed,
645 { "Min Speed", "gnutella.query.min_speed",
646 FT_UINT32, BASE_DEC, NULL, 0,
647 "Gnutella Query Minimum Speed", HFILL }
649 { &hf_gnutella_query_search,
650 { "Search", "gnutella.query.search",
651 FT_STRINGZ, BASE_NONE, NULL, 0,
652 "Gnutella Query Search", HFILL }
654 { &hf_gnutella_queryhit_hit,
655 { "Hit", "gnutella.queryhit.hit",
656 FT_NONE, BASE_NONE, NULL, 0,
657 "Gnutella QueryHit", HFILL }
659 { &hf_gnutella_queryhit_hit_index,
660 { "Index", "gnutella.queryhit.hit.index",
661 FT_UINT32, BASE_DEC, NULL, 0,
662 "Gnutella QueryHit Index", HFILL }
664 { &hf_gnutella_queryhit_hit_size,
665 { "Size", "gnutella.queryhit.hit.size",
666 FT_UINT32, BASE_DEC, NULL, 0,
667 "Gnutella QueryHit Size", HFILL }
669 { &hf_gnutella_queryhit_hit_name,
670 { "Name", "gnutella.queryhit.hit.name",
671 FT_STRING, BASE_NONE, NULL, 0,
672 "Gnutella Query Name", HFILL }
674 { &hf_gnutella_queryhit_hit_extra,
675 { "Extra", "gnutella.queryhit.hit.extra",
676 FT_BYTES, BASE_NONE, NULL, 0,
677 "Gnutella Query Extra", HFILL }
679 { &hf_gnutella_queryhit_count,
680 { "Count", "gnutella.queryhit.count",
681 FT_UINT8, BASE_DEC, NULL, 0,
682 "Gnutella QueryHit Count", HFILL }
684 { &hf_gnutella_queryhit_port,
685 { "Port", "gnutella.queryhit.port",
686 FT_UINT16, BASE_DEC, NULL, 0,
687 "Gnutella QueryHit Port", HFILL }
689 { &hf_gnutella_queryhit_ip,
690 { "IP", "gnutella.queryhit.ip",
691 FT_IPv4, BASE_NONE, NULL, 0,
692 "Gnutella QueryHit IP Address", HFILL }
694 { &hf_gnutella_queryhit_speed,
695 { "Speed", "gnutella.queryhit.speed",
696 FT_UINT32, BASE_DEC, NULL, 0,
697 "Gnutella QueryHit Speed", HFILL }
699 { &hf_gnutella_queryhit_extra,
700 { "Extra", "gnutella.queryhit.extra",
701 FT_BYTES, BASE_NONE, NULL, 0,
702 "Gnutella QueryHit Extra", HFILL }
704 { &hf_gnutella_queryhit_servent_id,
705 { "Servent ID", "gnutella.queryhit.servent_id",
706 FT_BYTES, BASE_NONE, NULL, 0,
707 "Gnutella QueryHit Servent ID", HFILL }
709 { &hf_gnutella_push_servent_id,
710 { "Servent ID", "gnutella.push.servent_id",
711 FT_BYTES, BASE_NONE, NULL, 0,
712 "Gnutella Push Servent ID", HFILL }
714 { &hf_gnutella_push_ip,
715 { "IP", "gnutella.push.ip",
716 FT_IPv4, BASE_NONE, NULL, 0,
717 "Gnutella Push IP Address", HFILL }
719 { &hf_gnutella_push_index,
720 { "Index", "gnutella.push.index",
721 FT_UINT32, BASE_DEC, NULL, 0,
722 "Gnutella Push Index", HFILL }
724 { &hf_gnutella_push_port,
725 { "Port", "gnutella.push.port",
726 FT_UINT16, BASE_DEC, NULL, 0,
727 "Gnutella Push Port", HFILL }
731 static gint *ett[] = {
732 &ett_gnutella,
735 proto_gnutella = proto_register_protocol("Gnutella Protocol",
736 "GNUTELLA",
737 "gnutella");
739 proto_register_field_array(proto_gnutella, hf, array_length(hf));
741 proto_register_subtree_array(ett, array_length(ett));
744 void proto_reg_handoff_gnutella(void) {
745 dissector_handle_t gnutella_handle;
747 gnutella_handle = new_create_dissector_handle(dissect_gnutella,
748 proto_gnutella);
749 dissector_add_uint("tcp.port", GNUTELLA_TCP_PORT, gnutella_handle);