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>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-tftp.c
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include "packet-rx.h"
20 #include <epan/addr_resolv.h>
25 * http://web.mit.edu/kolya/afs/rx/rx-spec
27 * XXX - is the "Epoch" really a UN*X time? The high-order bit, according
28 * to that spec, is a flag bit.
30 void proto_register_rx(void);
31 void proto_reg_handoff_rx(void);
33 static dissector_handle_t rx_handle
;
35 #define UDP_PORT_RX_RANGE "7000-7009,7021"
37 static const value_string rx_types
[] = {
38 { RX_PACKET_TYPE_DATA
, "data" },
39 { RX_PACKET_TYPE_ACK
, "ack" },
40 { RX_PACKET_TYPE_BUSY
, "busy" },
41 { RX_PACKET_TYPE_ABORT
, "abort" },
42 { RX_PACKET_TYPE_ACKALL
, "ackall" },
43 { RX_PACKET_TYPE_CHALLENGE
, "challenge" },
44 { RX_PACKET_TYPE_RESPONSE
, "response" },
45 { RX_PACKET_TYPE_DEBUG
, "debug" },
46 { RX_PACKET_TYPE_PARAMS
, "params" },
47 { RX_PACKET_TYPE_VERSION
, "version" },
51 static const value_string rx_reason
[] = {
52 { RX_ACK_REQUESTED
, "Ack Requested" },
53 { RX_ACK_DUPLICATE
, "Duplicate Packet" },
54 { RX_ACK_OUT_OF_SEQUENCE
, "Out Of Sequence" },
55 { RX_ACK_EXEEDS_WINDOW
, "Exceeds Window" },
56 { RX_ACK_NOSPACE
, "No Space" },
57 { RX_ACK_PING
, "Ping" },
58 { RX_ACK_PING_RESPONSE
, "Ping Response" },
59 { RX_ACK_DELAY
, "Delay" },
60 { RX_ACK_IDLE
, "Idle" },
64 static const value_string rx_ack_type
[] = {
65 { RX_ACK_TYPE_NACK
, "NACK" },
66 { RX_ACK_TYPE_ACK
, "ACK" },
71 static int hf_rx_epoch
;
74 static int hf_rx_serial
;
75 static int hf_rx_callnumber
;
76 static int hf_rx_type
;
77 static int hf_rx_flags
;
78 static int hf_rx_flags_clientinit
;
79 static int hf_rx_flags_request_ack
;
80 static int hf_rx_flags_last_packet
;
81 static int hf_rx_flags_more_packets
;
82 static int hf_rx_flags_free_packet
;
83 static int hf_rx_userstatus
;
84 static int hf_rx_securityindex
;
85 static int hf_rx_spare
;
86 static int hf_rx_serviceid
;
87 static int hf_rx_bufferspace
;
88 static int hf_rx_maxskew
;
89 static int hf_rx_first_packet
;
90 static int hf_rx_prev_packet
;
91 static int hf_rx_reason
;
92 static int hf_rx_numacks
;
93 static int hf_rx_ack_type
;
95 static int hf_rx_challenge
;
96 static int hf_rx_version
;
97 static int hf_rx_nonce
;
98 static int hf_rx_inc_nonce
;
99 static int hf_rx_min_level
;
100 static int hf_rx_level
;
101 static int hf_rx_response
;
102 static int hf_rx_encrypted
;
103 static int hf_rx_kvno
;
104 static int hf_rx_ticket_len
;
105 static int hf_rx_ticket
;
106 static int hf_rx_ifmtu
;
107 static int hf_rx_maxmtu
;
108 static int hf_rx_rwind
;
109 static int hf_rx_maxpackets
;
110 static int hf_rx_abort
;
111 static int hf_rx_abortcode
;
114 static int ett_rx_flags
;
115 static int ett_rx_ack
;
116 static int ett_rx_challenge
;
117 static int ett_rx_response
;
118 static int ett_rx_encrypted
;
119 static int ett_rx_abort
;
121 static dissector_handle_t afs_handle
;
124 dissect_rx_response_encrypted(tvbuff_t
*tvb
, proto_tree
*parent_tree
, int offset
)
128 int old_offset
=offset
;
132 item
= proto_tree_add_item(parent_tree
, hf_rx_encrypted
, tvb
, offset
, -1, ENC_NA
);
133 tree
= proto_item_add_subtree(item
, ett_rx_encrypted
);
135 /* epoch : 4 bytes */
136 proto_tree_add_item(tree
, hf_rx_epoch
, tvb
, offset
, 4, ENC_TIME_SECS
|ENC_BIG_ENDIAN
);
140 proto_tree_add_item(tree
, hf_rx_cid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
143 /*FIXME don't know how to handle this checksum, skipping it */
146 /* securityindex : 1 byte */
147 proto_tree_add_item(tree
, hf_rx_securityindex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
150 for (i
=0; i
<RX_MAXCALLS
; i
++) {
151 /* callnumber : 4 bytes */
152 callnumber
= tvb_get_ntohl(tvb
, offset
);
153 proto_tree_add_uint(tree
, hf_rx_callnumber
, tvb
,
154 offset
, 4, callnumber
);
158 /* inc nonce : 4 bytes */
159 proto_tree_add_item(tree
, hf_rx_inc_nonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
162 /* level : 4 bytes */
163 proto_tree_add_item(tree
, hf_rx_level
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
166 proto_item_set_len(item
, offset
-old_offset
);
172 dissect_rx_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, uint32_t seq
, uint32_t callnumber
)
176 uint32_t version
, tl
;
177 int old_offset
=offset
;
179 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
180 "RESPONSE Seq: %lu Call: %lu Source Port: %s Destination Port: %s ",
182 (unsigned long)callnumber
,
183 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
184 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
187 item
= proto_tree_add_item(parent_tree
, hf_rx_response
, tvb
, offset
, -1, ENC_NA
);
188 tree
= proto_item_add_subtree(item
, ett_rx_response
);
190 version
= tvb_get_ntohl(tvb
, offset
);
191 proto_tree_add_uint(tree
, hf_rx_version
, tvb
,
199 /* encrypted : struct */
200 offset
= dissect_rx_response_encrypted(tvb
, tree
, offset
);
203 proto_tree_add_item(tree
, hf_rx_kvno
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
207 tl
= tvb_get_ntohl(tvb
, offset
);
208 proto_tree_add_uint(tree
, hf_rx_ticket_len
, tvb
,
212 proto_tree_add_item(tree
, hf_rx_ticket
, tvb
, offset
, tl
, ENC_NA
);
216 proto_item_set_len(item
, offset
-old_offset
);
221 dissect_rx_abort(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, uint32_t seq
, uint32_t callnumber
)
225 int old_offset
=offset
;
227 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
228 "ABORT Seq: %lu Call: %lu Source Port: %s Destination Port: %s ",
230 (unsigned long)callnumber
,
231 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
232 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
235 item
= proto_tree_add_item(parent_tree
, hf_rx_abort
, tvb
, offset
, -1, ENC_NA
);
236 tree
= proto_item_add_subtree(item
, ett_rx_abort
);
239 proto_tree_add_item(tree
, hf_rx_abortcode
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
242 proto_item_set_len(item
, offset
-old_offset
);
248 dissect_rx_challenge(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, uint32_t seq
, uint32_t callnumber
)
253 int old_offset
=offset
;
255 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
256 "CHALLENGE Seq: %lu Call: %lu Source Port: %s Destination Port: %s ",
258 (unsigned long)callnumber
,
259 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
260 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
263 item
= proto_tree_add_item(parent_tree
, hf_rx_challenge
, tvb
, offset
, -1, ENC_NA
);
264 tree
= proto_item_add_subtree(item
, ett_rx_challenge
);
266 version
= tvb_get_ntohl(tvb
, offset
);
267 proto_tree_add_uint(tree
, hf_rx_version
, tvb
,
272 proto_tree_add_item(tree
, hf_rx_nonce
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
275 proto_tree_add_item(tree
, hf_rx_min_level
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
279 proto_item_set_len(item
, offset
-old_offset
);
284 dissect_rx_acks(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, int offset
, uint32_t seq
, uint32_t callnumber
)
289 int old_offset
= offset
;
293 item
= proto_tree_add_item(parent_tree
, hf_rx_ack
, tvb
, offset
, -1, ENC_NA
);
294 tree
= proto_item_add_subtree(item
, ett_rx_ack
);
297 /* bufferspace: 2 bytes*/
298 proto_tree_add_item(tree
, hf_rx_bufferspace
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
301 /* maxskew: 2 bytes*/
302 proto_tree_add_item(tree
, hf_rx_maxskew
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
305 /* first packet: 4 bytes*/
306 proto_tree_add_item(tree
, hf_rx_first_packet
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
309 /* prev packet: 4 bytes*/
310 proto_tree_add_item(tree
, hf_rx_prev_packet
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
313 /* serial : 4 bytes */
314 proto_tree_add_item(tree
, hf_rx_serial
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
317 /* reason : 1 byte */
318 reason
= tvb_get_uint8(tvb
, offset
);
319 proto_tree_add_item(tree
, hf_rx_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
323 num
= tvb_get_uint8(tvb
, offset
);
324 proto_tree_add_uint(tree
, hf_rx_numacks
, tvb
, offset
, 1, num
);
328 proto_tree_add_item(tree
, hf_rx_ack_type
, tvb
, offset
, 1,
333 /* Some implementations add some extra fields.
334 * As far as I can see, these first add 3 padding bytes and then
335 * up to 4 32-bit values. (0,3,4 have been witnessed)
337 * RX as a protocol seems to be completely undefined and seems to lack
338 * any sort of documentation other than "read the source of any of the
339 * (compatible?) implementations. The OpenAFS source indicates that
340 * 3 bytes of padding are written after the acks.
342 if (tvb_reported_length_remaining(tvb
, offset
)>3) {
343 offset
+= 3; /* guess. some implementations add 3 bytes */
345 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
346 proto_tree_add_item(tree
, hf_rx_maxmtu
, tvb
, offset
, 4,
350 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
351 proto_tree_add_item(tree
, hf_rx_ifmtu
, tvb
, offset
, 4,
355 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
356 proto_tree_add_item(tree
, hf_rx_rwind
, tvb
, offset
, 4,
360 if (tvb_reported_length_remaining(tvb
, offset
) >= 4){
361 proto_tree_add_item(tree
, hf_rx_maxpackets
, tvb
, offset
, 4,
367 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
372 "Destination Port: %s ",
373 val_to_str(reason
, rx_reason
, "%d"),
375 (unsigned long)callnumber
,
376 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
377 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
380 proto_item_set_len(item
, offset
-old_offset
);
386 dissect_rx_flags(tvbuff_t
*tvb
, struct rxinfo
*rxinfo
, proto_tree
*parent_tree
, int offset
)
388 static int * const flags
[] = {
389 &hf_rx_flags_free_packet
,
390 &hf_rx_flags_more_packets
,
391 &hf_rx_flags_last_packet
,
392 &hf_rx_flags_request_ack
,
393 &hf_rx_flags_clientinit
,
397 rxinfo
->flags
= tvb_get_uint8(tvb
, offset
);
399 proto_tree_add_bitmask(parent_tree
, tvb
, offset
, hf_rx_flags
, ett_rx_flags
, flags
, ENC_NA
);
406 dissect_rx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void *data _U_
)
410 const char *version_type
;
412 struct rxinfo rxinfo
;
415 uint32_t seq
, callnumber
;
418 /* Ensure we have enough data */
419 if (tvb_captured_length(tvb
) < 28)
422 /* Make sure it's a known type */
423 type
= tvb_get_uint8(tvb
, 20);
424 if (!try_val_to_str(type
, rx_types
))
427 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RX");
428 col_clear(pinfo
->cinfo
, COL_INFO
);
430 item
= proto_tree_add_protocol_format(parent_tree
, proto_rx
, tvb
,
431 offset
, 28, "RX Protocol");
432 tree
= proto_item_add_subtree(item
, ett_rx
);
434 /* epoch : 4 bytes */
435 rxinfo
.epoch
= tvb_get_ntohl(tvb
, offset
);
436 ts
.secs
= rxinfo
.epoch
;
438 proto_tree_add_time(tree
, hf_rx_epoch
, tvb
, offset
, 4, &ts
);
442 rxinfo
.cid
= tvb_get_ntohl(tvb
, offset
);
443 proto_tree_add_item(tree
, hf_rx_cid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
446 /* callnumber : 4 bytes */
447 callnumber
= tvb_get_ntohl(tvb
, offset
);
448 proto_tree_add_uint(tree
, hf_rx_callnumber
, tvb
,
449 offset
, 4, callnumber
);
451 rxinfo
.callnumber
= callnumber
;
454 seq
= tvb_get_ntohl(tvb
, offset
);
455 proto_tree_add_uint(tree
, hf_rx_seq
, tvb
,
460 /* serial : 4 bytes */
461 proto_tree_add_item(tree
, hf_rx_serial
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
465 type
= tvb_get_uint8(tvb
, offset
);
466 proto_tree_add_uint(tree
, hf_rx_type
, tvb
,
472 offset
= dissect_rx_flags(tvb
, &rxinfo
, tree
, offset
);
474 /* userstatus : 1 byte */
475 proto_tree_add_item(tree
, hf_rx_userstatus
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
478 /* securityindex : 1 byte */
479 proto_tree_add_item(tree
, hf_rx_securityindex
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
483 * How clever: even though the AFS header files indicate that the
484 * serviceId is first, it's really encoded _after_ the spare field.
485 * I wasted a day figuring that out!
489 proto_tree_add_item(tree
, hf_rx_spare
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
492 /* service id : 2 bytes */
493 serviceid
= tvb_get_ntohs(tvb
, offset
);
494 proto_tree_add_uint(tree
, hf_rx_serviceid
, tvb
,
495 offset
, 2, serviceid
);
497 rxinfo
.serviceid
= serviceid
;
500 case RX_PACKET_TYPE_ACK
:
501 /*dissect_rx_acks(tvb, pinfo, parent_tree, offset,
502 can't create it in a parallel tree, then ett search
504 dissect_rx_acks(tvb
, pinfo
, tree
, offset
,
507 case RX_PACKET_TYPE_ACKALL
:
508 /* does not contain any payload */
509 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
510 "ACKALL Seq: %lu Call: %lu Source Port: %s Destination Port: %s ",
512 (unsigned long)callnumber
,
513 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
514 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
517 case RX_PACKET_TYPE_VERSION
:
518 /* does not contain any payload */
520 version_type
= "NAT ping";
522 version_type
= "request";
524 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
525 "VERSION %s Seq: %lu Call: %lu Source Port: %s Destination Port: %s ",
528 (unsigned long)callnumber
,
529 udp_port_to_display(pinfo
->pool
, pinfo
->srcport
),
530 udp_port_to_display(pinfo
->pool
, pinfo
->destport
)
533 case RX_PACKET_TYPE_CHALLENGE
:
534 dissect_rx_challenge(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
536 case RX_PACKET_TYPE_RESPONSE
:
537 dissect_rx_response(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
539 case RX_PACKET_TYPE_DATA
: {
542 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
543 call_dissector_with_data(afs_handle
, next_tvb
, pinfo
, parent_tree
, &rxinfo
);
546 case RX_PACKET_TYPE_ABORT
:
547 dissect_rx_abort(tvb
, pinfo
, tree
, offset
, seq
, callnumber
);
551 return tvb_captured_length(tvb
);
555 proto_register_rx(void)
557 static hf_register_info hf
[] = {
559 "Epoch", "rx.epoch", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
560 NULL
, 0, NULL
, HFILL
}},
563 "CID", "rx.cid", FT_UINT32
, BASE_DEC
,
564 NULL
, 0, NULL
, HFILL
}},
566 { &hf_rx_callnumber
, {
567 "Call Number", "rx.callnumber", FT_UINT32
, BASE_DEC
,
568 NULL
, 0, NULL
, HFILL
}},
571 "Sequence Number", "rx.seq", FT_UINT32
, BASE_DEC
,
572 NULL
, 0, NULL
, HFILL
}},
575 "Serial", "rx.serial", FT_UINT32
, BASE_DEC
,
576 NULL
, 0, NULL
, HFILL
}},
579 "Type", "rx.type", FT_UINT8
, BASE_DEC
,
580 VALS(rx_types
), 0, NULL
, HFILL
}},
583 "Flags", "rx.flags", FT_UINT8
, BASE_HEX
,
584 NULL
, 0, NULL
, HFILL
}},
586 { &hf_rx_flags_clientinit
, {
587 "Client Initiated", "rx.flags.client_init", FT_BOOLEAN
, 8,
588 NULL
, RX_CLIENT_INITIATED
, NULL
, HFILL
}},
590 { &hf_rx_flags_request_ack
, {
591 "Request Ack", "rx.flags.request_ack", FT_BOOLEAN
, 8,
592 NULL
, RX_REQUEST_ACK
, NULL
, HFILL
}},
594 { &hf_rx_flags_last_packet
, {
595 "Last Packet", "rx.flags.last_packet", FT_BOOLEAN
, 8,
596 NULL
, RX_LAST_PACKET
, NULL
, HFILL
}},
598 { &hf_rx_flags_more_packets
, {
599 "More Packets", "rx.flags.more_packets", FT_BOOLEAN
, 8,
600 NULL
, RX_MORE_PACKETS
, NULL
, HFILL
}},
602 { &hf_rx_flags_free_packet
, {
603 "Free Packet", "rx.flags.free_packet", FT_BOOLEAN
, 8,
604 NULL
, RX_FREE_PACKET
, NULL
, HFILL
}},
606 /* XXX - what about RX_SLOW_START_OR_JUMBO? */
608 { &hf_rx_userstatus
, {
609 "User Status", "rx.userstatus", FT_UINT32
, BASE_DEC
,
610 NULL
, 0, NULL
, HFILL
}},
612 { &hf_rx_securityindex
, {
613 "Security Index", "rx.securityindex", FT_UINT32
, BASE_DEC
,
614 NULL
, 0, NULL
, HFILL
}},
617 "Spare/Checksum", "rx.spare", FT_UINT16
, BASE_DEC
,
618 NULL
, 0, NULL
, HFILL
}},
620 { &hf_rx_serviceid
, {
621 "Service ID", "rx.serviceid", FT_UINT16
, BASE_DEC
,
622 NULL
, 0, NULL
, HFILL
}},
624 { &hf_rx_bufferspace
, {
625 "Bufferspace", "rx.bufferspace", FT_UINT16
, BASE_DEC
,
626 NULL
, 0, "Number Of Packets Available", HFILL
}},
629 "Max Skew", "rx.maxskew", FT_UINT16
, BASE_DEC
,
630 NULL
, 0, NULL
, HFILL
}},
632 { &hf_rx_first_packet
, {
633 "First Packet", "rx.first", FT_UINT32
, BASE_DEC
,
634 NULL
, 0, NULL
, HFILL
}},
636 { &hf_rx_prev_packet
, {
637 "Prev Packet", "rx.prev", FT_UINT32
, BASE_DEC
,
638 NULL
, 0, "Previous Packet", HFILL
}},
641 "Reason", "rx.reason", FT_UINT8
, BASE_DEC
,
642 VALS(rx_reason
), 0, "Reason For This ACK", HFILL
}},
645 "Num ACKs", "rx.num_acks", FT_UINT8
, BASE_DEC
,
646 NULL
, 0, "Number Of ACKs", HFILL
}},
649 "ACK Type", "rx.ack_type", FT_UINT8
, BASE_DEC
,
650 VALS(rx_ack_type
), 0, "Type Of ACKs", HFILL
}},
653 "ACK Packet", "rx.ack", FT_NONE
, BASE_NONE
,
654 NULL
, 0, NULL
, HFILL
}},
656 { &hf_rx_challenge
, {
657 "CHALLENGE Packet", "rx.challenge", FT_NONE
, BASE_NONE
,
658 NULL
, 0, NULL
, HFILL
}},
661 "Version", "rx.version", FT_UINT32
, BASE_DEC
,
662 NULL
, 0, "Version Of Challenge/Response", HFILL
}},
665 "Nonce", "rx.nonce", FT_UINT32
, BASE_HEX
,
666 NULL
, 0, NULL
, HFILL
}},
668 { &hf_rx_inc_nonce
, {
669 "Inc Nonce", "rx.inc_nonce", FT_UINT32
, BASE_HEX
,
670 NULL
, 0, "Incremented Nonce", HFILL
}},
672 { &hf_rx_min_level
, {
673 "Min Level", "rx.min_level", FT_UINT32
, BASE_DEC
,
674 NULL
, 0, NULL
, HFILL
}},
677 "Level", "rx.level", FT_UINT32
, BASE_DEC
,
678 NULL
, 0, NULL
, HFILL
}},
681 "RESPONSE Packet", "rx.response", FT_NONE
, BASE_NONE
,
682 NULL
, 0, NULL
, HFILL
}},
685 "ABORT Packet", "rx.abort", FT_NONE
, BASE_NONE
,
686 NULL
, 0, NULL
, HFILL
}},
688 { &hf_rx_encrypted
, {
689 "Encrypted", "rx.encrypted", FT_NONE
, BASE_NONE
,
690 NULL
, 0, "Encrypted part of response packet", HFILL
}},
693 "kvno", "rx.kvno", FT_UINT32
, BASE_DEC
,
694 NULL
, 0, NULL
, HFILL
}},
696 { &hf_rx_ticket_len
, {
697 "Ticket len", "rx.ticket_len", FT_UINT32
, BASE_DEC
,
698 NULL
, 0, "Ticket Length", HFILL
}},
701 "ticket", "rx.ticket", FT_BYTES
, BASE_NONE
,
702 NULL
, 0, NULL
, HFILL
}},
705 "Interface MTU", "rx.if_mtu", FT_UINT32
, BASE_DEC
,
706 NULL
, 0, NULL
, HFILL
}},
709 "Max MTU", "rx.max_mtu", FT_UINT32
, BASE_DEC
,
710 NULL
, 0, NULL
, HFILL
}},
713 "rwind", "rx.rwind", FT_UINT32
, BASE_DEC
,
714 NULL
, 0, NULL
, HFILL
}},
716 { &hf_rx_maxpackets
, {
717 "Max Packets", "rx.max_packets", FT_UINT32
, BASE_DEC
,
718 NULL
, 0, NULL
, HFILL
}},
720 { &hf_rx_abortcode
, {
721 "Abort Code", "rx.abort_code", FT_INT32
, BASE_DEC
,
722 NULL
, 0, NULL
, HFILL
}},
725 static int *ett
[] = {
735 proto_rx
= proto_register_protocol("RX Protocol", "RX", "rx");
736 proto_register_field_array(proto_rx
, hf
, array_length(hf
));
737 proto_register_subtree_array(ett
, array_length(ett
));
739 rx_handle
= register_dissector("rx", dissect_rx
, proto_rx
);
743 proto_reg_handoff_rx(void)
746 * Get handle for the AFS dissector.
748 afs_handle
= find_dissector_add_dependency("afs", proto_rx
);
750 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_RX_RANGE
, rx_handle
);
754 * Editor modelines - https://www.wireshark.org/tools/modelines.html
759 * indent-tabs-mode: t
762 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
763 * :indentSize=8:tabSize=8:noTabs=yes: