2 * Routines for RMCP packet dissection
4 * Duncan Laurie <duncan@sun.com>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-tftp.c
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include <epan/packet.h>
40 * http://www.dmtf.org/standards/standard_alert.php
42 * (the ASF specification includes RMCP)
45 static int proto_rmcp = -1;
46 static int hf_rmcp_version = -1;
47 static int hf_rmcp_sequence = -1;
48 static int hf_rmcp_class = -1;
49 static int hf_rmcp_type = -1;
51 static gint ett_rmcp = -1;
52 static gint ett_rmcp_typeclass = -1;
54 static dissector_handle_t data_handle;
55 static dissector_table_t rmcp_dissector_table;
57 #define UDP_PORT_RMCP 623
58 #define UDP_PORT_RMCP_SECURE 664
60 #define RMCP_TYPE_MASK 0x80
61 #define RMCP_TYPE_NORM 0x00
62 #define RMCP_TYPE_ACK 0x01
64 static const value_string rmcp_type_vals[] = {
65 { RMCP_TYPE_NORM, "Normal RMCP" },
66 { RMCP_TYPE_ACK, "RMCP ACK" },
70 #define RMCP_CLASS_MASK 0x1f
71 #define RMCP_CLASS_ASF 0x06
72 #define RMCP_CLASS_IPMI 0x07
73 #define RMCP_CLASS_OEM 0x08
75 static const value_string rmcp_class_vals[] = {
76 { RMCP_CLASS_ASF, "ASF" },
77 { RMCP_CLASS_IPMI, "IPMI" },
78 { RMCP_CLASS_OEM, "OEM" },
83 dissect_rmcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
85 proto_tree *rmcp_tree = NULL, *field_tree;
93 * Check whether it's a known class value; if not, assume it's
96 if (!tvb_bytes_exist(tvb, 3, 1))
97 return 0; /* class value byte not present */
98 class = tvb_get_guint8(tvb, 3);
100 /* Get the normal/ack bit from the RMCP class */
101 type = (class & RMCP_TYPE_MASK) >> 7;
102 class &= RMCP_CLASS_MASK;
104 class_str = match_strval(class, rmcp_class_vals);
105 if (class_str == NULL)
106 return 0; /* unknown class value */
108 if (check_col(pinfo->cinfo, COL_PROTOCOL))
109 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMCP");
110 if (check_col(pinfo->cinfo, COL_INFO))
111 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, Class: %s",
112 val_to_str(type, rmcp_type_vals, "Unknown (0x%02x)"),
116 ti = proto_tree_add_protocol_format(tree, proto_rmcp, tvb, 0, 4,
117 "Remote Management Control Protocol, Class: %s",
119 rmcp_tree = proto_item_add_subtree(ti, ett_rmcp);
121 proto_tree_add_item(rmcp_tree, hf_rmcp_version, tvb, 0, 1, TRUE);
122 proto_tree_add_item(rmcp_tree, hf_rmcp_sequence, tvb, 2, 1, TRUE);
124 tf = proto_tree_add_text(rmcp_tree, tvb, 3, 1, "Type: %s, Class: %s",
125 val_to_str(type, rmcp_type_vals, "Unknown (0x%02x)"),
128 field_tree = proto_item_add_subtree(tf, ett_rmcp_typeclass);
130 proto_tree_add_item(field_tree, hf_rmcp_class, tvb, 3, 1, TRUE);
131 proto_tree_add_item(field_tree, hf_rmcp_type, tvb, 3, 1, TRUE);
134 next_tvb = tvb_new_subset(tvb, 4, -1, -1);
136 if (!dissector_try_port(rmcp_dissector_table, class, next_tvb, pinfo,
138 call_dissector(data_handle, next_tvb, pinfo, tree);
140 return tvb_length(tvb);
144 proto_register_rmcp(void)
146 static hf_register_info hf[] = {
147 { &hf_rmcp_version, {
148 "Version", "rmcp.version",
149 FT_UINT8, BASE_HEX, NULL, 0,
150 "RMCP Version", HFILL }},
151 { &hf_rmcp_sequence, {
152 "Sequence", "rmcp.sequence",
153 FT_UINT8, BASE_HEX, NULL, 0,
154 "RMCP Sequence", HFILL }},
156 "Class", "rmcp.class",
158 VALS(rmcp_class_vals), RMCP_CLASS_MASK,
159 "RMCP Class", HFILL }},
161 "Message Type", "rmcp.type",
163 VALS(rmcp_type_vals), RMCP_TYPE_MASK,
164 "RMCP Message Type", HFILL }},
166 static gint *ett[] = {
171 proto_rmcp = proto_register_protocol(
172 "Remote Management Control Protocol", "RMCP", "rmcp");
174 proto_register_field_array(proto_rmcp, hf, array_length(hf));
175 proto_register_subtree_array(ett, array_length(ett));
177 rmcp_dissector_table = register_dissector_table(
178 "rmcp.class", "RMCP Class", FT_UINT8, BASE_HEX);
182 proto_reg_handoff_rmcp(void)
184 dissector_handle_t rmcp_handle;
186 data_handle = find_dissector("data");
188 rmcp_handle = new_create_dissector_handle(dissect_rmcp, proto_rmcp);
189 dissector_add("udp.port", UDP_PORT_RMCP, rmcp_handle);
190 dissector_add("udp.port", UDP_PORT_RMCP_SECURE, rmcp_handle);