/src/wireshark/epan/dissectors/packet-marker.c
Line | Count | Source |
1 | | /* packet-marker.c |
2 | | * Routines for Link Aggregation Marker protocol dissection. |
3 | | * IEEE Std 802.1AX-2014 Section 6.5 |
4 | | * |
5 | | * Copyright 2002 Steve Housley <steve_housley@3com.com> |
6 | | * Copyright 2005 Dominique Bastien <dbastien@accedian.com> |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@wireshark.org> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/to_str.h> |
19 | | #include <epan/expert.h> |
20 | | #include "packet-slowprotocols.h" |
21 | | |
22 | | /* General declarations */ |
23 | | void proto_register_marker(void); |
24 | | void proto_reg_handoff_marker(void); |
25 | | |
26 | | static dissector_handle_t marker_handle; |
27 | | |
28 | | /* MARKER TLVs subtype */ |
29 | 45 | #define MARKER_TERMINATOR 0x0 |
30 | 45 | #define MARKERPDU_MARKER_INFO 0x1 |
31 | 45 | #define MARKERPDU_MARKER_RESPONSE 0x2 |
32 | | |
33 | | static const value_string marker_vals[] = { |
34 | | { MARKER_TERMINATOR, "Marker Terminator" }, |
35 | | { MARKERPDU_MARKER_INFO, "Marker Information" }, |
36 | | { MARKERPDU_MARKER_RESPONSE, "Marker Response Information" }, |
37 | | { 0, NULL } |
38 | | }; |
39 | | |
40 | | /* Initialise the protocol and registered fields */ |
41 | | static int proto_marker; |
42 | | |
43 | | static int hf_marker_version_number; |
44 | | static int hf_marker_tlv_type; |
45 | | static int hf_marker_tlv_length; |
46 | | static int hf_marker_req_port; |
47 | | static int hf_marker_req_system; |
48 | | static int hf_marker_req_trans_id; |
49 | | static int hf_marker_req_pad; |
50 | | static int hf_marker_reserved; |
51 | | |
52 | | /* Expert Items */ |
53 | | static expert_field ei_marker_wrong_tlv_type; |
54 | | static expert_field ei_marker_wrong_tlv_length; |
55 | | static expert_field ei_marker_wrong_pad_value; |
56 | | |
57 | | /* Initialise the subtree pointers */ |
58 | | static int ett_marker; |
59 | | |
60 | | static int |
61 | | dissect_marker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
62 | 45 | { |
63 | 45 | int offset = 0; |
64 | 45 | unsigned tlv_type, tlv_length; |
65 | 45 | unsigned port, transactionid, pad; |
66 | 45 | const char *sysidstr; |
67 | | |
68 | 45 | proto_tree *marker_tree; |
69 | 45 | proto_item *marker_item, *tlv_type_item, *tlv_length_item, *pad_item; |
70 | | |
71 | 45 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Marker"); |
72 | 45 | col_set_str(pinfo->cinfo, COL_INFO, "Marker Protocol"); |
73 | | |
74 | 45 | marker_item = proto_tree_add_protocol_format(tree, proto_marker, tvb, |
75 | 45 | 0, -1, "Marker Protocol"); |
76 | 45 | marker_tree = proto_item_add_subtree(marker_item, ett_marker); |
77 | | |
78 | 45 | proto_tree_add_item(marker_tree, hf_marker_version_number, tvb, |
79 | 45 | offset, 1, ENC_BIG_ENDIAN); |
80 | 45 | offset += 1; |
81 | | |
82 | 45 | tlv_type_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_type, tvb, |
83 | 45 | offset, 1, ENC_BIG_ENDIAN, &tlv_type); |
84 | 45 | offset += 1; |
85 | | |
86 | 45 | tlv_length_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_length, tvb, |
87 | 45 | offset, 1, ENC_BIG_ENDIAN, &tlv_length); |
88 | 45 | offset += 1; |
89 | | |
90 | 45 | if (tlv_type == MARKERPDU_MARKER_INFO) { |
91 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Information"); |
92 | 45 | } else if (tlv_type == MARKERPDU_MARKER_RESPONSE) { |
93 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Response"); |
94 | 45 | } else { |
95 | 45 | expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_type); |
96 | 45 | } |
97 | 45 | if (tlv_length != 16) { |
98 | 45 | expert_add_info(pinfo, tlv_length_item, &ei_marker_wrong_tlv_length); |
99 | 45 | } |
100 | 45 | proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_port, tvb, |
101 | 45 | offset, 2, ENC_BIG_ENDIAN, &port); |
102 | 45 | offset += 2; |
103 | | |
104 | 45 | proto_tree_add_item(marker_tree, hf_marker_req_system, tvb, |
105 | 45 | offset, 6, ENC_NA); |
106 | 45 | sysidstr = tvb_ether_to_str(pinfo->pool, tvb, offset); |
107 | 45 | offset += 6; |
108 | | |
109 | 45 | proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_trans_id, tvb, |
110 | 45 | offset, 4, ENC_BIG_ENDIAN, &transactionid); |
111 | 45 | offset += 4; |
112 | | |
113 | 45 | col_append_fstr(pinfo->cinfo, COL_INFO, " SysId=%s, P=%d, TId=%d", |
114 | 45 | sysidstr, port, transactionid); |
115 | | |
116 | 45 | pad_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_pad, tvb, |
117 | 45 | offset, 2, ENC_BIG_ENDIAN, &pad); |
118 | 45 | if (pad != 0) { |
119 | 15 | expert_add_info(pinfo, pad_item, &ei_marker_wrong_pad_value); |
120 | 15 | } |
121 | 45 | offset += 2; |
122 | | |
123 | 45 | proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_type, tvb, |
124 | 45 | offset, 1, ENC_BIG_ENDIAN, &tlv_type); |
125 | 45 | offset += 1; |
126 | | |
127 | 45 | proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_length, tvb, |
128 | 45 | offset, 1, ENC_BIG_ENDIAN, &tlv_length); |
129 | 45 | offset += 1; |
130 | | |
131 | 45 | if (tlv_type == MARKER_TERMINATOR) { |
132 | 17 | if (tlv_length != 0) { |
133 | 10 | expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_length); |
134 | 10 | } |
135 | 28 | } else { |
136 | 28 | expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_type); |
137 | 28 | } |
138 | | |
139 | 45 | proto_tree_add_item(marker_tree, hf_marker_reserved, tvb, |
140 | 45 | offset, 90, ENC_NA); |
141 | 45 | offset += 90; |
142 | 45 | return offset; |
143 | 45 | } |
144 | | |
145 | | /* Register the protocol with Wireshark */ |
146 | | void |
147 | | proto_register_marker(void) |
148 | 14 | { |
149 | | /* Setup list of header fields */ |
150 | | |
151 | 14 | static hf_register_info hf[] = { |
152 | 14 | { &hf_marker_version_number, |
153 | 14 | { "Version Number", "marker.version", |
154 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
155 | 14 | "Marker protocol version", HFILL }}, |
156 | | |
157 | 14 | { &hf_marker_tlv_type, |
158 | 14 | { "TLV Type", "marker.tlvType", |
159 | 14 | FT_UINT8, BASE_HEX, VALS(marker_vals), 0x0, |
160 | 14 | NULL, HFILL }}, |
161 | | |
162 | 14 | { &hf_marker_tlv_length, |
163 | 14 | { "TLV Length", "marker.tlvLen", |
164 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
165 | 14 | "Length of the Actor TLV", HFILL }}, |
166 | | |
167 | 14 | { &hf_marker_req_port, |
168 | 14 | { "Requester Port", "marker.requesterPort", |
169 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
170 | 14 | NULL, HFILL }}, |
171 | | |
172 | 14 | { &hf_marker_req_system, |
173 | 14 | { "Requester System", "marker.requesterSystem", |
174 | 14 | FT_ETHER, BASE_NONE, NULL, 0x0, |
175 | 14 | "Requester System ID encoded as a MAC address", HFILL }}, |
176 | | |
177 | 14 | { &hf_marker_req_trans_id, |
178 | 14 | { "Requester Transaction ID", "marker.requesterTransId", |
179 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
180 | 14 | NULL, HFILL }}, |
181 | | |
182 | 14 | { &hf_marker_req_pad, |
183 | 14 | { "Requester Pad", "marker.requesterPad", |
184 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
185 | 14 | NULL, HFILL }}, |
186 | | |
187 | 14 | { &hf_marker_reserved, |
188 | 14 | { "Reserved", "marker.reserved", |
189 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
190 | 14 | NULL, HFILL }}, |
191 | 14 | }; |
192 | | |
193 | | /* Setup protocol subtree array */ |
194 | | |
195 | 14 | static int *ett[] = { |
196 | 14 | &ett_marker, |
197 | 14 | }; |
198 | | |
199 | 14 | static ei_register_info ei[] = { |
200 | 14 | { &ei_marker_wrong_tlv_type, { "marker.wrong_tlv_type", PI_MALFORMED, PI_ERROR, "TLV is not expected type", EXPFILL }}, |
201 | 14 | { &ei_marker_wrong_tlv_length, { "marker.wrong_tlv_length", PI_MALFORMED, PI_ERROR, "TLV is not expected length", EXPFILL }}, |
202 | 14 | { &ei_marker_wrong_pad_value, { "marker.wrong_pad_value", PI_PROTOCOL, PI_WARN, "pad value is not 0", EXPFILL }}, |
203 | 14 | }; |
204 | | |
205 | 14 | expert_module_t* expert_marker; |
206 | | |
207 | | |
208 | | |
209 | | /* Register the protocol name and description */ |
210 | | |
211 | 14 | proto_marker = proto_register_protocol("Link Aggregation Marker Protocol", "Marker", "marker"); |
212 | | |
213 | | /* Required function calls to register the header fields and subtrees used */ |
214 | | |
215 | 14 | proto_register_field_array(proto_marker, hf, array_length(hf)); |
216 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
217 | 14 | expert_marker = expert_register_protocol(proto_marker); |
218 | 14 | expert_register_field_array(expert_marker, ei, array_length(ei)); |
219 | | |
220 | 14 | marker_handle = register_dissector("marker", dissect_marker, proto_marker); |
221 | 14 | } |
222 | | |
223 | | void |
224 | | proto_reg_handoff_marker(void) |
225 | 14 | { |
226 | 14 | dissector_add_uint("slow.subtype", MARKER_SUBTYPE, marker_handle); |
227 | 14 | } |
228 | | |
229 | | /* |
230 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
231 | | * |
232 | | * Local variables: |
233 | | * c-basic-offset: 4 |
234 | | * tab-width: 8 |
235 | | * indent-tabs-mode: nil |
236 | | * End: |
237 | | * |
238 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
239 | | * :indentSize=4:tabSize=8:noTabs=true: |
240 | | */ |