HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-mpls-y1711.c
blob73cc880f21d3b2069ae7ab3e46c4a7f690539e1c
1 /* packet-mpls-y1711.c
2 * Routines for (old) ITU-T MPLS OAM: it conforms to ITU-T Y.1711 and RFC 3429
4 * Copyright 2006, 2011 _FF_
6 * Francesco Fondelli <francesco dot fondelli, gmail dot com>
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 * FF: NOTES
32 * - this should dissect OAM pdus (identified by the MPLS_LABEL_OAM_ALERT = 14
33 * label) as described in ITU-T Y.1711 and RFC 3429.
35 * - this code used to be (since 2006) in packet-mpls.c ... nobody on this
36 * planet is using Y.1711 today (?), so thanks to the mpls subdissector
37 * table indexed by label value it has been moved here.
40 #include "config.h"
42 #include <glib.h>
44 #include <epan/packet.h>
45 #include <epan/addr_resolv.h>
46 #include <epan/expert.h>
48 #include "packet-mpls.h"
50 static gint proto_mpls_y1711 = -1;
52 static int hf_mpls_y1711_function_type = -1;
53 /* static int hf_mpls_y1711_ttsi = -1; */
54 static int hf_mpls_y1711_frequency = -1;
55 static int hf_mpls_y1711_defect_type = -1;
56 static int hf_mpls_y1711_defect_location = -1;
57 static int hf_mpls_y1711_bip16 = -1;
58 /* Generated from convert_proto_tree_add_text.pl */
59 static int hf_mpls_y1711_lsr_id = -1;
60 static int hf_mpls_y1711_lsp_id = -1;
62 static gint ett_mpls_y1711 = -1;
64 /* Generated from convert_proto_tree_add_text.pl */
65 static expert_field ei_mpls_y1711_padding_not_ff = EI_INIT;
66 static expert_field ei_mpls_y1711_reserved_not_zero = EI_INIT;
67 static expert_field ei_mpls_y1711_ttsi_not_preset = EI_INIT;
68 static expert_field ei_mpls_y1711_minimum_payload = EI_INIT;
69 static expert_field ei_mpls_y1711_s_bit_not_one = EI_INIT;
70 static expert_field ei_mpls_y1711_no_OAM_alert_label = EI_INIT;
71 static expert_field ei_mpls_y1711_exp_bits_not_zero = EI_INIT;
72 static expert_field ei_mpls_y1711_ttl_not_one = EI_INIT;
73 static expert_field ei_mpls_y1711_padding_not_zero = EI_INIT;
74 static expert_field ei_mpls_y1711_unknown_pdu = EI_INIT;
76 static dissector_handle_t mpls_y1711_handle;
77 static dissector_handle_t data_handle;
79 static const value_string y1711_function_type_vals[] = {
80 {0x00, "Reserved" },
81 {0x01, "CV (Connectivity Verification)" },
82 {0x02, "FDI (Forward Defect Indicator)" },
83 {0x03, "BDI (Backward Defect Indicator)" },
84 {0x04, "Reserved for Performance packets" },
85 {0x05, "Reserved for LB-Req (Loopback Request)" },
86 {0x06, "Reserved for LB-Rsp (Loopback Response)"},
87 {0x07, "FDD (Fast Failure Detection)" },
88 {0, NULL }
91 static const value_string y1711_frequency_vals[] = {
92 {0x00, "Reserved" },
93 {0x01, "10 ms" },
94 {0x02, "20 ms" },
95 {0x03, "50 ms (default value)"},
96 {0x04, "100 ms" },
97 {0x05, "200 ms" },
98 {0x06, "500 ms" },
99 /* 7-255 Reserved */
100 {0, NULL }
103 static const value_string y1711_defect_type_vals[] = {
104 {0x0000, "Reserved" },
105 {0x0101, "dServer" },
106 {0x0102, "dPeerME" },
107 {0x0201, "dLOCV" },
108 {0x0202, "dTTSI_Mismatch"},
109 {0x0203, "dTTSI_Mismerge"},
110 {0x0204, "dExcess" },
111 {0x02FF, "dUnknown" },
112 {0xFFFF, "Reserved" },
113 {0, NULL }
116 static int
117 dissect_mpls_y1711(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
119 struct mplsinfo *mplsinfo = (struct mplsinfo *)data;
120 int offset = 0;
121 proto_item *ti;
122 proto_tree *mpls_y1711_tree;
123 int functype;
124 tvbuff_t *data_tvb;
126 static const guint8 allone[] = { 0xff, 0xff };
127 static const guint8 allzero[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00 };
132 functype = tvb_get_guint8(tvb, offset);
133 col_append_fstr(pinfo->cinfo, COL_INFO, " (Y.1711: %s)",
134 (functype == 0x01) ? "CV" :
135 (functype == 0x02) ? "FDI" :
136 (functype == 0x03) ? "BDI" :
137 (functype == 0x07) ? "FDD" :
138 "reserved/unknown");
140 /* sanity checks */
141 if (tvb_reported_length(tvb) < 44) {
143 * ITU-T Y.1711, 5.3: PDUs must have a minimum payload length of
144 * 44 bytes
146 proto_tree_add_expert(tree, pinfo, &ei_mpls_y1711_minimum_payload, tvb, offset, -1);
147 data_tvb = tvb_new_subset_remaining(tvb, offset);
148 call_dissector(data_handle, data_tvb, pinfo, tree);
150 return tvb_reported_length(tvb);
153 ti = proto_tree_add_text(tree, tvb, offset, 44, "Y.1711 OAM");
154 mpls_y1711_tree = proto_item_add_subtree(ti, ett_mpls_y1711);
156 /* checks for exp, bos and ttl encoding */
157 if (mplsinfo->label != MPLS_LABEL_OAM_ALERT)
158 proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_no_OAM_alert_label, tvb, offset - 4, 3,
159 "Warning: Y.1711 but no OAM alert label (%d) ?!", MPLS_LABEL_OAM_ALERT);
161 if (mplsinfo->exp != 0)
162 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_exp_bits_not_zero, tvb, offset - 2, 1);
164 if (mplsinfo->bos != 1)
165 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_s_bit_not_one, tvb, offset - 2, 1);
167 if (mplsinfo->ttl != 1)
168 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttl_not_one, tvb, offset - 1, 1);
170 /* starting dissection */
171 functype = tvb_get_guint8(tvb, offset);
172 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_function_type, tvb,
173 offset, 1,
174 ENC_LITTLE_ENDIAN);
175 offset++;
177 switch (functype) {
178 case 0x01: /* CV */
180 /* 3 octets reserved (all 0x00) */
181 if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
182 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
184 offset += 3;
186 /* ttsi (ipv4 flavor as in RFC 2373) */
187 if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
188 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
190 offset += 10;
192 if (tvb_memeql(tvb, offset, allone, 2) == -1) {
193 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
195 offset += 2;
197 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
198 offset += 4;
200 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
201 offset += 4;
203 /* 18 octets of padding (all 0x00) */
204 if (tvb_memeql(tvb, offset, allzero, 18) == -1) {
205 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 18);
207 offset += 18;
209 break;
211 case 0x02: /* FDI */
212 case 0x03: /* BDI */
214 /* 1 octets reserved (all 0x00) */
215 if (tvb_memeql(tvb, offset, allzero, 1) == -1) {
216 proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3,
217 "Error: this byte is reserved and must be 0x00");
219 offset++;
221 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_type, tvb,
222 offset, 2,
223 ENC_LITTLE_ENDIAN);
224 offset += 2;
227 * ttsi (ipv4 flavor as in RFC 2373) is optional if not used must
228 * be set to all 0x00
230 if (tvb_memeql(tvb, offset, allzero, 20) == 0) {
231 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttsi_not_preset, tvb, offset, 20);
232 offset += 20;
233 } else {
234 if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
235 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
237 offset += 10;
239 if (tvb_memeql(tvb, offset, allone, 2) == -1) {
240 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
242 offset += 2;
244 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
245 offset += 4;
247 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
248 offset += 4;
251 /* defect location */
252 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_location, tvb,
253 offset, 4,
254 ENC_LITTLE_ENDIAN);
255 offset += 4;
257 /* 14 octets of padding (all 0x00) */
258 if (tvb_memeql(tvb, offset, allzero, 14) == -1) {
259 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 14);
261 offset += 14;
263 break;
265 case 0x07: /* FDD */
267 /* 3 octets reserved (all 0x00) */
268 if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
269 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
271 offset += 3;
273 /* ttsi (ipv4 flavor as in RFC 2373) */
274 if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
275 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
277 offset += 10;
279 if (tvb_memeql(tvb, offset, allone, 2) == -1) {
280 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
282 offset += 2;
284 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
285 offset += 4;
287 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
288 offset += 4;
290 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_frequency, tvb,
291 offset, 1,
292 ENC_LITTLE_ENDIAN);
293 offset++;
295 /* 17 octets of padding (all 0x00) */
296 if (tvb_memeql(tvb, offset, allzero, 17) == -1) {
297 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 17);
299 offset += 17;
301 break;
303 default:
304 proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_unknown_pdu, tvb, offset - 1, -1);
305 return offset;
308 /* BIP16 */
309 proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_bip16, tvb, offset, 2,
310 ENC_LITTLE_ENDIAN);
311 offset += 2;
313 return offset;
316 void
317 proto_register_mpls_y1711(void)
319 static hf_register_info hf[] = {
321 &hf_mpls_y1711_function_type,
323 "Function Type", "mpls_y1711.function_type", FT_UINT8,
324 BASE_HEX, VALS(y1711_function_type_vals),
325 0x0, "Function Type codepoint", HFILL
328 #if 0
330 &hf_mpls_y1711_ttsi,
332 "Trail Termination Source Identifier",
333 "mpls_y1711.ttsi",
334 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL
337 #endif
339 &hf_mpls_y1711_frequency,
341 "Frequency", "mpls_y1711.frequency", FT_UINT8,
342 BASE_HEX, VALS(y1711_frequency_vals), 0x0,
343 "Frequency of probe injection", HFILL
347 &hf_mpls_y1711_defect_type,
349 "Defect Type", "mpls_y1711.defect_type", FT_UINT16,
350 BASE_HEX, VALS(y1711_defect_type_vals), 0x0, NULL, HFILL
354 &hf_mpls_y1711_defect_location,
356 "Defect Location (AS)", "mpls_y1711.defect_location",
357 FT_UINT32, BASE_DEC, NULL, 0x0, "Defect Location", HFILL
361 &hf_mpls_y1711_bip16,
363 "BIP16", "mpls_y1711.bip16", FT_UINT16,
364 BASE_HEX, NULL, 0x0, NULL, HFILL
367 /* Generated from convert_proto_tree_add_text.pl */
368 { &hf_mpls_y1711_lsr_id, { "LSR ID", "mpls_y1711.lsr_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
369 { &hf_mpls_y1711_lsp_id, { "LSP ID", "mpls_y1711.lsp_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
372 static gint *ett[] = {
373 &ett_mpls_y1711
376 static ei_register_info ei[] = {
377 /* Generated from convert_proto_tree_add_text.pl */
378 { &ei_mpls_y1711_minimum_payload, { "mpls_y1711.minimum_payload", PI_MALFORMED, PI_ERROR, "Error: must have a minimum payload length of 44 bytes", EXPFILL }},
379 { &ei_mpls_y1711_no_OAM_alert_label, { "mpls_y1711.no_OAM_alert_label", PI_PROTOCOL, PI_WARN, "Warning: Y.1711 but no OAM alert label (%d) ?!", EXPFILL }},
380 { &ei_mpls_y1711_exp_bits_not_zero, { "mpls_y1711.exp_bits_not_0", PI_PROTOCOL, PI_WARN, "Warning: Exp bits should be 0 for Y.1711", EXPFILL }},
381 { &ei_mpls_y1711_s_bit_not_one, { "mpls_y1711.s_bit_not_1", PI_PROTOCOL, PI_WARN, "Warning: S bit should be 1 for Y.1711", EXPFILL }},
382 { &ei_mpls_y1711_ttl_not_one, { "mpls_y1711.ttl_not_1", PI_PROTOCOL, PI_WARN, "Warning: TTL should be 1 for Y.1711", EXPFILL }},
383 { &ei_mpls_y1711_reserved_not_zero, { "mpls_y1711.reserved_not_zero", PI_PROTOCOL, PI_WARN, "Error: these bytes are reserved and must be 0x00", EXPFILL }},
384 { &ei_mpls_y1711_padding_not_zero, { "mpls_y1711.padding_not_zero", PI_PROTOCOL, PI_WARN, "Error: these bytes are padding and must be 0x00", EXPFILL }},
385 { &ei_mpls_y1711_padding_not_ff, { "mpls_y1711.padding_not_ff", PI_PROTOCOL, PI_WARN, "Error: these bytes are padding and must be 0xFF", EXPFILL }},
386 { &ei_mpls_y1711_ttsi_not_preset, { "mpls_y1711.ttsi_not_preset", PI_PROTOCOL, PI_NOTE, "TTSI not preset (optional for FDI/BDI)", EXPFILL }},
387 { &ei_mpls_y1711_unknown_pdu, { "mpls_y1711.unknown_pdu", PI_PROTOCOL, PI_WARN, "Unknown MPLS Y.1711 PDU", EXPFILL }},
390 expert_module_t* expert_mpls_y1711;
392 proto_mpls_y1711 =
393 proto_register_protocol("MPLS ITU-T Y.1711 OAM",
394 "MPLS ITU-T Y.1711 OAM",
395 "mpls_y1711");
396 proto_register_field_array(proto_mpls_y1711, hf, array_length(hf));
397 proto_register_subtree_array(ett, array_length(ett));
398 expert_mpls_y1711 = expert_register_protocol(proto_mpls_y1711);
399 expert_register_field_array(expert_mpls_y1711, ei, array_length(ei));
400 new_register_dissector("mpls_y1711", dissect_mpls_y1711, proto_mpls_y1711);
403 void
404 proto_reg_handoff_mpls_y1711(void)
406 mpls_y1711_handle = find_dissector("mpls_y1711");
407 dissector_add_uint("mpls.label",
408 MPLS_LABEL_OAM_ALERT /* 14 */,
409 mpls_y1711_handle);
411 data_handle = find_dissector("data");
415 * Editor modelines - http://www.wireshark.org/tools/modelines.html
417 * Local variables:
418 * c-basic-offset: 4
419 * tab-width: 8
420 * indent-tabs-mode: nil
421 * End:
423 * vi: set shiftwidth=4 tabstop=8 expandtab:
424 * :indentSize=4:tabSize=8:noTabs=true: