2 * Routines for ATM PW dissection: it should be conform to RFC 4717.
4 * Copyright 2009 _FF_, _ATA_
6 * Francesco Fondelli <francesco dot fondelli, gmail dot com>
7 * Artem Tamazov <artem [dot] tamazov [at] tellabs [dot] com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 - ATM N-to-One Cell Mode (with CW)
19 - ATM N-to-One Cell Mode (no CW)
20 - ATM One-to-One Cell Mode
27 #include <epan/packet.h>
28 #include <epan/expert.h>
29 #include <epan/prefs.h>
32 #include <wsutil/array.h>
33 #include <wsutil/str_util.h>
35 #include <wiretap/wtap.h> /*for atm pseudo header*/
36 #include "packet-mpls.h"
37 #include "packet-atm.h"
38 #include "packet-pw-atm.h"
39 #include "packet-pw-common.h"
41 void proto_register_pw_atm_ata(void);
42 void proto_reg_handoff_pw_atm_ata(void);
43 void proto_register_pw_atm(void);
44 void proto_reg_handoff_pw_atm(void);
46 static int proto_n1_nocw
;
47 static int proto_n1_cw
;
48 static int proto_11_or_aal5_pdu
;
49 static int proto_aal5_sdu
;
50 /* subordinate dissectors: */
51 static int proto_control_word
;
52 static int proto_cell_header
;
53 static int proto_cell
;
55 static int ett_encaps
;
57 static int ett_cell_header
;
60 static int hf_pw_type_n1_cw
;
61 static int hf_pw_type_n1_nocw
;
62 static int hf_pw_type_11_vcc
;
63 static int hf_pw_type_11_vpc
;
64 static int hf_pw_type_aal5_sdu
;
65 static int hf_pw_type_aal5_pdu
;
67 static int hf_cell_h_vpi
;
68 static int hf_cell_h_vci
;
69 static int hf_cell_h_pti
;
70 static int hf_cell_h_clp
;
71 static int hf_cell_h_m
;
72 static int hf_cell_h_v
;
73 static int hf_cell_h_rsv
;
74 static int hf_aal5_pdu_rsv
;
75 static int hf_aal5_pdu_u
;
76 static int hf_aal5_pdu_e
;
78 static int hf_cw_bits03
;
79 static int hf_pref_cw_rsv
;
80 static int hf_generic_cw_rsv
;
81 static int hf_pref_cw_flags
;
82 static int hf_pref_cw_a5s_t
;
83 static int hf_pref_cw_a5s_e
;
84 static int hf_pref_cw_a5s_c
;
85 static int hf_pref_cw_a5s_u
;
86 static int hf_pref_cw_len
;
87 static int hf_pref_cw_rsvlen
;
89 static int hf_n1_cw_ncells
;
90 static int hf_n1_nocw_ncells
;
91 static int hf_11_ncells
;
92 static int hf_gen_cw_atmbyte
;
93 static int hf_cell_payload_len
;
95 static expert_field ei_cell_h_v_not_one
;
96 static expert_field ei_cell_h_pti_undecoded
;
97 static expert_field ei_pref_cw_flags
;
98 static expert_field ei_cell_h_v_not_zero
;
99 static expert_field ei_pw_payload_size_invalid_note
;
100 static expert_field ei_pw_payload_size_invalid_error
;
101 static expert_field ei_cell_h_pti_malformed
;
102 static expert_field ei_cell_h_rsv
;
103 static expert_field ei_cell_broken
;
104 static expert_field ei_cell_h_m
;
105 static expert_field ei_cw_bits03
;
106 static expert_field ei_pw_packet_size_too_small
;
107 static expert_field ei_pref_cw_len
;
108 static expert_field ei_gen_cw_atmbyte
;
111 static dissector_handle_t dh_cell
;
112 static dissector_handle_t dh_cell_header
;
113 static dissector_handle_t dh_control_word
;
114 static dissector_handle_t dh_atm_truncated
;
115 static dissector_handle_t dh_atm_untruncated
;
116 static dissector_handle_t dh_atm_oam_cell
;
117 static dissector_handle_t dh_padding
;
120 PWATM_MODE_UNKNOWN
= 0
130 PWATM_SUBMODE_DEFAULT
= 0
131 ,PWATM_SUBMODE_ADMIN_CELL
/*used in aal5_sdu dissector only*/
139 pwatm_submode_t submode
;
142 * ATM-specific attributes which remain the same
143 * across all the cells in the pw packet. Values are filled
144 * by sub-dissectors and read by upper-level dissector.
145 * Meanings of values:
146 * (-1) - value is unknown
147 * (-2) - value is different among cells
148 * positive - value is the same in all cells
149 * Machinery is implemented in the UPDATE_CUMULATIVE_VALUE macro.
156 int32_t vpi
; /*-1 if unknown*/
157 int32_t vci
; /*-1 if unknown*/
158 int32_t pti
; /*-1 if unknown*/
161 * Some fields from 3rd byte of CW. Filled by cell_header dissector.
162 * In in AAL5 PDU mode, this allows control_word dissector to print
163 * these values in the CW heading line in the tree.
164 * Meanings of values:
165 * (-1) - value is unknown
174 bool aal5_sdu_frame_relay_cr_bit
; /*see rfc4717 10.1*/
175 bool cell_mode_oam
; /*atm admin cell*/
176 } pwatm_private_data_t
;
178 #define PWATM_PRIVATE_DATA_T_INITIALIZER { \
179 0, PWC_PACKET_PROPERTIES_T_INITIALIZER, 0 \
180 ,PWATM_MODE_UNKNOWN, PWATM_SUBMODE_DEFAULT \
183 ,{-1, -1, -1, -1, -1, -1 } \
187 #define PTI_IS_ADMIN(pti) ((pti) == 4 || (pti) == 5 || (pti) == 6) /*see atm_pt_vals[]*/
189 #define MODE_11(mode) (PWATM_MODE_11_VCC == (mode) || PWATM_MODE_11_VPC == (mode))
190 #define MODE_N1(mode) (PWATM_MODE_N1_NOCW == (mode)|| PWATM_MODE_N1_CW == (mode))
191 #define MODE_11_OR_AAL5_PDU(mode) (MODE_11(mode) || PWATM_MODE_AAL5_PDU == (mode))
193 #define VALUE_SELECTOR_VPC_VCC_PDU(mode,val_vpc,val_vcc,val_pdu)\
194 ((PWATM_MODE_11_VPC == (mode)) \
196 : ((PWATM_MODE_11_VCC == (mode)) \
198 : ((PWATM_MODE_AAL5_PDU == (mode)) \
205 #define UPDATE_CUMULATIVE_VALUE(cumulative_val,new_val)\
208 if (-2 >= (cumulative_val))\
211 else if (-1 == (cumulative_val))\
213 (cumulative_val) = (new_val);\
215 else if ((new_val) != (cumulative_val))\
217 (cumulative_val) = -2;\
222 #define SIZEOF_ATM_CELL_PAYLOAD 48
223 #define SIZEOF_N1_PW_CELL_HEADER 4
224 #define SIZEOF_11_VCC_PW_CELL_HEADER 1
225 #define SIZEOF_11_VPC_PW_CELL_HEADER 3
226 #define SIZEOF_N1_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_N1_PW_CELL_HEADER)
227 #define SIZEOF_11_VCC_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_11_VCC_PW_CELL_HEADER)
228 #define SIZEOF_11_VPC_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_11_VPC_PW_CELL_HEADER)
230 const char pwc_longname_pw_atm_n1_cw
[] = "MPLS PW ATM N-to-One encapsulation, with CW";
231 const char pwc_longname_pw_atm_n1_nocw
[] = "MPLS PW ATM N-to-One encapsulation, no CW";
232 const char pwc_longname_pw_atm_11_or_aal5_pdu
[] = "MPLS PW ATM One-to-One or AAL5 PDU encapsulation";
233 const char pwc_longname_pw_atm_aal5_sdu
[] = "MPLS PW ATM AAL5 CPCS-SDU mode encapsulation";
235 static const char longname_pw_atm_11_vcc
[] = "MPLS PW ATM One-to-One VCC Cell Transport";
236 static const char longname_pw_atm_11_vpc
[] = "MPLS PW ATM One-to-One VPC Cell Transport";
237 static const char longname_pw_atm_aal5_pdu
[] = "MPLS PW ATM AAL5 PDU encapsulation";
239 static const char shortname_n1_cw
[] = "MPLS PW ATM N:1 CW";
240 static const char shortname_n1_nocw
[] = "MPLS PW ATM N:1 no CW";
241 static const char shortname_11_or_aal5_pdu
[] = "MPLS PW ATM 1:1 / AAL5 PDU";
242 static const char shortname_11_vpc
[] = "MPLS PW ATM 1:1 VPC";
243 static const char shortname_11_vcc
[] = "MPLS PW ATM 1:1 VCC";
244 static const char shortname_aal5_sdu
[] = "MPLS PW ATM AAL5 SDU";
245 static const char shortname_aal5_pdu
[] = "MPLS PW ATM AAL5 PDU";
248 * These options are needed to support Nokia AXE and stuff alike.
249 * Note that these options will affect PW type auto-guessing, if such heuristic
250 * implemented in the future.
252 static bool pref_n1_cw_allow_cw_length_nonzero
;
253 static bool pref_n1_cw_extend_cw_length_with_rsvd
;
254 static bool pref_aal5_sdu_allow_cw_length_nonzero
;
255 static bool pref_aal5_sdu_extend_cw_length_with_rsvd
;
259 pw_cell_size(const pwatm_mode_t mode
, const pwatm_submode_t submode
)
263 case PWATM_MODE_N1_NOCW
:
264 case PWATM_MODE_N1_CW
:
265 return SIZEOF_N1_PW_CELL
;
266 case PWATM_MODE_11_VCC
:
267 return SIZEOF_11_VCC_PW_CELL
;
268 case PWATM_MODE_11_VPC
:
269 return SIZEOF_11_VPC_PW_CELL
;
270 case PWATM_MODE_AAL5_PDU
:
271 /* AAL5 PDU size is n*48 bytes */
272 return SIZEOF_ATM_CELL_PAYLOAD
;
273 case PWATM_MODE_AAL5_SDU
:
274 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
276 return SIZEOF_N1_PW_CELL
; /*n:1 encapsulation is used for admin cells*/
280 DISSECTOR_ASSERT_NOT_REACHED();
284 DISSECTOR_ASSERT_NOT_REACHED();
290 pw_cell_header_size(const pwatm_mode_t mode
, const pwatm_submode_t submode
)
294 case PWATM_MODE_N1_NOCW
:
295 case PWATM_MODE_N1_CW
:
296 return SIZEOF_N1_PW_CELL_HEADER
;
297 case PWATM_MODE_11_VCC
:
298 return SIZEOF_11_VCC_PW_CELL_HEADER
;
299 case PWATM_MODE_11_VPC
:
300 return SIZEOF_11_VPC_PW_CELL_HEADER
;
301 case PWATM_MODE_AAL5_SDU
:
302 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
304 return SIZEOF_N1_PW_CELL_HEADER
; /*n:1 encapsulation is used for admin cells*/
308 DISSECTOR_ASSERT_NOT_REACHED();
311 case PWATM_MODE_AAL5_PDU
: /*not applicable*/
313 DISSECTOR_ASSERT_NOT_REACHED();
319 number_of_cells(const pwatm_mode_t mode
320 ,const pwatm_submode_t submode
321 ,const int payload_size
322 ,int* const remainder_size
)
326 DISSECTOR_ASSERT(payload_size
>= 0);
330 case PWATM_MODE_N1_NOCW
:
331 case PWATM_MODE_N1_CW
:
332 case PWATM_MODE_11_VCC
:
333 case PWATM_MODE_11_VPC
:
334 case PWATM_MODE_AAL5_PDU
:
335 cells
= payload_size
/ pw_cell_size(mode
, submode
);
336 *remainder_size
= payload_size
- (cells
* pw_cell_size(mode
, submode
));
338 case PWATM_MODE_AAL5_SDU
:
339 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
341 cells
= payload_size
/ pw_cell_size(mode
, submode
);
342 if (cells
> 1) cells
= 1; /*max. 1 admin cell may be present in aal5 sdu mode */
343 *remainder_size
= payload_size
- (cells
* pw_cell_size(mode
, submode
));
352 *remainder_size
= payload_size
;
353 DISSECTOR_ASSERT_NOT_REACHED();
361 col_append_pw_info(packet_info
* pinfo
362 ,const int payload_size
364 ,const int padding_size
365 ,pwatm_private_data_t
* pd
)
367 if (pd
->props
& PWC_ANYOF_CW_BAD
)
369 col_append_str(pinfo
->cinfo
, COL_INFO
, "CW:Bad");
372 if (pd
->props
& PWC_PAY_SIZE_BAD
)
374 if (pd
->props
& PWC_ANYOF_CW_BAD
)
376 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
378 col_append_str(pinfo
->cinfo
, COL_INFO
, "Payload size:Bad, ");
379 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d byte%s"
381 ,plurality(payload_size
, "", "s"));
384 if (pd
->props
== 0) /*omit "atm cells" etc if something is wrong*/
386 /* number of cells may be not known */
388 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d ATM cell%s"
390 ,plurality(cells
, "", "s"));
392 * Display ATM-specific attributes which are the same
393 * across all the cells in the pw packet.
394 * Meanings of values:
395 * (-1) unknown - not displayed,
396 * (-2) "not the same in all cells" - not displayed
397 * positive values - ok, displayed
399 if (pd
->cumulative
.vpi
>= 0)
400 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", VPI:%.4d", pd
->cumulative
.vpi
);
401 if (pd
->cumulative
.vci
>= 0)
402 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", VCI:%.5d", pd
->cumulative
.vci
);
403 if (pd
->cumulative
.pti
>= 0)
404 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", PTI:%.1d", pd
->cumulative
.pti
);
405 if (pd
->cumulative
.clp
>= 0)
406 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", CLP:%.1d", pd
->cumulative
.clp
);
409 if (padding_size
!= 0)
411 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %d padding"
418 prepare_pseudo_header_atm(
420 const pwatm_private_data_t
* const pdata
,
423 DISSECTOR_ASSERT(NULL
!= pdata
);
424 DISSECTOR_ASSERT(NULL
!= ph
);
426 memset(ph
, 0 , sizeof(*ph
)); /* it is OK to clear unknown values */
427 ph
->flags
= 0; /* status flags */
429 ph
->type
= TRAF_UNKNOWN
;
430 ph
->subtype
= TRAF_ST_UNKNOWN
;
431 ph
->vpi
= (pdata
->vpi
>= 0) ? pdata
->vpi
: 0 /*unknown*/;
432 ph
->vci
= (pdata
->vci
>= 0) ? pdata
->vci
: 0 /*unknown*/;
433 ph
->aal2_cid
= 0; /*not applicable*//* channel id */
434 ph
->channel
= 0; /*unknown*//* link: 0 for DTE->DCE, 1 for DCE->DTE */
435 ph
->cells
= 0; /*zero indicates that we do not have trailer info*/
436 /*user-to-user indicator & CPI*/
437 ph
->aal5t_u2u
= 0; /* all bits unknown except lsb of UU */
438 if (pdata
->aal5_sdu_frame_relay_cr_bit
)
439 { /* Let's give Frame Relay C/R bit to ATM dissector.*/
440 ph
->aal5t_u2u
|= (1<<8); /*UU octet is at << 8 in aal5t_u2u*/
442 ph
->aal5t_len
= 0; /*unknown*//* length of the packet from trailer*/
443 ph
->aal5t_chksum
= 0; /*unknown*//* checksum for AAL5 packet from trailer */
449 dissect_payload_and_padding(
453 ,const int payload_size
454 ,const int padding_size
455 ,pwatm_private_data_t
* pd
)
460 for(dissected
= 0, pd
->pw_cell_number
= 0;
461 payload_size
> dissected
;
462 ++(pd
->pw_cell_number
))
464 tvb_2
= tvb_new_subset_remaining(tvb
, dissected
);
465 dissected
+= call_dissector_with_data(dh_cell_header
, tvb_2
, pinfo
, tree
, pd
);
467 tvb_2
= tvb_new_subset_remaining(tvb
, dissected
);
469 /*dissect as oam for specific vci/pti, just like atm dissector does*/
470 if ((pd
->vci
>= 0) && (pd
->pti
>=0))
472 if (atm_is_oam_cell(pd
->vci
, pd
->pti
))
474 pd
->cell_mode_oam
= true;
478 if (pd
->cell_mode_oam
)
480 struct pw_atm_phdr ph
;
482 int bytes_to_dissect
;
483 /* prepare buffer for old-style dissector */
484 /* oam cell is always 48 bytes, but payload_size maybe too small */
485 if ((payload_size
- dissected
) >= SIZEOF_ATM_CELL_PAYLOAD
)
486 bytes_to_dissect
= SIZEOF_ATM_CELL_PAYLOAD
;
488 bytes_to_dissect
= (payload_size
- dissected
);
489 tvb_3
= tvb_new_subset_length_caplen(tvb_2
, 0, bytes_to_dissect
, -1);
490 /*aal5_sdu: disable filling columns after 1st (valid) oam cell*/
491 if (pd
->mode
== PWATM_MODE_AAL5_SDU
&& (pd
->pw_cell_number
> 0))
492 ph
.enable_fill_columns_by_atm_dissector
= false;
494 ph
.enable_fill_columns_by_atm_dissector
= true;
495 /* prepare atm pseudo header for atm OAM cell decoding */
496 prepare_pseudo_header_atm(&ph
.info
, pd
, AAL_OAMCELL
);
498 call_dissector_with_data(dh_atm_oam_cell
, tvb_3
, pinfo
, tree
, &ph
);
499 dissected
+= bytes_to_dissect
;
503 dissected
+= call_dissector(dh_cell
, tvb_2
, pinfo
, tree
);
507 if (padding_size
!= 0)
509 tvb_2
= tvb_new_subset_remaining(tvb
, -padding_size
);
510 call_dissector(dh_padding
, tvb_2
, pinfo
, tree
);
517 too_small_packet_or_notpw(tvbuff_t
* tvb
520 ,const int proto_handler
521 ,const char * const proto_name_column
)
524 packet_size
= tvb_reported_length_remaining(tvb
, 0);
527 * "4" below should be replaced by something like "min_packet_size_this_dissector"
528 * Also call to dissect_try_cw_first_nibble() should be moved before this block
530 if (packet_size
< 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
533 item
= proto_tree_add_item(tree
, proto_handler
, tvb
, 0, -1, ENC_NA
);
534 expert_add_info_format(pinfo
, item
, &ei_pw_packet_size_too_small
,
535 "PW packet size (%d) is too small to carry sensible information"
537 /* represent problems in the Packet List pane */
538 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
539 col_set_str(pinfo
->cinfo
, COL_INFO
, "Malformed: PW packet is too small");
542 if (dissect_try_cw_first_nibble(tvb
, pinfo
, tree
))
551 * NOTE. RFC describes ATM-specific byte in a cumbersome way.
552 * It is a part of CW, but at the same time, it must be repeated
553 * with each cell, _except_ first.
555 * Alternatively, ATM-specific byte may be considered as part of
556 * PW payload (i.e., as part of pw atm cell header), so we can say that
557 * it is being repeated with each cell.
559 * This dissector is written according to the latter consideration.
562 dissect_11_or_aal5_pdu(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
564 const char * proto_name_column
;
565 const char * proto_name_tree
= NULL
;
568 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
570 proto_name_column
= &shortname_11_or_aal5_pdu
[0];
571 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_11_or_aal5_pdu
, proto_name_column
))
575 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
578 * Guess encapsulation mode according to M & V bits from the 3rd byte of CW.
579 * Also adjust protocol name strings.
583 third_byte
= tvb_get_uint8(tvb
, 3);
584 if (0 == (third_byte
& 0x80 /*generic_cw.m*/))
586 if (0 != (third_byte
& 0x40 /*generic_cw.v*/))
588 pd
.mode
= PWATM_MODE_11_VPC
;
589 proto_name_column
= &shortname_11_vpc
[0];
590 proto_name_tree
= &longname_pw_atm_11_vpc
[0];
594 pd
.mode
= PWATM_MODE_11_VCC
;
595 proto_name_column
= &shortname_11_vcc
[0];
596 proto_name_tree
= &longname_pw_atm_11_vcc
[0];
601 pd
.mode
= PWATM_MODE_AAL5_PDU
;
602 proto_name_column
= &shortname_aal5_pdu
[0];
603 proto_name_tree
= &longname_pw_atm_aal5_pdu
[0];
608 /* check how "good" is this packet */
609 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
610 if (0 != (tvb_get_uint8(tvb
, 0) & 0xf0 /*bits03*/))
612 pd
.props
|= PWC_CW_BAD_BITS03
;
614 if (0 != (tvb_get_uint8(tvb
, 0) & 0x0f /*generic_cw.rsvd*/))
616 pd
.props
|= PWC_CW_BAD_RSV
;
620 * Do not dissect and validate atm-specific byte (3rd byte of CW).
621 * It will be dissected/validated as pw cell header.
625 * Decide about payload length and padding.
627 * Is padding allowed?
628 * eth header length == 14
629 * mpls label length == 4
631 * min payload length == 48
632 * => 14 + 4 + 4 + 48 == 70
634 * => no padding allowed
636 if (MODE_11(pd
.mode
))
638 int bad_padding_size
;
639 payload_size
= pd
.packet_size
- (PWC_SIZEOF_CW
-1);
640 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
641 if ((0 == cells
) || (0 != bad_padding_size
))
643 pd
.props
|= PWC_PAY_SIZE_BAD
;
648 int bad_padding_size
;
649 payload_size
= pd
.packet_size
- PWC_SIZEOF_CW
;
650 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
651 /* at least 1 cell must be present in the packet in this mode*/
652 if ((1 > cells
) || (0 != bad_padding_size
))
654 pd
.props
|= PWC_PAY_SIZE_BAD
;
656 cells
= -1; /*this value not needed anymore, suppress pinting of it*/
659 if (PWATM_MODE_AAL5_PDU
== pd
.mode
)
661 /* sub-dissectors _may_ overwrite columns in aal5_pdu mode */
662 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
663 col_clear(pinfo
->cinfo
, COL_INFO
);
664 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
669 item
= proto_tree_add_item(tree
, proto_11_or_aal5_pdu
, tvb
, 0, -1, ENC_NA
);
670 /*overwrite heading line*/
671 proto_item_set_text(item
, proto_name_tree
, 0/*-warn gcc 3.4.4*/);
672 pwc_item_append_text_n_items(item
, cells
, "good ATM cell");
675 tree2
= proto_item_add_subtree(item
, ett_encaps
);
678 item2
= proto_tree_add_boolean(tree2
679 ,VALUE_SELECTOR_VPC_VCC_PDU(pd
.mode
682 ,hf_pw_type_aal5_pdu
)
684 proto_item_set_generated(item2
);
685 if (MODE_11(pd
.mode
))
687 item2
= proto_tree_add_int(tree2
, hf_11_ncells
, tvb
, 0, 0, cells
);
688 proto_item_set_generated(item2
);
692 if (pd
.props
& PWC_PAY_SIZE_BAD
)
694 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
695 "PW payload size (%d) must be <> 0 and multiple of %d",
696 (int)payload_size
, pw_cell_size(pd
.mode
, pd
.submode
));
697 if ((payload_size
!= 0) && MODE_11(pd
.mode
))
699 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
700 "PW ATM cell [%.3d] is broken", (int)cells
);
707 tvb_2
= tvb_new_subset_length(tvb
, 0, PWC_SIZEOF_CW
);
708 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
710 tvb_2
= tvb_new_subset_remaining(tvb
, (PWC_SIZEOF_CW
-1));
711 if (MODE_11(pd
.mode
))
713 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, 0, &pd
);
717 if (payload_size
!= 0)
722 tvb_3
= tvb_new_subset_remaining(tvb_2
, 1);
723 /* prepare atm pseudo header for atm aal5 decoding */
724 prepare_pseudo_header_atm(&ph
, &pd
, AAL_5
);
725 call_dissector_with_data(dh_atm_untruncated
, tvb_3
, pinfo
, tree
, &ph
);
730 if (MODE_11(pd
.mode
))
732 /* overwrite everything written by sub-dissectors in 1:1 modes*/
733 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
734 col_clear(pinfo
->cinfo
, COL_INFO
);
735 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
738 return tvb_captured_length(tvb
);
743 dissect_aal5_sdu(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
745 const char * proto_name_column
;
749 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
751 pd
.mode
= PWATM_MODE_AAL5_SDU
;
753 proto_name_column
= &shortname_aal5_sdu
[0];
754 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_aal5_sdu
, proto_name_column
))
758 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
760 /* check how "good" is this packet */
761 /* also decide payload length from packet size and CW */
762 if (0 != (tvb_get_uint8(tvb
, 0) & 0xf0 /*bits03*/))
764 pd
.props
|= PWC_CW_BAD_BITS03
;
767 pd
.submode
= PWATM_SUBMODE_DEFAULT
;
768 if (0 != (tvb_get_uint8(tvb
, 0) & 0x08 /*preferred_cw.T*/))
770 pd
.submode
= PWATM_SUBMODE_ADMIN_CELL
;
773 if (! pref_aal5_sdu_extend_cw_length_with_rsvd
)
775 if (0 != (tvb_get_uint8(tvb
, 1) & 0xc0 /*preferred_cw.rsvd*/))
777 pd
.props
|= PWC_CW_BAD_RSV
;
782 * [ If the packet's length (defined as the length of the layer 2 payload
783 * plus the length of the control word) is less than 64 bytes, the
784 * length field MUST be set to the packet's length. Otherwise, the
785 * length field MUST be set to zero... Note that the length field
786 * is not used in the N-to-one mode and MUST be set to 0. ]
788 * Also we allow some "extensions"conducted by pref_xxx.
790 int payload_size_from_packet
;
791 int cw_len
; /*length field from cw*/
793 payload_size_from_packet
= pd
.packet_size
- PWC_SIZEOF_CW
;
794 if (pref_aal5_sdu_extend_cw_length_with_rsvd
)
796 cw_len
= tvb_get_uint8(tvb
, 1) & 0xff;
800 cw_len
= tvb_get_uint8(tvb
, 1) & 0x3f;
804 * Initial assumptions: no padding,
805 * payload size derived from psn packet size.
807 payload_size
= payload_size_from_packet
;
812 /*keep initial assumptions*/
814 else if (!pref_aal5_sdu_allow_cw_length_nonzero
815 && (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
))
818 * The "allow CW.Length != 0" option affects
819 * ATM admin cell submode only, because this submode
820 * is equal to N:1 encapsulation.
821 * CW.Length !=0 is always OK for normal (AAL5 payload) submode.
823 pd
.props
|= PWC_CW_BAD_LEN_MUST_BE_0
;
827 int payload_size_from_cw
;
828 payload_size_from_cw
= cw_len
- PWC_SIZEOF_CW
;
829 if (payload_size_from_cw
<= 0)
831 pd
.props
|= PWC_CW_BAD_PAYLEN_LE_0
;
833 else if (payload_size_from_cw
> payload_size_from_packet
)
835 pd
.props
|= PWC_CW_BAD_PAYLEN_GT_PACKET
;
840 payload_size
= payload_size_from_cw
;
841 padding_size
= payload_size_from_packet
- payload_size_from_cw
; /* >=0 */
842 if (padding_size
!= 0)
845 * Padding is not allowed in ATM admin cell submode only,
846 * because this submode is equal to N:1 encapsulation.
847 * Padding is OK for normal (AAL5 payload) submode.
849 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
851 pd
.props
|= PWC_CW_BAD_PADDING_NE_0
;
853 payload_size
= payload_size_from_packet
;
860 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
862 int bad_padding_size
;
863 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
864 /* only one atm admin cell is allowed in the packet in this mode*/
865 if ((1 != cells
) || (0 != bad_padding_size
))
867 pd
.props
|= PWC_PAY_SIZE_BAD
;
872 cells
= -1; /*unknown*/
873 /* Any size is allowed for AAL5 SDU payload */
877 /* fill columns in Packet List */
878 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
879 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
881 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, ", OAM cell");
884 col_clear(pinfo
->cinfo
, COL_INFO
);
885 col_append_pw_info(pinfo
, payload_size
, cells
, padding_size
, &pd
);
889 item
= proto_tree_add_item(tree
, proto_aal5_sdu
, tvb
, 0, -1, ENC_NA
);
892 tree2
= proto_item_add_subtree(item
, ett_encaps
);
894 item
= proto_tree_add_boolean(tree2
, hf_pw_type_aal5_sdu
, tvb
, 0, 0, true);
895 proto_item_set_generated(item
);
898 if (pd
.props
& PWC_PAY_SIZE_BAD
)
900 DISSECTOR_ASSERT(PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
);
901 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
902 "In ATM admin cell mode,"
903 " PW payload size (%d) must be == %d (exactly 1 admin cell)",
904 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
910 tvb_2
= tvb_new_subset_length(tvb
, 0, PWC_SIZEOF_CW
);
911 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
913 tvb_2
= tvb_new_subset_remaining(tvb
, PWC_SIZEOF_CW
);
914 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
916 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, padding_size
, &pd
);
918 else /*AAL5 payload*/
920 if (payload_size
!= 0)
925 tvb_3
= tvb_new_subset_length(tvb_2
, 0, payload_size
);
926 /* prepare atm pseudo header for atm aal5 decoding */
927 prepare_pseudo_header_atm(&ph
, &pd
, AAL_5
);
928 call_dissector_with_data(dh_atm_truncated
, tvb_3
, pinfo
, tree
, &ph
); /* no PAD and trailer */
930 if (padding_size
!= 0)
933 tvb_3
= tvb_new_subset_length_caplen(tvb_2
, payload_size
, padding_size
, -1);
934 call_dissector(dh_padding
, tvb_3
, pinfo
, tree
);
938 return tvb_captured_length(tvb
);
943 dissect_n1_cw(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
945 const char * proto_name_column
;
949 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
951 pd
.mode
= PWATM_MODE_N1_CW
;
953 proto_name_column
= &shortname_n1_cw
[0];
954 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_n1_cw
, proto_name_column
))
958 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
960 /* check how "good" is this packet */
961 /* also decide payload length from packet size and CW */
962 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
963 if (0 != (tvb_get_uint8(tvb
, 0) & 0xf0 /*bits03*/))
965 pd
.props
|= PWC_CW_BAD_BITS03
;
967 if (0 != (tvb_get_uint8(tvb
, 0) & 0x0f /*preferred_cw.flags*/))
969 pd
.props
|= PWC_CW_BAD_FLAGS
;
971 if (! pref_n1_cw_extend_cw_length_with_rsvd
)
973 if (0 != (tvb_get_uint8(tvb
, 1) & 0xc0 /*preferred_cw.rsvd*/))
975 pd
.props
|= PWC_CW_BAD_RSV
;
980 * [ If the packet's length (defined as the length of the layer 2 payload
981 * plus the length of the control word) is less than 64 bytes, the
982 * length field MUST be set to the packet's length. Otherwise, the
983 * length field MUST be set to zero... Note that the length field
984 * is not used in the N-to-one mode and MUST be set to 0. ]
986 * Also we allow some "extensions"conducted by pref_xxx.
988 int payload_size_from_packet
;
989 int cw_len
; /*length field from cw*/
991 payload_size_from_packet
= pd
.packet_size
- PWC_SIZEOF_CW
;
992 if (pref_n1_cw_extend_cw_length_with_rsvd
)
994 cw_len
= tvb_get_uint8(tvb
, 1) & 0xff;
998 cw_len
= tvb_get_uint8(tvb
, 1) & 0x3f;
1002 * Initial assumptions: no padding,
1003 * payload size derived from psn packet size.
1005 payload_size
= payload_size_from_packet
;
1010 /*keep initial assumptions*/
1012 else if (!pref_n1_cw_allow_cw_length_nonzero
)
1014 pd
.props
|= PWC_CW_BAD_LEN_MUST_BE_0
;
1018 int payload_size_from_cw
;
1019 payload_size_from_cw
= cw_len
- PWC_SIZEOF_CW
;
1020 if (payload_size_from_cw
<= 0)
1022 pd
.props
|= PWC_CW_BAD_PAYLEN_LE_0
;
1024 else if (payload_size_from_cw
> payload_size_from_packet
)
1026 pd
.props
|= PWC_CW_BAD_PAYLEN_GT_PACKET
;
1031 payload_size
= payload_size_from_cw
;
1032 padding_size
= payload_size_from_packet
- payload_size_from_cw
; /* >=0 */
1033 if (padding_size
!= 0)
1035 pd
.props
|= PWC_CW_BAD_PADDING_NE_0
;
1037 payload_size
= payload_size_from_packet
;
1043 int bad_padding_size
;
1044 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
1045 if ((0 == cells
) || (0 != bad_padding_size
))
1047 pd
.props
|= PWC_PAY_SIZE_BAD
;
1054 item
= proto_tree_add_item(tree
, proto_n1_cw
, tvb
, 0, -1, ENC_NA
);
1055 pwc_item_append_text_n_items(item
, cells
, "good ATM cell");
1058 tree2
= proto_item_add_subtree(item
, ett_encaps
);
1061 item2
= proto_tree_add_boolean(tree2
, hf_pw_type_n1_cw
, tvb
, 0, 0, true);
1062 proto_item_set_generated(item2
);
1063 item2
= proto_tree_add_int(tree2
, hf_n1_cw_ncells
, tvb
, 0, 0, cells
);
1064 proto_item_set_generated(item2
);
1067 if (pd
.props
& PWC_PAY_SIZE_BAD
)
1069 if (payload_size
!= 0)
1071 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
1072 "PW ATM cell [%.3d] is broken", (int)cells
);
1073 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_note
,
1074 "PW payload size (%d) must be <>0 and multiple of %d",
1075 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1079 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1080 "PW payload size (%d) must be <>0 and multiple of %d",
1081 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1088 tvb_2
= tvb_new_subset_length(tvb
, 0, PWC_SIZEOF_CW
);
1089 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
1091 tvb_2
= tvb_new_subset_remaining(tvb
, PWC_SIZEOF_CW
);
1092 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, padding_size
, &pd
);
1095 /* fill columns in Packet List */
1096 /* overwrite everything written by sub-dissectors */
1097 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
1099 col_clear(pinfo
->cinfo
, COL_INFO
);
1100 col_append_pw_info(pinfo
, payload_size
, cells
, padding_size
, &pd
);
1101 return tvb_captured_length(tvb
);
1106 dissect_n1_nocw(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
1108 const char * proto_name_column
= &shortname_n1_nocw
[0];
1111 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
1113 pd
.mode
= PWATM_MODE_N1_NOCW
;
1114 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
1116 /* check how "good" is this packet */
1117 /* also decide payload length from packet size */
1118 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
1119 payload_size
= pd
.packet_size
;
1121 int bad_padding_size
;
1122 cells
= number_of_cells(pd
.mode
, pd
.submode
, pd
.packet_size
, &bad_padding_size
);
1123 if ((cells
== 0) || (bad_padding_size
!= 0))
1125 pd
.props
|= PWC_PAY_SIZE_BAD
;
1131 item
= proto_tree_add_item(tree
, proto_n1_nocw
, tvb
, 0, -1, ENC_NA
);
1132 pwc_item_append_text_n_items(item
, cells
, "ATM cell");
1135 tree2
= proto_item_add_subtree(item
, ett_encaps
);
1138 item2
= proto_tree_add_boolean(tree2
, hf_pw_type_n1_nocw
, tvb
, 0, 0, true);
1139 proto_item_set_generated(item2
);
1140 item2
= proto_tree_add_int(tree2
, hf_n1_nocw_ncells
, tvb
, 0, 0, cells
);
1141 proto_item_set_generated(item2
);
1144 if (pd
.props
& PWC_PAY_SIZE_BAD
)
1146 if (payload_size
!= 0)
1148 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
1149 "Last PW ATM cell [%.3d] is broken", (int)cells
);
1150 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_note
,
1151 "PW payload size (%d) must be <>0 and multiple of %d",
1152 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1156 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1157 "PW payload size (%d) must be <>0 and multiple of %d",
1158 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1163 dissect_payload_and_padding(tvb
, pinfo
, tree
, payload_size
, 0, &pd
);
1165 /* fill columns in Packet List */
1166 /* overwrite everything written by sub-dissectors */
1167 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
1169 col_clear(pinfo
->cinfo
, COL_INFO
);
1170 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
1171 return tvb_captured_length(tvb
);
1176 proto_item_append_text_cwb3_fields(proto_item
* item
, const pwatm_private_data_t
* const pd
)
1178 if (NULL
== item
) return;
1179 DISSECTOR_ASSERT(NULL
!= pd
);
1180 if (pd
->cwb3
.m
>= 0)
1181 proto_item_append_text(item
, "M:%.1u " , (unsigned)(pd
->cwb3
.m
));
1182 if (pd
->cwb3
.v
>= 0)
1183 proto_item_append_text(item
, "V:%.1u " , (unsigned)(pd
->cwb3
.v
));
1184 if (pd
->cwb3
.rsv
>= 0)
1185 proto_item_append_text(item
, "RSV:%.1u ", (unsigned)(pd
->cwb3
.rsv
));
1186 if (pd
->cwb3
.u
>= 0)
1187 proto_item_append_text(item
, "U:%.1u " , (unsigned)(pd
->cwb3
.u
));
1188 if (pd
->cwb3
.e
>= 0)
1189 proto_item_append_text(item
, "EFCI:%.1u ",(unsigned)(pd
->cwb3
.e
));
1190 if (pd
->cwb3
.clp
>= 0)
1191 proto_item_append_text(item
, "CLP:%.1u ", (unsigned)(pd
->cwb3
.clp
));
1197 dissect_control_word(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
)
1199 pwatm_private_data_t
* pd
;
1201 /* Reject the packet if data is NULL */
1204 pd
= (pwatm_private_data_t
*)data
;
1207 * NB: do not touch columns -- keep info from previous dissector
1212 size
= tvb_reported_length_remaining(tvb
, 0);
1213 if (size
< PWC_SIZEOF_CW
)
1216 item
= proto_tree_add_item(tree
, proto_control_word
, tvb
, 0, -1, ENC_NA
);
1217 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1218 "Packet (size: %d) is too small to carry MPLS PW Control Word"
1220 return tvb_captured_length(tvb
);
1225 proto_item
* item_top
;
1229 item_top
= proto_tree_add_item(tree
, proto_control_word
, tvb
, 0, -1, ENC_NA
);
1230 pwc_item_append_cw(item_top
, tvb_get_ntohl(tvb
, 0), false);
1232 tree2
= proto_item_add_subtree(item_top
, ett_cw
);
1235 item
= proto_tree_add_item(tree2
, hf_cw_bits03
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1236 if (pd
->props
& PWC_CW_BAD_BITS03
)
1238 /* add item to tree (and show it) only if its value is wrong*/
1239 expert_add_info(pinfo
, item
, &ei_cw_bits03
);
1243 proto_item_set_hidden(item
); /* show only in error cases */
1247 if (MODE_N1(pd
->mode
))
1249 item
= proto_tree_add_item(tree2
, hf_pref_cw_flags
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1250 if (pd
->props
& PWC_CW_BAD_FLAGS
)
1252 expert_add_info(pinfo
, item
, &ei_pref_cw_flags
);
1255 if (pd
->mode
== PWATM_MODE_AAL5_SDU
)
1257 proto_tree_add_item(tree2
, hf_pref_cw_a5s_t
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1258 proto_tree_add_item(tree2
, hf_pref_cw_a5s_e
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1259 proto_tree_add_item(tree2
, hf_pref_cw_a5s_c
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1260 proto_tree_add_item(tree2
, hf_pref_cw_a5s_u
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1262 * rfc4717: [When FRF.8.1 Frame Relay/ATM PVC Service Interworking [RFC3916]
1263 * traffic is being transported, the CPCS-UU Least Significant Bit
1264 * (LSB) of the AAL5 CPCS-PDU may contain the Frame Relay C/R bit.
1265 * The ingress router, PE1, SHOULD copy this bit to the U bit of the
1266 * control word. The egress router, PE2, SHOULD copy the U bit to
1267 * the CPCS-UU Least Significant Bit (LSB) of the AAL5 CPCS PDU.]
1269 * Let's remember this bit (and then transfer it to ATM dissector).
1271 pd
->aal5_sdu_frame_relay_cr_bit
=
1272 (0 == (tvb_get_uint8(tvb
, 0) & 0x01 /*preferred_cw.U*/))
1277 if (MODE_11_OR_AAL5_PDU(pd
->mode
)
1278 || (MODE_N1(pd
->mode
) && !pref_n1_cw_extend_cw_length_with_rsvd
)
1279 /* for N:1 add RSV only if it is NOT used in length */
1280 || ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && !pref_aal5_sdu_extend_cw_length_with_rsvd
)
1281 /* for AAl5 SDU add RSV only if it is NOT used in length */)
1283 if (MODE_11_OR_AAL5_PDU(pd
->mode
))
1285 item
= proto_tree_add_item(tree2
1286 ,hf_generic_cw_rsv
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1290 item
= proto_tree_add_item(tree2
1291 ,hf_pref_cw_rsv
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
1294 if (pd
->props
& PWC_CW_BAD_RSV
)
1296 expert_add_info(pinfo
, item
, &ei_cw_bits03
);
1300 proto_item_set_hidden(item
); /*...and show only in error cases */
1305 if (MODE_N1(pd
->mode
)
1306 || (PWATM_MODE_AAL5_SDU
== pd
->mode
))
1309 int hf_len
= hf_pref_cw_len
;
1310 if (MODE_N1(pd
->mode
))
1312 if (pref_n1_cw_extend_cw_length_with_rsvd
)
1313 hf_len
= hf_pref_cw_rsvlen
;
1315 else /*PW_MODE_AAL5_SDU*/
1317 if (pref_aal5_sdu_extend_cw_length_with_rsvd
)
1318 hf_len
= hf_pref_cw_rsvlen
;
1320 item
= proto_tree_add_item(tree2
, hf_len
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
1322 if (pd
->props
& PWC_CW_BAD_LEN_MUST_BE_0
)
1324 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1325 "Bad Length: must be 0 for this encapsulation");
1327 if (pd
->props
& PWC_CW_BAD_PAYLEN_LE_0
)
1329 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1330 "Bad Length: too small, must be >= %d",
1331 (int)(PWC_SIZEOF_CW
+SIZEOF_N1_PW_CELL
));
1333 if (pd
->props
& PWC_CW_BAD_PAYLEN_GT_PACKET
)
1335 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1336 "Bad Length: must be <= than PSN packet size (%d)",
1337 (int)pd
->packet_size
);
1339 if (pd
->props
& PWC_CW_BAD_PADDING_NE_0
)
1341 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1342 "Bad Length: must be == PSN packet size (%d), no padding allowed",
1343 (int)pd
->packet_size
);
1347 /* sequence number */
1348 proto_tree_add_item(tree2
, hf_cw_seq
, tvb
1349 ,MODE_11_OR_AAL5_PDU(pd
->mode
) ? 1 : 2, 2, ENC_BIG_ENDIAN
);
1351 /* atm-specific byte */
1352 if (MODE_11(pd
->mode
))
1354 item
= proto_tree_add_item(tree2
, hf_gen_cw_atmbyte
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1355 expert_add_info_format(pinfo
, item
, &ei_gen_cw_atmbyte
,
1356 "ATM-specific byte of CW is fully dissected below as %s%s"
1357 ,(PWATM_MODE_11_VPC
== pd
->mode
) ? "a part of " : ""
1358 ,"PW ATM Cell Header [000]");
1360 * Note: if atm-specific byte contains something wrong
1361 * (e.g. non-zero RSV or inadequate V), CW is not
1367 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1370 tvb_2
= tvb_new_subset_remaining(tvb
, (PWC_SIZEOF_CW
-1));
1371 call_dissector_with_data(dh_cell_header
, tvb_2
, pinfo
, tree2
, pd
);
1372 proto_item_append_text(item_top
, ", ");
1373 proto_item_append_text_cwb3_fields(item_top
, pd
);
1377 return tvb_captured_length(tvb
);
1382 * This function is also used to dissect 3rd byte of CW in AAL5 PDU mode.
1385 dissect_cell_header(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
)
1387 pwatm_private_data_t
* pd
;
1388 bool is_enough_data
;
1391 /* Reject the packet if data is NULL */
1394 pd
= (pwatm_private_data_t
*)data
;
1396 pd
->vpi
= pd
->vci
= pd
->pti
= -1;
1397 pd
->cwb3
.clp
= pd
->cwb3
.m
= pd
->cwb3
.v
= pd
->cwb3
.rsv
= pd
->cwb3
.u
= pd
->cwb3
.e
= -1;
1399 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1401 if (tvb_reported_length_remaining(tvb
, 0) < 1)
1403 is_enough_data
= false;
1408 is_enough_data
= true;
1415 size
= tvb_reported_length_remaining(tvb
, 0);
1417 if (size
< pw_cell_header_size(pd
->mode
, pd
->submode
))
1419 is_enough_data
= false;
1420 dissect_size
= size
;
1424 is_enough_data
= true;
1425 dissect_size
= pw_cell_header_size(pd
->mode
, pd
->submode
);
1430 * NB: do not touch columns -- keep info from previous dissector
1433 /* Collect info for upper-level dissectors regardless of
1434 * the presence of the tree
1441 case PWATM_MODE_AAL5_SDU
:
1442 DISSECTOR_ASSERT(pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
);
1443 /*fallthrough for ATM admin cell submode only*/
1445 case PWATM_MODE_N1_CW
:
1446 case PWATM_MODE_N1_NOCW
:
1447 pd
->vpi
= (tvb_get_ntohs (tvb
, 0) >> 4);
1448 pd
->vci
= (tvb_get_ntoh24(tvb
, 1) >> 4) & 0xffff;
1449 tmp8
= (tvb_get_uint8(tvb
, 3));
1450 pd
->pti
= (tmp8
>> 1) & 0x07;
1451 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x01;
1452 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vpi
, pd
->vpi
);
1453 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vci
, pd
->vci
);
1454 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.pti
, pd
->pti
);
1455 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1457 * OAM cell mode is always used for aal5_sdu/admin_cell mode,
1458 * even if pti indicates user cell.
1461 ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && (pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
))
1462 || PTI_IS_ADMIN(pd
->pti
);
1464 case PWATM_MODE_11_VPC
:
1465 pd
->vci
= tvb_get_ntohs(tvb
, 1);
1466 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vci
, pd
->vci
);
1468 case PWATM_MODE_11_VCC
:
1469 tmp8
= (tvb_get_uint8(tvb
, 0));
1470 pd
->cwb3
.m
= (tmp8
>> 7) & 0x1;
1471 pd
->cwb3
.v
= (tmp8
>> 6) & 0x1;
1472 pd
->cwb3
.rsv
= (tmp8
>> 4) & 0x3;
1473 pd
->pti
= (tmp8
>> 1) & 0x7;
1474 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x1;
1475 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.pti
, pd
->pti
);
1476 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1478 * OAM cell mode is possible if packet contains atm cell (m == 0).
1480 pd
->cell_mode_oam
= PTI_IS_ADMIN(pd
->pti
) && (pd
->cwb3
.m
== 0);
1482 case PWATM_MODE_AAL5_PDU
:
1483 tmp8
= (tvb_get_uint8(tvb
, 0));
1484 pd
->cwb3
.m
= (tmp8
>> 7) & 0x1;
1485 pd
->cwb3
.v
= (tmp8
>> 6) & 0x1;
1486 pd
->cwb3
.rsv
= (tmp8
>> 3) & 0x7;
1487 pd
->cwb3
.u
= (tmp8
>> 2) & 0x1;
1488 pd
->cwb3
.e
= (tmp8
>> 1) & 0x1;
1489 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x1;
1490 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1493 DISSECTOR_ASSERT_NOT_REACHED();
1501 item
= proto_tree_add_item(tree
, proto_cell_header
, tvb
1505 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1507 proto_item_set_text(item
, "Third byte of Control Word"); /*overwrite heading line*/
1508 /* cwb3 fileds are appended to CW heading line, not here */
1512 proto_item_append_text(item
, " [%.3d]", pd
->pw_cell_number
);
1513 proto_item_append_text(item
, ", ");
1515 proto_item_append_text(item
, "VPI:%.4u ", (unsigned)(pd
->vpi
));
1517 proto_item_append_text(item
, "VCI:%.5u ", (unsigned)(pd
->vci
));
1519 proto_item_append_text(item
, "PTI:%.1u ", (unsigned)(pd
->pti
));
1520 proto_item_append_text_cwb3_fields(item
, pd
);
1525 tree2
= proto_item_add_subtree(item
, ett_cell_header
);
1529 if (MODE_N1(pd
->mode
)
1530 || ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && (pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
)))
1532 proto_tree_add_uint(tree2
, hf_cell_h_vpi
, tvb
, 0, 2, (unsigned)pd
->vpi
);
1533 proto_tree_add_uint(tree2
, hf_cell_h_vci
, tvb
, 1, 3, (unsigned)pd
->vci
);
1535 item2
= proto_tree_add_item(tree2
, hf_cell_h_pti
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1536 if (NULL
== try_val_to_str(pd
->pti
, atm_pt_vals
))
1538 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_undecoded
,
1539 "Unknown value of PTI field (%d) in the ATM cell header",
1542 else if ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && !PTI_IS_ADMIN(pd
->pti
))
1544 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_malformed
,
1545 "ATM admin cell is transerred;"
1546 " PTI field (%d) should be 4, 5 or 6.",
1550 proto_tree_add_item(tree2
, hf_cell_h_clp
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1552 else if (MODE_11_OR_AAL5_PDU(pd
->mode
))
1554 item2
= proto_tree_add_item(tree2
, hf_cell_h_m
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1555 if ((0 != pd
->cwb3
.m
) && MODE_11(pd
->mode
))
1557 expert_add_info(pinfo
, item2
, &ei_cell_h_m
);
1560 item2
= proto_tree_add_item(tree2
, hf_cell_h_v
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1561 if ((0 == pd
->cwb3
.v
) && (PWATM_MODE_11_VPC
== pd
->mode
))
1563 expert_add_info(pinfo
, item2
, &ei_cell_h_v_not_zero
);
1565 if ((0 != pd
->cwb3
.v
) && (PWATM_MODE_11_VCC
== pd
->mode
))
1567 expert_add_info_format(pinfo
, item2
, &ei_cell_h_v_not_one
,
1569 " V bit must be 0 to indicate that VCI is absent");
1571 if ((0 != pd
->cwb3
.v
) && (PWATM_MODE_AAL5_PDU
== pd
->mode
))
1573 expert_add_info_format(pinfo
, item2
, &ei_cell_h_v_not_one
,
1575 " V bit must be 0 to indicate that VCI is absent");
1578 item2
= proto_tree_add_item(tree2
1579 ,(PWATM_MODE_AAL5_PDU
== pd
->mode
)
1582 ,tvb
, 0, 1, ENC_BIG_ENDIAN
);
1583 if (0 != pd
->cwb3
.rsv
)
1585 expert_add_info(pinfo
, item2
, &ei_cell_h_rsv
);
1589 proto_item_set_hidden(item2
); /*...and show only in error cases */
1592 if (MODE_11(pd
->mode
))
1594 item2
= proto_tree_add_item(tree2
, hf_cell_h_pti
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1595 if (NULL
== try_val_to_str(pd
->pti
, atm_pt_vals
))
1597 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_undecoded
,
1598 "Unknown value of PTI field (%d) in the atm-specific byte"
1604 proto_tree_add_item(tree2
, hf_aal5_pdu_u
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1605 proto_tree_add_item(tree2
, hf_aal5_pdu_e
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1608 proto_tree_add_item(tree2
, hf_cell_h_clp
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1610 if (PWATM_MODE_11_VPC
== pd
->mode
)
1612 proto_tree_add_uint(tree2
, hf_cell_h_vci
, tvb
, 1, 2
1613 ,(unsigned)pd
->vci
);
1618 DISSECTOR_ASSERT_NOT_REACHED();
1623 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1624 "Not enough data (size: %d), impossible to decode",
1629 return dissect_size
;
1635 dissect_cell(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
)
1637 bool is_enough_data
;
1641 pwatm_private_data_t
* pd
= (pwatm_private_data_t
*)data
;
1643 size
= tvb_reported_length_remaining(tvb
, 0);
1644 if (size
< SIZEOF_ATM_CELL_PAYLOAD
)
1646 is_enough_data
= false;
1647 dissect_size
= size
;
1651 is_enough_data
= true;
1652 dissect_size
= SIZEOF_ATM_CELL_PAYLOAD
;
1656 * NB: do not touch columns -- keep info from previous dissector
1659 item
= proto_tree_add_item(tree
, proto_cell
, tvb
, 0, dissect_size
, ENC_NA
);
1661 proto_item_append_text(item
, " [%.3d]", pd
->pw_cell_number
);
1663 pwc_item_append_text_n_items(item
, dissect_size
, "byte");
1664 if (!is_enough_data
)
1666 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1667 "Bad length of cell payload: must be == %d",
1668 (int)SIZEOF_ATM_CELL_PAYLOAD
);
1674 tree2
= proto_item_add_subtree(item
, ett_cell
);
1675 tvb_d
= tvb_new_subset_length_caplen(tvb
, 0, dissect_size
, -1);
1676 call_data_dissector(tvb_d
, pinfo
, tree2
);
1677 item
= proto_tree_add_int(tree2
, hf_cell_payload_len
, tvb
, 0, 0, dissect_size
);
1678 proto_item_set_hidden(item
);
1681 return dissect_size
;
1686 proto_register_pw_atm_ata(void)
1688 static const value_string clp_vals
[] = {
1689 { 0, "High priority" },
1690 { 1, "Low priority" },
1693 static const value_string m_vals
[] = {
1695 { 1, "AAL5 payload" },
1698 static const value_string u_vals
[] = {
1699 { 0, "This frame does not contain the last cell of AAL5 PDU" },
1700 { 1, "This frame contains the last cell of AAL5 PDU" },
1703 static const value_string e_vals
[] = {
1704 { 0, "Congestion is not experienced" },
1705 { 1, "Congestion is experienced for one or more ATM AAL5 cells" },
1708 static hf_register_info hfa_cell_header
[] = {
1709 { &hf_cell_h_vpi
,{"VPI" ,"atm.vpi"
1710 ,FT_UINT16
,BASE_DEC
,NULL
,0
1713 { &hf_cell_h_vci
,{"VCI" ,"atm.vci"
1714 ,FT_UINT16
,BASE_DEC
,NULL
,0
1717 { &hf_cell_h_pti
,{"Payload Type" ,"atm.pti"
1718 ,FT_UINT8
,BASE_DEC
,VALS(atm_pt_vals
),0x0e
1719 ,"The 3-bit Payload Type Identifier (PTI) incorporates ATM Layer"
1720 " PTI coding of the cell. These bits are set to the value of the"
1721 " PTI of the encapsulated ATM cell."
1724 { &hf_cell_h_clp
,{"Cell Loss Priority" ,"atm.clp"
1725 ,FT_UINT8
,BASE_DEC
,VALS(clp_vals
) ,0x01
1726 ,"The Cell Loss Priority (CLP) field indicates CLP value"
1727 " of the encapsulated cell."
1730 { &hf_cell_h_m
,{"Transport Mode" ,"atm.pw_control_byte.m"
1731 ,FT_UINT8
,BASE_DEC
,VALS(m_vals
) ,0x80
1732 ,"Bit (M) of the control byte indicates whether the packet"
1733 " contains an ATM cell or a frame payload. If set to 0,"
1734 " the packet contains an ATM cell. If set to 1, the PDU"
1735 " contains an AAL5 payload."
1738 { &hf_cell_h_v
,{"VCI Present" ,"atm.pw_control_byte.v"
1739 ,FT_BOOLEAN
,8 ,TFS(&tfs_yes_no
),0x40
1740 ,"Bit (V) of the control byte indicates whether the VCI field"
1741 " is present in the packet. If set to 1, the VCI field is present"
1742 " for the cell. If set to 0, no VCI field is present."
1745 { &hf_cell_h_rsv
,{"Reserved bits" ,"atm.pw_control_byte.rsv"
1746 ,FT_UINT8
,BASE_DEC
,NULL
,0x30
1747 ,"The reserved bits should be set to 0 at the transmitter and"
1748 " ignored upon reception."
1751 { &hf_aal5_pdu_rsv
,{"Reserved bits" ,"atm.pw_control_byte.rsv"
1752 ,FT_UINT8
,BASE_DEC
,NULL
,0x38
1753 ,"The reserved bits should be set to 0 at the transmitter and"
1754 " ignored upon reception."
1757 { &hf_aal5_pdu_u
,{"U bit" ,"atm.pw_control_byte.u"
1758 ,FT_UINT8
,BASE_DEC
,VALS(u_vals
) ,0x04
1759 ,"Indicates whether this frame contains the last cell of"
1760 " an AAL5 PDU and represents the value of the ATM User-to-User"
1761 " bit for the last ATM cell of the PSN frame. Note: The ATM"
1762 " User-to-User bit is the least significant bit of the PTI"
1763 " in the ATM header."
1766 { &hf_aal5_pdu_e
,{"EFCI" ,"atm.pw_control_byte.efci"
1767 ,FT_UINT8
,BASE_DEC
,VALS(e_vals
) ,0x02
1768 ,"EFCI is set to the EFCI state of the last cell of the"
1769 " AAL5 PDU or AAL5 fragment. Note: The EFCI state is"
1770 " indicated in the middle bit of each ATM cell's PTI."
1773 static hf_register_info hfa_cell
[] = {
1774 {&hf_cell_payload_len
,{"Length" ,"atm.cell.len"
1775 ,FT_INT32
,BASE_DEC
,NULL
,0
1779 static hf_register_info hfa_n1_nocw
[] = {
1780 { &hf_n1_nocw_ncells
,
1781 { "Number of good N:1 no CW encapsulated cells", "pw.atm.n1_nocw.cells", FT_INT32
,
1782 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
1783 { &hf_pw_type_n1_nocw
,
1784 { "N:1 noCW", "pw.type.atm.n1nocw", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1788 static hf_register_info hfa_n1_cw
[] = {
1790 { "Number of good N:1 CW encapsulated cells", "pw.atm.n1_cw.cells", FT_INT32
,
1791 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
1792 { &hf_pw_type_n1_cw
,
1793 { "N:1 CW", "pw.type.atm.n1cw", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1797 static hf_register_info hfa_11_aal5pdu
[] = {
1799 { "Number of good 1:1 encapsulated cells", "pw.atm.11.cells", FT_INT32
,
1800 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
1801 { &hf_pw_type_11_vcc
,
1802 { "1:1 VCC", "pw.type.atm.11vcc", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1804 { &hf_pw_type_11_vpc
,
1805 { "1:1 VPC", "pw.type.atm.11vpc", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1807 { &hf_pw_type_aal5_pdu
,
1808 { "AAL5 PDU", "pw.type.atm.aal5pdu", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1812 static hf_register_info hfa_aal5_sdu
[] = {
1813 { &hf_pw_type_aal5_sdu
,
1814 { "AAL5 SDU", "pw.type.atm.aal5sdu", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1818 static const value_string a5s_t_vals
[] = {
1819 { 0, "AAL5 payload" },
1820 { 1, "ATM admin cell" },
1824 static const value_string a5s_e_vals
[] = {
1825 { 0, "No congestion" },
1826 { 1, "Congestion experienced" },
1830 static hf_register_info hfa_cw
[] = {
1831 { &hf_cw_bits03
,{"Bits 0 to 3" ,"pw.cw.bits03"
1832 ,FT_UINT8
,BASE_HEX
,NULL
,0xf0
1835 { &hf_pref_cw_flags
,{"Flags" ,"pw.cw.flags"
1836 ,FT_UINT8
,BASE_HEX
,NULL
,0x0f
1839 { &hf_pref_cw_a5s_t
,{"Payload type" ,"atm.pt"
1840 ,FT_UINT8
,BASE_DEC
,VALS(a5s_t_vals
),0x08
1841 ,"Bit (T) of the control word indicates whether the packet contains"
1842 " an ATM admin cell or an AAL5 payload. If T = 1, the packet"
1843 " contains an ATM admin cell, encapsulated according to the N:1"
1844 " cell relay encapsulation. If not set, the PDU"
1845 " contains an AAL5 payload."
1848 { &hf_pref_cw_a5s_e
,{"EFCI bit" ,"atm.efci"
1849 ,FT_UINT8
,BASE_DEC
,VALS(a5s_e_vals
),0x04
1850 ,"The ingress router sets this bit to 1 if the EFCI bit"
1851 " of the final cell of those that transported the AAL5 CPCS-SDU is"
1852 " set to 1, or if the EFCI bit of the single ATM cell to be"
1853 " transported in the packet is set to 1. Otherwise, this bit"
1857 { &hf_pref_cw_a5s_c
,{"CLP bit" ,"atm.clp"
1858 ,FT_UINT8
,BASE_DEC
,VALS(clp_vals
) ,0x02
1859 ,"The ingress router sets this bit to 1 if the CLP bit"
1860 " of any of the ATM cells that transported the AAL5 CPCS-SDU is set"
1861 " to 1, or if the CLP bit of the single ATM cell to be transported"
1862 " in the packet is set to 1. Otherwise this bit is set to 0."
1865 { &hf_pref_cw_a5s_u
,{"U bit (Command/Response)" ,"pw.cw.aal5sdu.u"
1866 ,FT_UINT8
,BASE_DEC
,NULL
,0x01
1867 ,"When FRF.8.1 Frame Relay/ATM PVC Service Interworking [RFC3916]"
1868 " traffic is being transported, the Least-Significant Bit of CPCS-UU"
1869 " of the AAL5 CPCS-PDU may contain the Frame Relay C/R bit."
1870 " The ingress router copies this bit here."
1873 { &hf_pref_cw_rsv
,{"Reserved bits" ,"pw.cw.rsv"
1874 ,FT_UINT8
,BASE_DEC
,NULL
,0xc0
1877 { &hf_generic_cw_rsv
,{"Reserved bits" ,"pw.cw.rsv"
1878 ,FT_UINT8
,BASE_DEC
,NULL
,0x0f
1881 { &hf_pref_cw_len
,{"Length" ,"pw.cw.length"
1882 ,FT_UINT8
,BASE_DEC
,NULL
,0x3f
1885 { &hf_pref_cw_rsvlen
,{"Length (extended)" ,"pw.cw.length"
1886 ,FT_UINT8
,BASE_DEC
,NULL
,0x0
1889 { &hf_cw_seq
,{"Sequence number" ,"pw.cw.seqno"
1890 ,FT_UINT16
,BASE_DEC
,NULL
,0
1893 { &hf_gen_cw_atmbyte
,{"ATM-specific byte" ,"pw.cw.3rd_byte"
1894 ,FT_UINT8
,BASE_HEX
,NULL
,0x0
1897 static int *ett_array
[] = {
1903 static ei_register_info ei
[] = {
1904 { &ei_pw_packet_size_too_small
, { "pw.packet_size_too_small", PI_MALFORMED
, PI_ERROR
, "PW packet size too small", EXPFILL
}},
1905 { &ei_pw_payload_size_invalid_error
, { "pw.payload.size_invalid", PI_MALFORMED
, PI_ERROR
, "PW payload size invalid", EXPFILL
}},
1906 { &ei_cell_broken
, { "atm.cell_broken", PI_MALFORMED
, PI_ERROR
, "PW ATM cell is broken", EXPFILL
}},
1907 { &ei_pw_payload_size_invalid_note
, { "pw.payload.size_invalid", PI_MALFORMED
, PI_NOTE
, "PW payload size invalid", EXPFILL
}},
1908 { &ei_cw_bits03
, { "pw.cw.bits03.not_zero", PI_MALFORMED
, PI_ERROR
, "Bits 0..3 of Control Word must be 0", EXPFILL
}},
1909 { &ei_pref_cw_flags
, { "pw.cw.flags.not_zero", PI_MALFORMED
, PI_ERROR
, "Flags must be 0 for PW ATM N:1 encapsulation", EXPFILL
}},
1910 { &ei_pref_cw_len
, { "pw.cw.length.invalid", PI_MALFORMED
, PI_ERROR
, "Bad Length: must be 0 for this encapsulation", EXPFILL
}},
1911 { &ei_cell_h_pti_undecoded
, { "atm.pti.invalid", PI_UNDECODED
, PI_WARN
, "Unknown value of PTI field in the ATM cell header", EXPFILL
}},
1912 { &ei_cell_h_pti_malformed
, { "atm.pti.invalid", PI_MALFORMED
, PI_ERROR
, "ATM admin cell is transerred. PTI field should be 4, 5 or 6.", EXPFILL
}},
1913 { &ei_cell_h_m
, { "atm.pw_control_byte.m.not_zero", PI_MALFORMED
, PI_ERROR
, "1:1 mode: M bit must be 0 to distinguish from AAL5 PDU mode", EXPFILL
}},
1914 { &ei_cell_h_v_not_zero
, { "atm.pw_control_byte.v.not_one", PI_MALFORMED
, PI_ERROR
, "1:1 VPC mode: V bit must be 1 to indicate that VCI is present", EXPFILL
}},
1915 { &ei_cell_h_v_not_one
, { "atm.pw_control_byte.v.not_zero", PI_MALFORMED
, PI_ERROR
, "1:1 VCC mode: V bit must be 0 to indicate that VCI is absent", EXPFILL
}},
1916 { &ei_cell_h_rsv
, { "atm.pw_control_byte.rsv.not_zero", PI_MALFORMED
, PI_ERROR
, "Reserved bits in the 3rd byte of CW must be 0", EXPFILL
}},
1917 { &ei_gen_cw_atmbyte
, { "pw.cw.atmbyte", PI_PROTOCOL
, PI_NOTE
, "ATM-specific byte of CW is fully dissected below", EXPFILL
}},
1920 expert_module_t
* expert_cell
;
1923 proto_register_protocol(pwc_longname_pw_atm_n1_cw
1926 proto_11_or_aal5_pdu
=
1927 proto_register_protocol(pwc_longname_pw_atm_11_or_aal5_pdu
1928 ,shortname_11_or_aal5_pdu
1929 ,"mplspwatm11_or_aal5pdu");
1931 proto_register_protocol(pwc_longname_pw_atm_aal5_sdu
1933 ,"mplspwatmaal5sdu");
1935 proto_register_protocol(pwc_longname_pw_atm_n1_nocw
1937 ,"mplspwatmn1nocw");
1938 proto_control_word
=
1939 proto_register_protocol("MPLS PW ATM Control Word"
1940 ,"MPLS PW ATM Control Word"
1941 ,"mplspwatmcontrolword");
1943 proto_register_protocol("MPLS PW ATM Cell Header"
1944 ,"MPLS PW ATM Cell Header"
1945 ,"mplspwatmcellheader");
1947 proto_register_protocol("ATM Cell"
1951 proto_register_field_array( proto_cell
,hfa_cell
,array_length(hfa_cell
));
1952 expert_cell
= expert_register_protocol(proto_cell
);
1953 expert_register_field_array(expert_cell
, ei
, array_length(ei
));
1955 proto_register_field_array( proto_cell_header
,hfa_cell_header
,array_length(hfa_cell_header
));
1956 proto_register_field_array( proto_control_word
,hfa_cw
,array_length(hfa_cw
));
1957 proto_register_field_array( proto_n1_nocw
,hfa_n1_nocw
,array_length(hfa_n1_nocw
));
1958 proto_register_field_array( proto_n1_cw
,hfa_n1_cw
,array_length(hfa_n1_cw
));
1959 proto_register_field_array( proto_11_or_aal5_pdu
,hfa_11_aal5pdu
,array_length(hfa_11_aal5pdu
));
1960 proto_register_field_array( proto_aal5_sdu
,hfa_aal5_sdu
,array_length(hfa_aal5_sdu
));
1962 proto_register_subtree_array(ett_array
, array_length(ett_array
));
1964 dh_control_word
= register_dissector("mpls_pw_atm_control_word" ,dissect_control_word
,proto_control_word
);
1965 dh_cell
= register_dissector("mpls_pw_atm_cell" ,dissect_cell
,proto_cell
);
1966 dh_cell_header
= register_dissector("mpls_pw_atm_cell_header",dissect_cell_header
,proto_cell_header
);
1967 register_dissector("mpls_pw_atm_aal5_sdu" ,dissect_aal5_sdu
,proto_aal5_sdu
);
1968 register_dissector("mpls_pw_atm_11_or_aal5_pdu" ,dissect_11_or_aal5_pdu
,proto_11_or_aal5_pdu
);
1969 register_dissector("mpls_pw_atm_n1_cw" ,dissect_n1_cw
,proto_n1_cw
);
1970 register_dissector("mpls_pw_atm_n1_nocw" ,dissect_n1_nocw
,proto_n1_nocw
);
1972 static const char description_allow_cw_length_nonzero
[] =
1973 "Enable to allow non-zero Length in Control Word."
1974 " This may be needed to correctly decode traffic from some legacy devices"
1975 " which generate non-zero Length even if there is no padding in the packet."
1976 " Note that Length should have proper value (dissector checks this anyway)."
1978 "Disable to blame all packets with CW.Length <> 0. This conforms to RFC4717."
1980 static const char description_extend_cw_length_with_rsvd
[] =
1981 "Enable to use reserved bits (8..9) of Control Word as an extension of CW.Length."
1982 " This may be needed to correctly decode traffic from some legacy devices"
1983 " which uses reserved bits as extension of Length"
1985 "Disable to blame all packets with CW.Reserved <> 0. This conforms to RFC4717."
1987 module_t
* module_n1_cw
;
1988 module_t
* module_aal5_sdu
;
1990 module_n1_cw
= prefs_register_protocol(proto_n1_cw
,NULL
);
1991 prefs_register_bool_preference(module_n1_cw
1992 ,"allow_cw_length_nonzero"
1993 ,"Allow CW.Length <> 0"
1994 ,&description_allow_cw_length_nonzero
[0]
1995 ,&pref_n1_cw_allow_cw_length_nonzero
);
1996 prefs_register_bool_preference(module_n1_cw
1997 ,"extend_cw_length_with_rsvd"
1998 ,"Use CW.Reserved as extension of CW.Length"
1999 ,&description_extend_cw_length_with_rsvd
[0]
2000 ,&pref_n1_cw_extend_cw_length_with_rsvd
);
2002 module_aal5_sdu
= prefs_register_protocol(proto_aal5_sdu
,NULL
);
2003 prefs_register_bool_preference(module_aal5_sdu
2004 ,"allow_cw_length_nonzero_aal5"
2005 ,"Allow CW.Length <> 0"
2006 ,&description_allow_cw_length_nonzero
[0]
2007 ,&pref_aal5_sdu_allow_cw_length_nonzero
);
2008 prefs_register_bool_preference(module_aal5_sdu
2009 ,"extend_cw_length_with_rsvd_aal5"
2010 ,"Use CW.Reserved as extension of CW.Length"
2011 ,&description_extend_cw_length_with_rsvd
[0]
2012 ,&pref_aal5_sdu_extend_cw_length_with_rsvd
);
2018 proto_reg_handoff_pw_atm_ata(void)
2020 dissector_handle_t h
;
2021 h
= find_dissector("mpls_pw_atm_n1_cw");
2022 dissector_add_for_decode_as( "mpls.label", h
);
2023 dissector_add_for_decode_as( "mpls.pfn", h
);
2024 h
= find_dissector("mpls_pw_atm_n1_nocw");
2025 dissector_add_for_decode_as( "mpls.label", h
);
2026 dissector_add_for_decode_as( "mpls.pfn", h
);
2027 h
= find_dissector("mpls_pw_atm_11_or_aal5_pdu");
2028 dissector_add_for_decode_as( "mpls.label", h
);
2029 dissector_add_for_decode_as( "mpls.pfn", h
);
2030 h
= find_dissector("mpls_pw_atm_aal5_sdu");
2031 dissector_add_for_decode_as( "mpls.label", h
);
2032 dissector_add_for_decode_as( "mpls.pfn", h
);
2034 dh_atm_truncated
= find_dissector("atm_pw_truncated");
2035 dh_atm_untruncated
= find_dissector("atm_pw_untruncated");
2036 dh_atm_oam_cell
= find_dissector("atm_pw_oam_cell");
2037 dh_padding
= find_dissector("pw_padding");
2041 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2046 * indent-tabs-mode: t
2049 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2050 * :indentSize=8:tabSize=8:noTabs=false: