2 * Routines for RMCP packet dissection
4 * Duncan Laurie <duncan@sun.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copied from packet-tftp.c
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
19 void proto_register_rmcp(void);
20 void proto_register_rsp(void);
21 void proto_reg_handoff_rmcp(void);
22 void proto_reg_handoff_rsp(void);
24 static dissector_handle_t rmcp_handle
;
25 static dissector_handle_t rsp_handle
;
29 * http://www.dmtf.org/standards/standard_alert.php
30 * http://www.dmtf.org/standards/documents/ASF/DSP0136.pdf
31 * (the ASF specification includes RMCP)
34 static int proto_rmcp
;
35 static int hf_rmcp_version
;
36 static int hf_rmcp_reserved
;
37 static int hf_rmcp_sequence
;
38 static int hf_rmcp_class
;
39 static int hf_rmcp_type
;
40 static int hf_rmcp_trailer
;
43 static int hf_rsp_session_id
;
44 static int hf_rsp_sequence
;
47 static int ett_rmcp_typeclass
;
51 static dissector_table_t rmcp_dissector_table
;
53 #define UDP_PORT_RMCP 623
54 #define UDP_PORT_RMCP_SECURE 664
56 #define RMCP_TYPE_MASK 0x80
57 #define RMCP_TYPE_NORM 0x00
58 #define RMCP_TYPE_ACK 0x01
60 static const value_string rmcp_type_vals
[] = {
61 { RMCP_TYPE_NORM
, "Normal RMCP" },
62 { RMCP_TYPE_ACK
, "RMCP ACK" },
66 #define RMCP_CLASS_MASK 0x1f
67 #define RMCP_CLASS_ASF 0x06
68 #define RMCP_CLASS_IPMI 0x07
69 #define RMCP_CLASS_OEM 0x08
71 static const value_string rmcp_class_vals
[] = {
72 { RMCP_CLASS_ASF
, "ASF" },
73 { RMCP_CLASS_IPMI
, "IPMI" },
74 { RMCP_CLASS_OEM
, "OEM" },
79 dissect_rmcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
81 proto_tree
*rmcp_tree
= NULL
, *field_tree
;
85 const char *class_str
;
90 * Check whether it's a known class value; if not, assume it's
93 if (!tvb_bytes_exist(tvb
, 3, 1))
94 return 0; /* class value byte not present */
95 rmcp_class
= tvb_get_uint8(tvb
, 3);
97 /* Get the normal/ack bit from the RMCP class */
98 type
= (rmcp_class
& RMCP_TYPE_MASK
) >> 7;
99 rmcp_class
&= RMCP_CLASS_MASK
;
101 class_str
= try_val_to_str(rmcp_class
, rmcp_class_vals
);
102 if (class_str
== NULL
)
103 return 0; /* unknown class value */
105 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RMCP");
106 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s, Class: %s",
107 val_to_str(type
, rmcp_type_vals
, "Unknown (0x%02x)"),
111 ti
= proto_tree_add_protocol_format(tree
, proto_rmcp
, tvb
, 0, 4,
112 "Remote Management Control Protocol, Class: %s",
114 rmcp_tree
= proto_item_add_subtree(ti
, ett_rmcp
);
116 proto_tree_add_item(rmcp_tree
, hf_rmcp_version
, tvb
, 0, 1, ENC_LITTLE_ENDIAN
);
117 proto_tree_add_item(rmcp_tree
, hf_rmcp_reserved
, tvb
, 1, 1, ENC_LITTLE_ENDIAN
);
118 proto_tree_add_item(rmcp_tree
, hf_rmcp_sequence
, tvb
, 2, 1, ENC_LITTLE_ENDIAN
);
120 field_tree
= proto_tree_add_subtree_format(rmcp_tree
, tvb
, 3, 1,
121 ett_rmcp_typeclass
, NULL
, "Type: %s, Class: %s",
122 val_to_str(type
, rmcp_type_vals
, "Unknown (0x%02x)"),
125 proto_tree_add_item(field_tree
, hf_rmcp_class
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
126 proto_tree_add_item(field_tree
, hf_rmcp_type
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
129 if (!type
){ /* do not expect a data block for an ACK */
131 next_tvb
= tvb_new_subset_remaining(tvb
, 4);
133 if (!dissector_try_uint(rmcp_dissector_table
, rmcp_class
, next_tvb
, pinfo
,
135 len
= call_data_dissector(next_tvb
, pinfo
, tree
);
136 if (len
< tvb_reported_length(next_tvb
)) {
137 proto_tree_add_item(tree
, hf_rmcp_trailer
, tvb
, 4 + len
, -1, ENC_NA
);
142 return tvb_captured_length(tvb
);
146 dissect_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
148 proto_tree
*rsp_tree
= NULL
/*, *field_tree*/;
149 proto_item
*ti
/*, *tf*/;
154 ti
= proto_tree_add_protocol_format(tree
, proto_rsp
, tvb
, offset
, 8,
155 "RMCP Security-extension Protocol");
156 rsp_tree
= proto_item_add_subtree(ti
, ett_rsp
);
158 proto_tree_add_item(rsp_tree
, hf_rsp_session_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
160 proto_tree_add_item(rsp_tree
, hf_rsp_sequence
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
164 /* XXX determination of RCMP message length needs to
165 * be done according to 3.2.3.3.3 of the specification.
166 * This is only valid for session ID equals 0
168 next_tvb
= tvb_new_subset_remaining(tvb
, 8);
169 dissect_rmcp(next_tvb
, pinfo
, tree
, NULL
);
171 return tvb_captured_length(tvb
);
175 proto_register_rmcp(void)
177 static hf_register_info hf
[] = {
178 { &hf_rmcp_version
, {
179 "Version", "rmcp.version",
180 FT_UINT8
, BASE_HEX
, NULL
, 0,
181 "RMCP Version", HFILL
}},
182 { &hf_rmcp_reserved
, {
183 "Reserved", "rmcp.reserved",
184 FT_UINT8
, BASE_HEX
, NULL
, 0,
185 "RMCP Reserved", HFILL
}},
186 { &hf_rmcp_sequence
, {
187 "Sequence", "rmcp.sequence",
188 FT_UINT8
, BASE_HEX
, NULL
, 0,
189 "RMCP Sequence", HFILL
}},
191 "Class", "rmcp.class",
193 VALS(rmcp_class_vals
), RMCP_CLASS_MASK
,
194 "RMCP Class", HFILL
}},
196 "Message Type", "rmcp.type",
198 VALS(rmcp_type_vals
), RMCP_TYPE_MASK
,
199 "RMCP Message Type", HFILL
}},
200 { &hf_rmcp_trailer
, {
201 "RSP Trailer", "rmcp.trailer",
202 FT_BYTES
, BASE_NONE
, NULL
, 0,
205 static int *ett
[] = {
210 proto_rmcp
= proto_register_protocol("Remote Management Control Protocol", "RMCP", "rmcp");
212 proto_register_field_array(proto_rmcp
, hf
, array_length(hf
));
213 proto_register_subtree_array(ett
, array_length(ett
));
215 rmcp_handle
= register_dissector("rmcp", dissect_rmcp
, proto_rmcp
);
217 rmcp_dissector_table
= register_dissector_table(
218 "rmcp.class", "RMCP Class", proto_rmcp
, FT_UINT8
, BASE_HEX
);
222 proto_register_rsp(void)
224 static hf_register_info hf
[] = {
225 { &hf_rsp_session_id
, {
226 "Session ID", "rsp.session_id",
227 FT_UINT32
, BASE_HEX
, NULL
, 0,
228 "RSP session ID", HFILL
}},
229 { &hf_rsp_sequence
, {
230 "Sequence", "rsp.sequence",
231 FT_UINT32
, BASE_HEX
, NULL
, 0,
232 "RSP sequence", HFILL
}},
234 static int *ett
[] = {
238 proto_rsp
= proto_register_protocol("RMCP Security-extensions Protocol", "RSP", "rsp");
239 proto_register_field_array(proto_rsp
, hf
, array_length(hf
));
240 proto_register_subtree_array(ett
, array_length(ett
));
242 rsp_handle
= register_dissector("rsp", dissect_rsp
, proto_rsp
);
246 proto_reg_handoff_rmcp(void)
248 dissector_add_uint_with_preference("udp.port", UDP_PORT_RMCP
, rmcp_handle
);
252 proto_reg_handoff_rsp(void)
254 dissector_add_uint_with_preference("udp.port", UDP_PORT_RMCP_SECURE
, rsp_handle
);
258 * Editor modelines - https://www.wireshark.org/tools/modelines.html
263 * indent-tabs-mode: t
266 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
267 * :indentSize=8:tabSize=8:noTabs=false: