/src/wireshark/epan/dissectors/packet-mpls-y1711.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-mpls-y1711.c |
2 | | * Routines for (old) ITU-T MPLS OAM: it conforms to ITU-T Y.1711 and RFC 3429 |
3 | | * |
4 | | * Copyright 2006, 2011 _FF_ |
5 | | * |
6 | | * Francesco Fondelli <francesco dot fondelli, gmail dot 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 | | /* |
16 | | * FF: NOTES |
17 | | * |
18 | | * - this should dissect OAM pdus (identified by the MPLS_LABEL_OAM_ALERT = 14 |
19 | | * label) as described in ITU-T Y.1711 and RFC 3429. |
20 | | * |
21 | | * - this code used to be (since 2006) in packet-mpls.c ... nobody on this |
22 | | * planet is using Y.1711 today (?), so thanks to the mpls subdissector |
23 | | * table indexed by label value it has been moved here. |
24 | | */ |
25 | | |
26 | | #include "config.h" |
27 | | |
28 | | #include <epan/packet.h> |
29 | | #include <epan/expert.h> |
30 | | |
31 | | #include "packet-mpls.h" |
32 | | |
33 | | void proto_register_mpls_y1711(void); |
34 | | void proto_reg_handoff_mpls_y1711(void); |
35 | | |
36 | | static int proto_mpls_y1711; |
37 | | |
38 | | static int hf_mpls_y1711_function_type; |
39 | | /* static int hf_mpls_y1711_ttsi; */ |
40 | | static int hf_mpls_y1711_frequency; |
41 | | static int hf_mpls_y1711_defect_type; |
42 | | static int hf_mpls_y1711_defect_location; |
43 | | static int hf_mpls_y1711_bip16; |
44 | | /* Generated from convert_proto_tree_add_text.pl */ |
45 | | static int hf_mpls_y1711_lsr_id; |
46 | | static int hf_mpls_y1711_lsp_id; |
47 | | |
48 | | static int ett_mpls_y1711; |
49 | | |
50 | | /* Generated from convert_proto_tree_add_text.pl */ |
51 | | static expert_field ei_mpls_y1711_padding_not_ff; |
52 | | static expert_field ei_mpls_y1711_reserved_not_zero; |
53 | | static expert_field ei_mpls_y1711_ttsi_not_preset; |
54 | | static expert_field ei_mpls_y1711_minimum_payload; |
55 | | static expert_field ei_mpls_y1711_s_bit_not_one; |
56 | | static expert_field ei_mpls_y1711_no_OAM_alert_label; |
57 | | static expert_field ei_mpls_y1711_exp_bits_not_zero; |
58 | | static expert_field ei_mpls_y1711_ttl_not_one; |
59 | | static expert_field ei_mpls_y1711_padding_not_zero; |
60 | | static expert_field ei_mpls_y1711_unknown_pdu; |
61 | | |
62 | | static dissector_handle_t mpls_y1711_handle; |
63 | | |
64 | | static const value_string y1711_function_type_vals[] = { |
65 | | {0x00, "Reserved" }, |
66 | | {0x01, "CV (Connectivity Verification)" }, |
67 | | {0x02, "FDI (Forward Defect Indicator)" }, |
68 | | {0x03, "BDI (Backward Defect Indicator)" }, |
69 | | {0x04, "Reserved for Performance packets" }, |
70 | | {0x05, "Reserved for LB-Req (Loopback Request)" }, |
71 | | {0x06, "Reserved for LB-Rsp (Loopback Response)"}, |
72 | | {0x07, "FDD (Fast Failure Detection)" }, |
73 | | {0, NULL } |
74 | | }; |
75 | | |
76 | | static const value_string y1711_frequency_vals[] = { |
77 | | {0x00, "Reserved" }, |
78 | | {0x01, "10 ms" }, |
79 | | {0x02, "20 ms" }, |
80 | | {0x03, "50 ms (default value)"}, |
81 | | {0x04, "100 ms" }, |
82 | | {0x05, "200 ms" }, |
83 | | {0x06, "500 ms" }, |
84 | | /* 7-255 Reserved */ |
85 | | {0, NULL } |
86 | | }; |
87 | | |
88 | | static const value_string y1711_defect_type_vals[] = { |
89 | | {0x0000, "Reserved" }, |
90 | | {0x0101, "dServer" }, |
91 | | {0x0102, "dPeerME" }, |
92 | | {0x0201, "dLOCV" }, |
93 | | {0x0202, "dTTSI_Mismatch"}, |
94 | | {0x0203, "dTTSI_Mismerge"}, |
95 | | {0x0204, "dExcess" }, |
96 | | {0x02FF, "dUnknown" }, |
97 | | {0xFFFF, "Reserved" }, |
98 | | {0, NULL } |
99 | | }; |
100 | | |
101 | | static int |
102 | | dissect_mpls_y1711(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
103 | 5 | { |
104 | 5 | struct mplsinfo *mplsinfo; |
105 | 5 | int offset = 0; |
106 | 5 | proto_tree *mpls_y1711_tree; |
107 | 5 | int functype; |
108 | 5 | tvbuff_t *data_tvb; |
109 | | |
110 | 5 | static const uint8_t allone[] = { 0xff, 0xff }; |
111 | 5 | static const uint8_t allzero[] = { 0x00, 0x00, 0x00, 0x00, 0x00, |
112 | 5 | 0x00, 0x00, 0x00, 0x00, 0x00, |
113 | 5 | 0x00, 0x00, 0x00, 0x00, 0x00, |
114 | 5 | 0x00, 0x00, 0x00, 0x00, 0x00 }; |
115 | | |
116 | | /* Reject the packet if data is NULL */ |
117 | 5 | if (data == NULL) |
118 | 0 | return 0; |
119 | 5 | mplsinfo = (struct mplsinfo *)data; |
120 | | |
121 | 5 | functype = tvb_get_uint8(tvb, offset); |
122 | 5 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Y.1711: %s)", |
123 | 5 | (functype == 0x01) ? "CV" : |
124 | 5 | (functype == 0x02) ? "FDI" : |
125 | 5 | (functype == 0x03) ? "BDI" : |
126 | 5 | (functype == 0x07) ? "FDD" : |
127 | 4 | "reserved/unknown"); |
128 | | |
129 | | /* sanity checks */ |
130 | 5 | if (tvb_reported_length(tvb) < 44) { |
131 | | /* |
132 | | * ITU-T Y.1711, 5.3: PDUs must have a minimum payload length of |
133 | | * 44 bytes |
134 | | */ |
135 | 3 | proto_tree_add_expert(tree, pinfo, &ei_mpls_y1711_minimum_payload, tvb, offset, -1); |
136 | 3 | data_tvb = tvb_new_subset_remaining(tvb, offset); |
137 | 3 | call_data_dissector(data_tvb, pinfo, tree); |
138 | | |
139 | 3 | return tvb_reported_length(tvb); |
140 | 3 | } |
141 | | |
142 | 2 | mpls_y1711_tree = proto_tree_add_subtree(tree, tvb, offset, 44, ett_mpls_y1711, NULL, "Y.1711 OAM"); |
143 | | |
144 | | /* checks for exp, bos and ttl encoding */ |
145 | 2 | if (mplsinfo->label != MPLS_LABEL_OAM_ALERT) |
146 | 0 | proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_no_OAM_alert_label, tvb, offset - 4, 3, |
147 | 0 | "Warning: Y.1711 but no OAM alert label (%d) ?!", MPLS_LABEL_OAM_ALERT); |
148 | | |
149 | 2 | if (mplsinfo->exp != 0) |
150 | 2 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_exp_bits_not_zero, tvb, offset - 2, 1); |
151 | | |
152 | 2 | if (mplsinfo->bos != 1) |
153 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_s_bit_not_one, tvb, offset - 2, 1); |
154 | | |
155 | 2 | if (mplsinfo->ttl != 1) |
156 | 2 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttl_not_one, tvb, offset - 1, 1); |
157 | | |
158 | | /* starting dissection */ |
159 | 2 | functype = tvb_get_uint8(tvb, offset); |
160 | 2 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_function_type, tvb, |
161 | 2 | offset, 1, |
162 | 2 | ENC_LITTLE_ENDIAN); |
163 | 2 | offset++; |
164 | | |
165 | 2 | switch (functype) { |
166 | 0 | case 0x01: /* CV */ |
167 | 0 | { |
168 | | /* 3 octets reserved (all 0x00) */ |
169 | 0 | if (tvb_memeql(tvb, offset, allzero, 3) == -1) { |
170 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3); |
171 | 0 | } |
172 | 0 | offset += 3; |
173 | | |
174 | | /* ttsi (ipv4 flavor as in RFC 2373) */ |
175 | 0 | if (tvb_memeql(tvb, offset, allzero, 10) == -1) { |
176 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10); |
177 | 0 | } |
178 | 0 | offset += 10; |
179 | |
|
180 | 0 | if (tvb_memeql(tvb, offset, allone, 2) == -1) { |
181 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2); |
182 | 0 | } |
183 | 0 | offset += 2; |
184 | |
|
185 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
186 | 0 | offset += 4; |
187 | |
|
188 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
189 | 0 | offset += 4; |
190 | | |
191 | | /* 18 octets of padding (all 0x00) */ |
192 | 0 | if (tvb_memeql(tvb, offset, allzero, 18) == -1) { |
193 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 18); |
194 | 0 | } |
195 | 0 | offset += 18; |
196 | 0 | } |
197 | 0 | break; |
198 | | |
199 | 0 | case 0x02: /* FDI */ |
200 | 0 | case 0x03: /* BDI */ |
201 | 0 | { |
202 | | /* 1 octets reserved (all 0x00) */ |
203 | 0 | if (tvb_memeql(tvb, offset, allzero, 1) == -1) { |
204 | 0 | proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3, |
205 | 0 | "Error: this byte is reserved and must be 0x00"); |
206 | 0 | } |
207 | 0 | offset++; |
208 | |
|
209 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_type, tvb, |
210 | 0 | offset, 2, |
211 | 0 | ENC_BIG_ENDIAN); |
212 | 0 | offset += 2; |
213 | | |
214 | | /* |
215 | | * ttsi (ipv4 flavor as in RFC 2373) is optional if not used must |
216 | | * be set to all 0x00 |
217 | | */ |
218 | 0 | if (tvb_memeql(tvb, offset, allzero, 20) == 0) { |
219 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttsi_not_preset, tvb, offset, 20); |
220 | 0 | offset += 20; |
221 | 0 | } else { |
222 | 0 | if (tvb_memeql(tvb, offset, allzero, 10) == -1) { |
223 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10); |
224 | 0 | } |
225 | 0 | offset += 10; |
226 | |
|
227 | 0 | if (tvb_memeql(tvb, offset, allone, 2) == -1) { |
228 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2); |
229 | 0 | } |
230 | 0 | offset += 2; |
231 | |
|
232 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
233 | 0 | offset += 4; |
234 | |
|
235 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
236 | 0 | offset += 4; |
237 | 0 | } |
238 | | |
239 | | /* defect location */ |
240 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_location, tvb, |
241 | 0 | offset, 4, |
242 | 0 | ENC_BIG_ENDIAN); |
243 | 0 | offset += 4; |
244 | | |
245 | | /* 14 octets of padding (all 0x00) */ |
246 | 0 | if (tvb_memeql(tvb, offset, allzero, 14) == -1) { |
247 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 14); |
248 | 0 | } |
249 | 0 | offset += 14; |
250 | 0 | } |
251 | 0 | break; |
252 | | |
253 | 0 | case 0x07: /* FDD */ |
254 | 0 | { |
255 | | /* 3 octets reserved (all 0x00) */ |
256 | 0 | if (tvb_memeql(tvb, offset, allzero, 3) == -1) { |
257 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3); |
258 | 0 | } |
259 | 0 | offset += 3; |
260 | | |
261 | | /* ttsi (ipv4 flavor as in RFC 2373) */ |
262 | 0 | if (tvb_memeql(tvb, offset, allzero, 10) == -1) { |
263 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10); |
264 | 0 | } |
265 | 0 | offset += 10; |
266 | |
|
267 | 0 | if (tvb_memeql(tvb, offset, allone, 2) == -1) { |
268 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2); |
269 | 0 | } |
270 | 0 | offset += 2; |
271 | |
|
272 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
273 | 0 | offset += 4; |
274 | |
|
275 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
276 | 0 | offset += 4; |
277 | |
|
278 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_frequency, tvb, |
279 | 0 | offset, 1, |
280 | 0 | ENC_LITTLE_ENDIAN); |
281 | 0 | offset++; |
282 | | |
283 | | /* 17 octets of padding (all 0x00) */ |
284 | 0 | if (tvb_memeql(tvb, offset, allzero, 17) == -1) { |
285 | 0 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 17); |
286 | 0 | } |
287 | 0 | offset += 17; |
288 | 0 | } |
289 | 0 | break; |
290 | | |
291 | 2 | default: |
292 | 2 | proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_unknown_pdu, tvb, offset - 1, -1); |
293 | 2 | return offset; |
294 | 2 | } |
295 | | |
296 | | /* BIP16 */ |
297 | 0 | proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_bip16, tvb, offset, 2, |
298 | 0 | ENC_BIG_ENDIAN); |
299 | 0 | offset += 2; |
300 | |
|
301 | 0 | return offset; |
302 | 2 | } |
303 | | |
304 | | void |
305 | | proto_register_mpls_y1711(void) |
306 | 14 | { |
307 | 14 | static hf_register_info hf[] = { |
308 | 14 | { |
309 | 14 | &hf_mpls_y1711_function_type, |
310 | 14 | { |
311 | 14 | "Function Type", "mpls_y1711.function_type", FT_UINT8, |
312 | 14 | BASE_HEX, VALS(y1711_function_type_vals), |
313 | 14 | 0x0, "Function Type codepoint", HFILL |
314 | 14 | } |
315 | 14 | }, |
316 | | #if 0 |
317 | | { |
318 | | &hf_mpls_y1711_ttsi, |
319 | | { |
320 | | "Trail Termination Source Identifier", |
321 | | "mpls_y1711.ttsi", |
322 | | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL |
323 | | } |
324 | | }, |
325 | | #endif |
326 | 14 | { |
327 | 14 | &hf_mpls_y1711_frequency, |
328 | 14 | { |
329 | 14 | "Frequency", "mpls_y1711.frequency", FT_UINT8, |
330 | 14 | BASE_HEX, VALS(y1711_frequency_vals), 0x0, |
331 | 14 | "Frequency of probe injection", HFILL |
332 | 14 | } |
333 | 14 | }, |
334 | 14 | { |
335 | 14 | &hf_mpls_y1711_defect_type, |
336 | 14 | { |
337 | 14 | "Defect Type", "mpls_y1711.defect_type", FT_UINT16, |
338 | 14 | BASE_HEX, VALS(y1711_defect_type_vals), 0x0, NULL, HFILL |
339 | 14 | } |
340 | 14 | }, |
341 | 14 | { |
342 | 14 | &hf_mpls_y1711_defect_location, |
343 | 14 | { |
344 | 14 | "Defect Location (AS)", "mpls_y1711.defect_location", |
345 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL |
346 | 14 | } |
347 | 14 | }, |
348 | 14 | { |
349 | 14 | &hf_mpls_y1711_bip16, |
350 | 14 | { |
351 | 14 | "BIP16", "mpls_y1711.bip16", FT_UINT16, |
352 | 14 | BASE_HEX, NULL, 0x0, NULL, HFILL |
353 | 14 | } |
354 | 14 | }, |
355 | | /* Generated from convert_proto_tree_add_text.pl */ |
356 | 14 | { &hf_mpls_y1711_lsr_id, { "LSR ID", "mpls_y1711.lsr_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
357 | 14 | { &hf_mpls_y1711_lsp_id, { "LSP ID", "mpls_y1711.lsp_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
358 | 14 | }; |
359 | | |
360 | 14 | static int *ett[] = { |
361 | 14 | &ett_mpls_y1711 |
362 | 14 | }; |
363 | | |
364 | 14 | static ei_register_info ei[] = { |
365 | | /* Generated from convert_proto_tree_add_text.pl */ |
366 | 14 | { &ei_mpls_y1711_minimum_payload, { "mpls_y1711.minimum_payload", PI_MALFORMED, PI_ERROR, "Must have a minimum payload length of 44 bytes", EXPFILL }}, |
367 | 14 | { &ei_mpls_y1711_no_OAM_alert_label, { "mpls_y1711.no_OAM_alert_label", PI_PROTOCOL, PI_WARN, "Y.1711 but no OAM alert label", EXPFILL }}, |
368 | 14 | { &ei_mpls_y1711_exp_bits_not_zero, { "mpls_y1711.exp_bits_not_0", PI_PROTOCOL, PI_WARN, "Exp bits should be 0", EXPFILL }}, |
369 | 14 | { &ei_mpls_y1711_s_bit_not_one, { "mpls_y1711.s_bit_not_1", PI_PROTOCOL, PI_WARN, "S bit should be 1", EXPFILL }}, |
370 | 14 | { &ei_mpls_y1711_ttl_not_one, { "mpls_y1711.ttl_not_1", PI_PROTOCOL, PI_WARN, "TTL should be 1", EXPFILL }}, |
371 | 14 | { &ei_mpls_y1711_reserved_not_zero, { "mpls_y1711.reserved_not_zero", PI_PROTOCOL, PI_WARN, "These bytes are reserved and must be 0x00", EXPFILL }}, |
372 | 14 | { &ei_mpls_y1711_padding_not_zero, { "mpls_y1711.padding_not_zero", PI_PROTOCOL, PI_WARN, "These bytes are padding and must be 0x00", EXPFILL }}, |
373 | 14 | { &ei_mpls_y1711_padding_not_ff, { "mpls_y1711.padding_not_ff", PI_PROTOCOL, PI_ERROR, "Error: these bytes are padding and must be 0xFF", EXPFILL }}, |
374 | 14 | { &ei_mpls_y1711_ttsi_not_preset, { "mpls_y1711.ttsi_not_preset", PI_PROTOCOL, PI_NOTE, "TTSI not preset (optional for FDI/BDI)", EXPFILL }}, |
375 | 14 | { &ei_mpls_y1711_unknown_pdu, { "mpls_y1711.unknown_pdu", PI_PROTOCOL, PI_WARN, "Unknown MPLS Y.1711 PDU", EXPFILL }}, |
376 | 14 | }; |
377 | | |
378 | 14 | expert_module_t* expert_mpls_y1711; |
379 | | |
380 | 14 | proto_mpls_y1711 = |
381 | 14 | proto_register_protocol("MPLS ITU-T Y.1711 OAM", |
382 | 14 | "MPLS ITU-T Y.1711 OAM", |
383 | 14 | "mpls_y1711"); |
384 | 14 | proto_register_field_array(proto_mpls_y1711, hf, array_length(hf)); |
385 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
386 | 14 | expert_mpls_y1711 = expert_register_protocol(proto_mpls_y1711); |
387 | 14 | expert_register_field_array(expert_mpls_y1711, ei, array_length(ei)); |
388 | 14 | mpls_y1711_handle = register_dissector("mpls_y1711", dissect_mpls_y1711, proto_mpls_y1711); |
389 | 14 | } |
390 | | |
391 | | void |
392 | | proto_reg_handoff_mpls_y1711(void) |
393 | 14 | { |
394 | 14 | dissector_add_uint("mpls.label", |
395 | 14 | MPLS_LABEL_OAM_ALERT /* 14 */, |
396 | 14 | mpls_y1711_handle); |
397 | 14 | } |
398 | | |
399 | | /* |
400 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
401 | | * |
402 | | * Local variables: |
403 | | * c-basic-offset: 4 |
404 | | * tab-width: 8 |
405 | | * indent-tabs-mode: nil |
406 | | * End: |
407 | | * |
408 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
409 | | * :indentSize=4:tabSize=8:noTabs=true: |
410 | | */ |