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 * $Id: packet-rx.c,v 1.8 2000/02/15 21:03:05 gram Exp $
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@zing.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
47 #include "packet-rx.h"
48 #include "packet-afs.h"
51 static const value_string rx_types[] = {
52 { RX_PACKET_TYPE_DATA, "data" },
53 { RX_PACKET_TYPE_ACK, "ack" },
54 { RX_PACKET_TYPE_BUSY, "busy" },
55 { RX_PACKET_TYPE_ABORT, "abort" },
56 { RX_PACKET_TYPE_ACKALL, "ackall" },
57 { RX_PACKET_TYPE_CHALLENGE, "challenge" },
58 { RX_PACKET_TYPE_RESPONSE, "response" },
59 { RX_PACKET_TYPE_DEBUG, "debug" },
60 { RX_PACKET_TYPE_PARAMS, "params" },
61 { RX_PACKET_TYPE_VERSION, "version" },
65 static const value_string rx_flags[] = {
66 { RX_CLIENT_INITIATED, "client-init" },
67 { RX_REQUEST_ACK, "req-ack" },
68 { RX_LAST_PACKET, "last-pckt" },
69 { RX_MORE_PACKETS, "more-pckts" },
70 { RX_FREE_PACKET, "free-pckt" }
73 static int proto_rx = -1;
75 static int hf_rx_epoch = -1;
76 static int hf_rx_cid = -1;
77 static int hf_rx_seq = -1;
78 static int hf_rx_serial = -1;
79 static int hf_rx_callnumber = -1;
80 static int hf_rx_type = -1;
81 static int hf_rx_flags = -1;
82 static int hf_rx_flags_clientinit = -1;
83 static int hf_rx_flags_request_ack = -1;
84 static int hf_rx_flags_last_packet = -1;
85 static int hf_rx_flags_more_packets = -1;
86 static int hf_rx_flags_free_packet = -1;
87 static int hf_rx_userstatus = -1;
88 static int hf_rx_securityindex = -1;
89 static int hf_rx_spare = -1;
90 static int hf_rx_serviceid = -1;
92 static gint ett_rx = -1;
93 static gint ett_rx_flags = -1;
96 dissect_rx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
98 proto_tree *rx_tree, *rx_tree_flags, *rx_flags, *ti;
99 struct rx_header *rxh;
102 rxh = (struct rx_header *) &pd[offset];
104 /* get at least a full packet structure */
105 if ( !BYTES_ARE_IN_FRAME(offset, sizeof(struct rx_header)) )
108 if (check_col(fd, COL_PROTOCOL))
109 col_add_str(fd, COL_PROTOCOL, "RX");
113 ti = proto_tree_add_item_format(tree, proto_rx, offset,
114 sizeof(struct rx_header), NULL, "RX Protocol (%s)",
115 val_to_str(rxh->type,rx_types,"unknown (%d)"));
116 rx_tree = proto_item_add_subtree(ti, ett_rx);
118 proto_tree_add_item(rx_tree, hf_rx_epoch,
119 offset, 4, pntohl(&rxh->epoch));
120 proto_tree_add_item(rx_tree, hf_rx_cid,
121 offset+4, 4, pntohl(&rxh->cid));
122 proto_tree_add_item(rx_tree, hf_rx_callnumber,
123 offset+8, 4, pntohl(&rxh->callNumber));
124 proto_tree_add_item(rx_tree, hf_rx_seq,
125 offset+12, 4, pntohl(&rxh->seq));
126 proto_tree_add_item(rx_tree, hf_rx_serial,
127 offset+16, 4, pntohl(&rxh->serial));
129 proto_tree_add_item(rx_tree, hf_rx_type,
130 offset+20, 1, rxh->type);
132 rx_flags = proto_tree_add_item(rx_tree, hf_rx_flags,
133 offset+21, 1, rxh->flags);
134 rx_tree_flags = proto_item_add_subtree(rx_flags, ett_rx_flags);
135 proto_tree_add_item(rx_tree_flags, hf_rx_flags_free_packet,
136 offset+21, 1, rxh->flags);
137 proto_tree_add_item(rx_tree_flags, hf_rx_flags_more_packets,
138 offset+21, 1, rxh->flags);
139 proto_tree_add_item(rx_tree_flags, hf_rx_flags_last_packet,
140 offset+21, 1, rxh->flags);
141 proto_tree_add_item(rx_tree_flags, hf_rx_flags_request_ack,
142 offset+21, 1, rxh->flags);
143 proto_tree_add_item(rx_tree_flags, hf_rx_flags_clientinit,
144 offset+21, 1, rxh->flags);
146 proto_tree_add_item(rx_tree, hf_rx_userstatus,
147 offset+22, 1, rxh->userStatus);
148 proto_tree_add_item(rx_tree, hf_rx_securityindex,
149 offset+23, 1, rxh->securityIndex);
150 proto_tree_add_item(rx_tree, hf_rx_spare,
151 offset+24, 2, pntohs(&rxh->spare));
152 proto_tree_add_item(rx_tree, hf_rx_serviceid,
153 offset+26, 2, pntohs(&rxh->serviceId));
156 if (check_col(fd, COL_INFO))
157 col_add_fstr(fd, COL_INFO,
162 "Destination Port: %s ",
163 val_to_str(rxh->type, rx_types, "%d"),
164 (unsigned long)pntohl(&rxh->seq),
165 (unsigned long)pntohl(&rxh->callNumber),
166 get_udp_port(pi.srcport),
167 get_udp_port(pi.destport)
170 reply = (rxh->flags & RX_CLIENT_INITIATED) == 0;
171 if ( (rxh->type == RX_PACKET_TYPE_ABORT && reply) ||
172 rxh->type == RX_PACKET_TYPE_DATA )
174 dissect_afs(pd,offset,fd,tree);
179 proto_register_rx(void)
181 static hf_register_info hf[] = {
183 "Epoch", "rx.epoch", FT_UINT32, BASE_DEC,
186 "CID", "rx.cid", FT_UINT32, BASE_DEC,
188 { &hf_rx_callnumber, {
189 "Call Number", "rx.callnumber", FT_UINT32, BASE_DEC,
190 NULL, 0, "Call Number" }},
192 "Sequence Number", "rx.seq", FT_UINT32, BASE_DEC,
193 NULL, 0, "Sequence Number" }},
195 "Serial", "rx.serial", FT_UINT32, BASE_DEC,
196 NULL, 0, "Serial" }},
198 "Type", "rx.type", FT_UINT8, BASE_DEC,
199 VALS(rx_types), 0, "Type" }},
201 "Flags", "rx.flags", FT_UINT8, BASE_HEX,
203 { &hf_rx_flags_clientinit, {
204 "Client Initiated", "rx.flags.client_init", FT_UINT8, BASE_BIN,
205 NULL, RX_CLIENT_INITIATED, "Client Initiated" }},
206 { &hf_rx_flags_request_ack, {
207 "Request Ack", "rx.flags.request_ack", FT_UINT8, BASE_BIN,
208 NULL, RX_REQUEST_ACK, "Request Ack" }},
209 { &hf_rx_flags_last_packet, {
210 "Last Packet", "rx.flags.last_packet", FT_UINT8, BASE_BIN,
211 NULL, RX_LAST_PACKET, "Last Packet" }},
212 { &hf_rx_flags_more_packets, {
213 "More Packets", "rx.flags.more_packets", FT_UINT8, BASE_BIN,
214 NULL, RX_MORE_PACKETS, "More Packets" }},
215 { &hf_rx_flags_free_packet, {
216 "Free Packet", "rx.flags.free_packet", FT_UINT8, BASE_BIN,
217 NULL, RX_FREE_PACKET, "Free Packet" }},
218 { &hf_rx_userstatus, {
219 "User Status", "rx.userstatus", FT_UINT32, BASE_DEC,
220 NULL, 0, "User Status" }},
221 { &hf_rx_securityindex, {
222 "Security Index", "rx.securityindex", FT_UINT32, BASE_DEC,
223 NULL, 0, "Security Index" }},
225 "Spare/Checksum", "rx.spare", FT_UINT16, BASE_DEC,
226 NULL, 0, "Spare/Checksum" }},
227 { &hf_rx_serviceid, {
228 "Service ID", "rx.serviceid", FT_UINT16, BASE_DEC,
229 NULL, 0, "Service ID" }},
231 static gint *ett[] = {
236 proto_rx = proto_register_protocol("RX Protocol", "rx");
237 proto_register_field_array(proto_rx, hf, array_length(hf));
238 proto_register_subtree_array(ett, array_length(ett));