2 * Routines for RX packet dissection
3 * Copyright 1999, Nathan Neulinger <nneul@umr.edu>
4 * Based on routines from tcpdump patches by
5 * Ken Hornstein <kenh@cmf.nrl.navy.mil>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from packet-tftp.c
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include "packet-rx.h"
35 #include <epan/addr_resolv.h>
40 * http://web.mit.edu/kolya/afs/rx/rx-spec
42 * XXX - is the "Epoch" really a UN*X time? The high-order bit, according
43 * to that spec, is a flag bit.
46 #define UDP_PORT_RX_LOW 7000
47 #define UDP_PORT_RX_HIGH 7009
48 #define UDP_PORT_RX_AFS_BACKUPS 7021
50 static const value_string rx_types
[] = {
51 { RX_PACKET_TYPE_DATA
, "data" },
52 { RX_PACKET_TYPE_ACK
, "ack" },
53 { RX_PACKET_TYPE_BUSY
, "busy" },
54 { RX_PACKET_TYPE_ABORT
, "abort" },
55 { RX_PACKET_TYPE_ACKALL
, "ackall" },
56 { RX_PACKET_TYPE_CHALLENGE
, "challenge" },
57 { RX_PACKET_TYPE_RESPONSE
, "response" },
58 { RX_PACKET_TYPE_DEBUG
, "debug" },
59 { RX_PACKET_TYPE_PARAMS
, "params" },
60 { RX_PACKET_TYPE_VERSION
, "version" },
64 static const value_string rx_reason
[] = {
65 { RX_ACK_REQUESTED
, "Ack Requested" },
66 { RX_ACK_DUPLICATE
, "Duplicate Packet" },
67 { RX_ACK_OUT_OF_SEQUENCE
, "Out Of Sequence" },
68 { RX_ACK_EXEEDS_WINDOW
, "Exceeds Window" },
69 { RX_ACK_NOSPACE
, "No Space" },
70 { RX_ACK_PING
, "Ping" },
71 { RX_ACK_PING_RESPONSE
, "Ping Response" },
72 { RX_ACK_DELAY
, "Delay" },
73 { RX_ACK_IDLE
, "Idle" },
77 static const value_string rx_ack_type
[] = {
78 { RX_ACK_TYPE_NACK
, "NACK" },
79 { RX_ACK_TYPE_ACK
, "ACK" },
83 static int proto_rx
= -1;
84 static int hf_rx_epoch
= -1;
85 static int hf_rx_cid
= -1;
86 static int hf_rx_seq
= -1;
87 static int hf_rx_serial
= -1;
88 static int hf_rx_callnumber
= -1;
89 static int hf_rx_type
= -1;
90 static int hf_rx_flags
= -1;
91 static int hf_rx_flags_clientinit
= -1;
92 static int hf_rx_flags_request_ack
= -1;
93 static int hf_rx_flags_last_packet
= -1;
94 static int hf_rx_flags_more_packets
= -1;
95 static int hf_rx_flags_free_packet
= -1;
96 static int hf_rx_userstatus
= -1;
97 static int hf_rx_securityindex
= -1;
98 static int hf_rx_spare
= -1;
99 static int hf_rx_serviceid
= -1;
100 static int hf_rx_bufferspace
= -1;
101 static int hf_rx_maxskew
= -1;
102 static int hf_rx_first_packet
= -1;
103 static int hf_rx_prev_packet
= -1;
104 static int hf_rx_reason
= -1;
105 static int hf_rx_numacks
= -1;
106 static int hf_rx_ack_type
= -1;
107 static int hf_rx_ack
= -1;
108 static int hf_rx_challenge
= -1;
109 static int hf_rx_version
= -1;
110 static int hf_rx_nonce
= -1;
111 static int hf_rx_inc_nonce
= -1;
112 static int hf_rx_min_level
= -1;
113 static int hf_rx_level
= -1;
114 static int hf_rx_response
= -1;
115 static int hf_rx_encrypted
= -1;
116 static int hf_rx_kvno
= -1;
117 static int hf_rx_ticket_len
= -1;
118 static int hf_rx_ticket
= -1;
119 static int hf_rx_ifmtu
= -1;
120 static int hf_rx_maxmtu
= -1;
121 static int hf_rx_rwind
= -1;
122 static int hf_rx_maxpackets
= -1;
123 static int hf_rx_abort
= -1;
124 static int hf_rx_abortcode
= -1;
126 static gint ett_rx
= -1;
127 static gint ett_rx_flags
= -1;
128 static gint ett_rx_ack
= -1;
129 static gint ett_rx_challenge
= -1;
130 static gint ett_rx_response
= -1;
131 static gint ett_rx_encrypted
= -1;
132 static gint ett_rx_abort
= -1;
134 static dissector_handle_t afs_handle
;
137 dissect_rx_response_encrypted(tvbuff_t
*tvb
, proto_tree
*parent_tree
, int offset
)
141 int old_offset
=offset
;
145 item
= proto_tree_add_item(parent_tree
, hf_rx_encrypted
, tvb
, offset
, -1, ENC_NA
);
146 tree
= proto_item_add_subtree(item
, ett_rx_encrypted
);
148 /* epoch : 4 bytes */
151 ts
.secs
= tvb_get_ntohl(tvb
, offset
);
154 proto_tree_add_time(tree
, hf_rx_epoch
, tvb
,
160 proto_tree_add_item(tree
, hf_rx_cid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
163 /*FIXME dont know how to handle this checksum, skipping it */
166 /* sequrityindex : 1 byte */
167 proto_tree_add_item(tree
, hf_rx_securityindex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
170 for (i
=0; i
<RX_MAXCALLS
; i
++) {
171 /* callnumber : 4 bytes */
172 callnumber
= tvb_get_ntohl(tvb
, offset
);
173 proto_tree_add_uint(tree
, hf_rx_callnumber
, tvb
,
174 offset
, 4, callnumber
);
178 /* inc nonce : 4 bytes */
179 proto_tree_add_item(tree
, hf_rx_inc_nonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
182 /* level : 4 bytes */
183 proto_tree_add_item(tree
, hf_rx_level
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
186 proto_item_set_len(item
, offset
-old_offset
);
192 dissect_rx_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, guint32 seq
, guint32 callnumber
)
197 int old_offset
=offset
;
199 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
204 "Destination Port: %s ",
206 (unsigned long)callnumber
,
207 get_udp_port(pinfo
->srcport
),
208 get_udp_port(pinfo
->destport
)
211 item
= proto_tree_add_item(parent_tree
, hf_rx_response
, tvb
, offset
, -1, ENC_NA
);
212 tree
= proto_item_add_subtree(item
, ett_rx_response
);
214 version
= tvb_get_ntohl(tvb
, offset
);
215 proto_tree_add_uint(tree
, hf_rx_version
, tvb
,
223 /* encrypted : struct */
224 offset
= dissect_rx_response_encrypted(tvb
, tree
, offset
);
227 proto_tree_add_item(tree
, hf_rx_kvno
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
231 tl
= tvb_get_ntohl(tvb
, offset
);
232 proto_tree_add_uint(tree
, hf_rx_ticket_len
, tvb
,
236 tvb_ensure_bytes_exist(tvb
, offset
, tl
);
237 proto_tree_add_item(tree
, hf_rx_ticket
, tvb
, offset
, tl
, ENC_NA
);
241 proto_item_set_len(item
, offset
-old_offset
);
246 dissect_rx_abort(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, guint32 seq
, guint32 callnumber
)
250 int old_offset
=offset
;
252 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
257 "Destination Port: %s ",
259 (unsigned long)callnumber
,
260 get_udp_port(pinfo
->srcport
),
261 get_udp_port(pinfo
->destport
)
264 item
= proto_tree_add_item(parent_tree
, hf_rx_abort
, tvb
, offset
, -1, ENC_NA
);
265 tree
= proto_item_add_subtree(item
, ett_rx_abort
);
268 proto_tree_add_item(tree
, hf_rx_abortcode
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
271 proto_item_set_len(item
, offset
-old_offset
);
277 dissect_rx_challenge(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, guint32 seq
, guint32 callnumber
)
282 int old_offset
=offset
;
284 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
289 "Destination Port: %s ",
291 (unsigned long)callnumber
,
292 get_udp_port(pinfo
->srcport
),
293 get_udp_port(pinfo
->destport
)
296 item
= proto_tree_add_item(parent_tree
, hf_rx_challenge
, tvb
, offset
, -1, ENC_NA
);
297 tree
= proto_item_add_subtree(item
, ett_rx_challenge
);
299 version
= tvb_get_ntohl(tvb
, offset
);
300 proto_tree_add_uint(tree
, hf_rx_version
, tvb
,
305 proto_tree_add_item(tree
, hf_rx_nonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
308 proto_tree_add_item(tree
, hf_rx_min_level
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
312 proto_item_set_len(item
, offset
-old_offset
);
317 dissect_rx_acks(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, guint32 seq
, guint32 callnumber
)
322 int old_offset
= offset
;
324 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
329 "Destination Port: %s ",
331 (unsigned long)callnumber
,
332 get_udp_port(pinfo
->srcport
),
333 get_udp_port(pinfo
->destport
)
336 item
= proto_tree_add_item(parent_tree
, hf_rx_ack
, tvb
, offset
, -1, ENC_NA
);
337 tree
= proto_item_add_subtree(item
, ett_rx_ack
);
340 /* bufferspace: 2 bytes*/
341 proto_tree_add_item(tree
, hf_rx_bufferspace
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
344 /* maxskew: 2 bytes*/
345 proto_tree_add_item(tree
, hf_rx_maxskew
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
348 /* first packet: 4 bytes*/
349 proto_tree_add_item(tree
, hf_rx_first_packet
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
352 /* prev packet: 4 bytes*/
353 proto_tree_add_item(tree
, hf_rx_prev_packet
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
356 /* serial : 4 bytes */
357 proto_tree_add_item(tree
, hf_rx_serial
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
360 /* reason : 1 byte */
361 proto_tree_add_item(tree
, hf_rx_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
365 num
= tvb_get_guint8(tvb
, offset
);
366 proto_tree_add_uint(tree
, hf_rx_numacks
, tvb
, offset
, 1, num
);
370 proto_tree_add_item(tree
, hf_rx_ack_type
, tvb
, offset
, 1,
375 /* Some implementations adds some extra fields.
376 * As far as I can see, these first add 3 padding bytes and then
377 * up to 4 32-bit values. (0,3,4 have been witnessed)
379 * RX as a protocol seems to be completely nondefined and seems to lack
380 * any sort of documentation other than "read the source of any of the
381 * (compatible?) implementations.
383 if (tvb_length_remaining(tvb
, offset
)>3) {
384 offset
+= 3; /* guess. some implementations adds 3 bytes */
386 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
387 proto_tree_add_item(tree
, hf_rx_ifmtu
, tvb
, offset
, 4,
391 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
392 proto_tree_add_item(tree
, hf_rx_maxmtu
, tvb
, offset
, 4,
396 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
397 proto_tree_add_item(tree
, hf_rx_rwind
, tvb
, offset
, 4,
401 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
402 proto_tree_add_item(tree
, hf_rx_maxpackets
, tvb
, offset
, 4,
408 proto_item_set_len(item
, offset
-old_offset
);
414 dissect_rx_flags(tvbuff_t
*tvb
, struct rxinfo
*rxinfo
, proto_tree
*parent_tree
, int offset
)
420 flags
= tvb_get_guint8(tvb
, offset
);
421 rxinfo
->flags
= flags
;
423 item
= proto_tree_add_uint(parent_tree
, hf_rx_flags
, tvb
,
425 tree
= proto_item_add_subtree(item
, ett_rx_flags
);
427 proto_tree_add_boolean(tree
, hf_rx_flags_free_packet
, tvb
,
429 proto_tree_add_boolean(tree
, hf_rx_flags_more_packets
, tvb
,
431 proto_tree_add_boolean(tree
, hf_rx_flags_last_packet
, tvb
,
433 proto_tree_add_boolean(tree
, hf_rx_flags_request_ack
, tvb
,
435 proto_tree_add_boolean(tree
, hf_rx_flags_clientinit
, tvb
,
443 dissect_rx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void *data _U_
)
448 struct rxinfo rxinfo
;
451 guint32 seq
, callnumber
;
454 /* Ensure we have enough data */
455 if (tvb_length(tvb
) < 28)
458 /* Make sure it's a known type */
459 type
= tvb_get_guint8(tvb
, 20);
460 if (type
== 0 || type
== 10 || type
== 11 || type
== 12 || type
> 13)
463 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RX");
464 col_clear(pinfo
->cinfo
, COL_INFO
);
466 item
= proto_tree_add_protocol_format(parent_tree
, proto_rx
, tvb
,
467 offset
, 28, "RX Protocol");
468 tree
= proto_item_add_subtree(item
, ett_rx
);
470 /* epoch : 4 bytes */
471 rxinfo
.epoch
= tvb_get_ntohl(tvb
, offset
);
472 ts
.secs
= rxinfo
.epoch
;
474 proto_tree_add_time(tree
, hf_rx_epoch
, tvb
, offset
, 4, &ts
);
478 rxinfo
.cid
= tvb_get_ntohl(tvb
, offset
);
479 proto_tree_add_item(tree
, hf_rx_cid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
482 /* callnumber : 4 bytes */
483 callnumber
= tvb_get_ntohl(tvb
, offset
);
484 proto_tree_add_uint(tree
, hf_rx_callnumber
, tvb
,
485 offset
, 4, callnumber
);
487 rxinfo
.callnumber
= callnumber
;
490 seq
= tvb_get_ntohl(tvb
, offset
);
491 proto_tree_add_uint(tree
, hf_rx_seq
, tvb
,
496 /* serial : 4 bytes */
497 proto_tree_add_item(tree
, hf_rx_serial
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
501 type
= tvb_get_guint8(tvb
, offset
);
502 proto_tree_add_uint(tree
, hf_rx_type
, tvb
,
508 offset
= dissect_rx_flags(tvb
, &rxinfo
, tree
, offset
);
510 /* userstatus : 1 byte */
511 proto_tree_add_item(tree
, hf_rx_userstatus
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
514 /* sequrityindex : 1 byte */
515 proto_tree_add_item(tree
, hf_rx_securityindex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
519 * How clever: even though the AFS header files indicate that the
520 * serviceId is first, it's really encoded _after_ the spare field.
521 * I wasted a day figuring that out!
525 proto_tree_add_item(tree
, hf_rx_spare
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
528 /* service id : 2 bytes */
529 serviceid
= tvb_get_ntohs(tvb
, offset
);
530 proto_tree_add_uint(tree
, hf_rx_serviceid
, tvb
,
531 offset
, 2, serviceid
);
533 rxinfo
.serviceid
= serviceid
;
536 case RX_PACKET_TYPE_ACK
:
537 /*dissect_rx_acks(tvb, pinfo, parent_tree, offset,
538 cant create it in a parallell tree, then ett seasrch
540 dissect_rx_acks(tvb
, pinfo
, tree
, offset
,
543 case RX_PACKET_TYPE_ACKALL
:
544 /* does not contain any payload */
545 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
550 "Destination Port: %s ",
552 (unsigned long)callnumber
,
553 get_udp_port(pinfo
->srcport
),
554 get_udp_port(pinfo
->destport
)
557 case RX_PACKET_TYPE_CHALLENGE
:
558 dissect_rx_challenge(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
560 case RX_PACKET_TYPE_RESPONSE
:
561 dissect_rx_response(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
563 case RX_PACKET_TYPE_DATA
: {
566 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
567 call_dissector_with_data(afs_handle
, next_tvb
, pinfo
, parent_tree
, &rxinfo
);
570 case RX_PACKET_TYPE_ABORT
:
571 dissect_rx_abort(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
575 return(tvb_length(tvb
));
579 proto_register_rx(void)
581 static hf_register_info hf
[] = {
583 "Epoch", "rx.epoch", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
584 NULL
, 0, NULL
, HFILL
}},
587 "CID", "rx.cid", FT_UINT32
, BASE_DEC
,
588 NULL
, 0, NULL
, HFILL
}},
590 { &hf_rx_callnumber
, {
591 "Call Number", "rx.callnumber", FT_UINT32
, BASE_DEC
,
592 NULL
, 0, NULL
, HFILL
}},
595 "Sequence Number", "rx.seq", FT_UINT32
, BASE_DEC
,
596 NULL
, 0, NULL
, HFILL
}},
599 "Serial", "rx.serial", FT_UINT32
, BASE_DEC
,
600 NULL
, 0, NULL
, HFILL
}},
603 "Type", "rx.type", FT_UINT8
, BASE_DEC
,
604 VALS(rx_types
), 0, NULL
, HFILL
}},
607 "Flags", "rx.flags", FT_UINT8
, BASE_HEX
,
608 NULL
, 0, NULL
, HFILL
}},
610 { &hf_rx_flags_clientinit
, {
611 "Client Initiated", "rx.flags.client_init", FT_BOOLEAN
, 8,
612 NULL
, RX_CLIENT_INITIATED
, NULL
, HFILL
}},
614 { &hf_rx_flags_request_ack
, {
615 "Request Ack", "rx.flags.request_ack", FT_BOOLEAN
, 8,
616 NULL
, RX_REQUEST_ACK
, NULL
, HFILL
}},
618 { &hf_rx_flags_last_packet
, {
619 "Last Packet", "rx.flags.last_packet", FT_BOOLEAN
, 8,
620 NULL
, RX_LAST_PACKET
, NULL
, HFILL
}},
622 { &hf_rx_flags_more_packets
, {
623 "More Packets", "rx.flags.more_packets", FT_BOOLEAN
, 8,
624 NULL
, RX_MORE_PACKETS
, NULL
, HFILL
}},
626 { &hf_rx_flags_free_packet
, {
627 "Free Packet", "rx.flags.free_packet", FT_BOOLEAN
, 8,
628 NULL
, RX_FREE_PACKET
, NULL
, HFILL
}},
630 /* XXX - what about RX_SLOW_START_OR_JUMBO? */
632 { &hf_rx_userstatus
, {
633 "User Status", "rx.userstatus", FT_UINT32
, BASE_DEC
,
634 NULL
, 0, NULL
, HFILL
}},
636 { &hf_rx_securityindex
, {
637 "Security Index", "rx.securityindex", FT_UINT32
, BASE_DEC
,
638 NULL
, 0, NULL
, HFILL
}},
641 "Spare/Checksum", "rx.spare", FT_UINT16
, BASE_DEC
,
642 NULL
, 0, NULL
, HFILL
}},
644 { &hf_rx_serviceid
, {
645 "Service ID", "rx.serviceid", FT_UINT16
, BASE_DEC
,
646 NULL
, 0, NULL
, HFILL
}},
648 { &hf_rx_bufferspace
, {
649 "Bufferspace", "rx.bufferspace", FT_UINT16
, BASE_DEC
,
650 NULL
, 0, "Number Of Packets Available", HFILL
}},
653 "Max Skew", "rx.maxskew", FT_UINT16
, BASE_DEC
,
654 NULL
, 0, NULL
, HFILL
}},
656 { &hf_rx_first_packet
, {
657 "First Packet", "rx.first", FT_UINT32
, BASE_DEC
,
658 NULL
, 0, NULL
, HFILL
}},
660 { &hf_rx_prev_packet
, {
661 "Prev Packet", "rx.prev", FT_UINT32
, BASE_DEC
,
662 NULL
, 0, "Previous Packet", HFILL
}},
665 "Reason", "rx.reason", FT_UINT8
, BASE_DEC
,
666 VALS(rx_reason
), 0, "Reason For This ACK", HFILL
}},
669 "Num ACKs", "rx.num_acks", FT_UINT8
, BASE_DEC
,
670 NULL
, 0, "Number Of ACKs", HFILL
}},
673 "ACK Type", "rx.ack_type", FT_UINT8
, BASE_DEC
,
674 VALS(rx_ack_type
), 0, "Type Of ACKs", HFILL
}},
677 "ACK Packet", "rx.ack", FT_NONE
, BASE_NONE
,
678 NULL
, 0, NULL
, HFILL
}},
680 { &hf_rx_challenge
, {
681 "CHALLENGE Packet", "rx.challenge", FT_NONE
, BASE_NONE
,
682 NULL
, 0, NULL
, HFILL
}},
685 "Version", "rx.version", FT_UINT32
, BASE_DEC
,
686 NULL
, 0, "Version Of Challenge/Response", HFILL
}},
689 "Nonce", "rx.nonce", FT_UINT32
, BASE_HEX
,
690 NULL
, 0, NULL
, HFILL
}},
692 { &hf_rx_inc_nonce
, {
693 "Inc Nonce", "rx.inc_nonce", FT_UINT32
, BASE_HEX
,
694 NULL
, 0, "Incremented Nonce", HFILL
}},
696 { &hf_rx_min_level
, {
697 "Min Level", "rx.min_level", FT_UINT32
, BASE_DEC
,
698 NULL
, 0, NULL
, HFILL
}},
701 "Level", "rx.level", FT_UINT32
, BASE_DEC
,
702 NULL
, 0, NULL
, HFILL
}},
705 "RESPONSE Packet", "rx.response", FT_NONE
, BASE_NONE
,
706 NULL
, 0, NULL
, HFILL
}},
709 "ABORT Packet", "rx.abort", FT_NONE
, BASE_NONE
,
710 NULL
, 0, NULL
, HFILL
}},
712 { &hf_rx_encrypted
, {
713 "Encrypted", "rx.encrypted", FT_NONE
, BASE_NONE
,
714 NULL
, 0, "Encrypted part of response packet", HFILL
}},
717 "kvno", "rx.kvno", FT_UINT32
, BASE_DEC
,
718 NULL
, 0, NULL
, HFILL
}},
720 { &hf_rx_ticket_len
, {
721 "Ticket len", "rx.ticket_len", FT_UINT32
, BASE_DEC
,
722 NULL
, 0, "Ticket Length", HFILL
}},
725 "ticket", "rx.ticket", FT_BYTES
, BASE_NONE
,
726 NULL
, 0, NULL
, HFILL
}},
729 "Interface MTU", "rx.if_mtu", FT_UINT32
, BASE_DEC
,
730 NULL
, 0, NULL
, HFILL
}},
733 "Max MTU", "rx.max_mtu", FT_UINT32
, BASE_DEC
,
734 NULL
, 0, NULL
, HFILL
}},
737 "rwind", "rx.rwind", FT_UINT32
, BASE_DEC
,
738 NULL
, 0, NULL
, HFILL
}},
740 { &hf_rx_maxpackets
, {
741 "Max Packets", "rx.max_packets", FT_UINT32
, BASE_DEC
,
742 NULL
, 0, NULL
, HFILL
}},
744 { &hf_rx_abortcode
, {
745 "Abort Code", "rx.abort_code", FT_UINT32
, BASE_DEC
,
746 NULL
, 0, NULL
, HFILL
}},
749 static gint
*ett
[] = {
759 proto_rx
= proto_register_protocol("RX Protocol", "RX", "rx");
760 proto_register_field_array(proto_rx
, hf
, array_length(hf
));
761 proto_register_subtree_array(ett
, array_length(ett
));
765 proto_reg_handoff_rx(void)
767 dissector_handle_t rx_handle
;
772 * Get handle for the AFS dissector.
774 afs_handle
= find_dissector("afs");
776 /* Ports in the range UDP_PORT_RX_LOW to UDP_PORT_RX_HIGH
777 are all used for various AFS services. */
778 rx_handle
= new_create_dissector_handle(dissect_rx
, proto_rx
);
779 for (port
= UDP_PORT_RX_LOW
; port
<= UDP_PORT_RX_HIGH
; port
++)
780 dissector_add_uint("udp.port", port
, rx_handle
);
781 dissector_add_uint("udp.port", UDP_PORT_RX_AFS_BACKUPS
, rx_handle
);