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>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 - ATM N-to-One Cell Mode (with CW)
33 - ATM N-to-One Cell Mode (no CW)
34 - ATM One-to-One Cell Mode
42 #include <epan/packet.h>
43 #include <epan/expert.h>
44 #include <epan/prefs.h>
46 #include <wiretap/wtap.h> /*for atm pseudo header*/
47 #include "packet-mpls.h"
48 #include "packet-atm.h"
49 #include "packet-pw-atm.h"
50 #include "packet-pw-common.h"
52 static gint proto_n1_nocw
= -1;
53 static gint proto_n1_cw
= -1;
54 static gint proto_11_or_aal5_pdu
= -1;
55 static gint proto_aal5_sdu
= -1;
56 /* subordinate dissectors: */
57 static gint proto_control_word
= -1;
58 static gint proto_cell_header
= -1;
59 static gint proto_cell
= -1;
61 static gint ett_encaps
= -1;
62 static gint ett_cw
= -1;
63 static gint ett_cell_header
= -1;
64 static gint ett_cell
= -1;
66 static int hf_pw_type_n1_cw
= -1;
67 static int hf_pw_type_n1_nocw
= -1;
68 static int hf_pw_type_11_vcc
= -1;
69 static int hf_pw_type_11_vpc
= -1;
70 static int hf_pw_type_aal5_sdu
= -1;
71 static int hf_pw_type_aal5_pdu
= -1;
73 static int hf_cell_h_vpi
= -1;
74 static int hf_cell_h_vci
= -1;
75 static int hf_cell_h_pti
= -1;
76 static int hf_cell_h_clp
= -1;
77 static int hf_cell_h_m
= -1;
78 static int hf_cell_h_v
= -1;
79 static int hf_cell_h_rsv
= -1;
80 static int hf_aal5_pdu_rsv
= -1;
81 static int hf_aal5_pdu_u
= -1;
82 static int hf_aal5_pdu_e
= -1;
84 static int hf_cw_bits03
= -1;
85 static int hf_pref_cw_rsv
= -1;
86 static int hf_generic_cw_rsv
= -1;
87 static int hf_pref_cw_flags
= -1;
88 static int hf_pref_cw_a5s_t
= -1;
89 static int hf_pref_cw_a5s_e
= -1;
90 static int hf_pref_cw_a5s_c
= -1;
91 static int hf_pref_cw_a5s_u
= -1;
92 static int hf_pref_cw_len
= -1;
93 static int hf_pref_cw_rsvlen
= -1;
94 static int hf_cw_seq
= -1;
95 static int hf_n1_cw_ncells
= -1;
96 static int hf_n1_nocw_ncells
= -1;
97 static int hf_11_ncells
= -1;
98 static int hf_gen_cw_atmbyte
= -1;
99 static int hf_cell_payload_len
= -1;
101 static expert_field ei_cell_h_v_not_one
= EI_INIT
;
102 static expert_field ei_cell_h_pti_undecoded
= EI_INIT
;
103 static expert_field ei_pref_cw_flags
= EI_INIT
;
104 static expert_field ei_cell_h_v_not_zero
= EI_INIT
;
105 static expert_field ei_pw_payload_size_invalid_note
= EI_INIT
;
106 static expert_field ei_pw_payload_size_invalid_error
= EI_INIT
;
107 static expert_field ei_cell_h_pti_malformed
= EI_INIT
;
108 static expert_field ei_cell_h_rsv
= EI_INIT
;
109 static expert_field ei_cell_broken
= EI_INIT
;
110 static expert_field ei_cell_h_m
= EI_INIT
;
111 static expert_field ei_cw_bits03
= EI_INIT
;
112 static expert_field ei_pw_packet_size_too_small
= EI_INIT
;
113 static expert_field ei_pref_cw_len
= EI_INIT
;
115 static dissector_handle_t dh_cell
;
116 static dissector_handle_t dh_cell_header
;
117 static dissector_handle_t dh_control_word
;
118 static dissector_handle_t dh_atm_truncated
;
119 static dissector_handle_t dh_atm_untruncated
;
120 static dissector_handle_t dh_atm_oam_cell
;
121 static dissector_handle_t dh_padding
;
122 static dissector_handle_t dh_data
;
124 #define PTI_IS_ADMIN(pti) ((pti) == 4 || (pti) == 5 || (pti) == 6) /*see atm_pt_vals[]*/
126 #define MODE_11(mode) (PWATM_MODE_11_VCC == (mode) || PWATM_MODE_11_VPC == (mode))
127 #define MODE_N1(mode) (PWATM_MODE_N1_NOCW == (mode)|| PWATM_MODE_N1_CW == (mode))
128 #define MODE_11_OR_AAL5_PDU(mode) (MODE_11(mode) || PWATM_MODE_AAL5_PDU == (mode))
130 #define VALUE_SELECTOR_VPC_VCC_PDU(mode,val_vpc,val_vcc,val_pdu)\
131 ((PWATM_MODE_11_VPC == (mode)) \
133 : ((PWATM_MODE_11_VCC == (mode)) \
135 : ((PWATM_MODE_AAL5_PDU == (mode)) \
142 #define UPDATE_CUMULATIVE_VALUE(cumulative_val,new_val)\
145 if (-2 >= (cumulative_val))\
148 else if (-1 == (cumulative_val))\
150 (cumulative_val) = (new_val);\
152 else if ((new_val) != (cumulative_val))\
154 (cumulative_val) = -2;\
159 #define SIZEOF_ATM_CELL_PAYLOAD 48
160 #define SIZEOF_N1_PW_CELL_HEADER 4
161 #define SIZEOF_11_VCC_PW_CELL_HEADER 1
162 #define SIZEOF_11_VPC_PW_CELL_HEADER 3
163 #define SIZEOF_N1_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_N1_PW_CELL_HEADER)
164 #define SIZEOF_11_VCC_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_11_VCC_PW_CELL_HEADER)
165 #define SIZEOF_11_VPC_PW_CELL (SIZEOF_ATM_CELL_PAYLOAD+SIZEOF_11_VPC_PW_CELL_HEADER)
167 const char pwc_longname_pw_atm_n1_cw
[] = "MPLS PW ATM N-to-One encapsulation, with CW";
168 const char pwc_longname_pw_atm_n1_nocw
[] = "MPLS PW ATM N-to-One encapsulation, no CW";
169 const char pwc_longname_pw_atm_11_or_aal5_pdu
[] = "MPLS PW ATM One-to-One or AAL5 PDU encapsulation";
170 const char pwc_longname_pw_atm_aal5_sdu
[] = "MPLS PW ATM AAL5 CPCS-SDU mode encapsulation";
172 static const char longname_pw_atm_11_vcc
[] = "MPLS PW ATM One-to-One VCC Cell Transport";
173 static const char longname_pw_atm_11_vpc
[] = "MPLS PW ATM One-to-One VPC Cell Transport";
174 static const char longname_pw_atm_aal5_pdu
[] = "MPLS PW ATM AAL5 PDU encapsulation";
176 static const char shortname_n1_cw
[] = "MPLS PW ATM N:1 CW";
177 static const char shortname_n1_nocw
[] = "MPLS PW ATM N:1 no CW";
178 static const char shortname_11_or_aal5_pdu
[] = "MPLS PW ATM 1:1 / AAL5 PDU";
179 static const char shortname_11_vpc
[] = "MPLS PW ATM 1:1 VPC";
180 static const char shortname_11_vcc
[] = "MPLS PW ATM 1:1 VCC";
181 static const char shortname_aal5_sdu
[] = "MPLS PW ATM AAL5 SDU";
182 static const char shortname_aal5_pdu
[] = "MPLS PW ATM AAL5 PDU";
185 * These options are needed to support Nokia AXE and stuff alike.
186 * Note that these options will affect PW type auto-guessing, if such heuristic
187 * implemented in the future.
189 static gboolean pref_n1_cw_allow_cw_length_nonzero
= FALSE
;
190 static gboolean pref_n1_cw_extend_cw_length_with_rsvd
= FALSE
;
191 static gboolean pref_aal5_sdu_allow_cw_length_nonzero
= FALSE
;
192 static gboolean pref_aal5_sdu_extend_cw_length_with_rsvd
= FALSE
;
196 pw_cell_size(const pwatm_mode_t mode
, const pwatm_submode_t submode
)
200 case PWATM_MODE_N1_NOCW
:
201 case PWATM_MODE_N1_CW
:
202 return SIZEOF_N1_PW_CELL
;
203 case PWATM_MODE_11_VCC
:
204 return SIZEOF_11_VCC_PW_CELL
;
205 case PWATM_MODE_11_VPC
:
206 return SIZEOF_11_VPC_PW_CELL
;
207 case PWATM_MODE_AAL5_PDU
:
208 /* AAL5 PDU size is n*48 bytes */
209 return SIZEOF_ATM_CELL_PAYLOAD
;
210 case PWATM_MODE_AAL5_SDU
:
211 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
213 return SIZEOF_N1_PW_CELL
; /*n:1 encapsulation is used for admin cells*/
217 DISSECTOR_ASSERT_NOT_REACHED();
221 DISSECTOR_ASSERT_NOT_REACHED();
227 pw_cell_header_size(const pwatm_mode_t mode
, const pwatm_submode_t submode
)
231 case PWATM_MODE_N1_NOCW
:
232 case PWATM_MODE_N1_CW
:
233 return SIZEOF_N1_PW_CELL_HEADER
;
234 case PWATM_MODE_11_VCC
:
235 return SIZEOF_11_VCC_PW_CELL_HEADER
;
236 case PWATM_MODE_11_VPC
:
237 return SIZEOF_11_VPC_PW_CELL_HEADER
;
238 case PWATM_MODE_AAL5_SDU
:
239 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
241 return SIZEOF_N1_PW_CELL_HEADER
; /*n:1 encapsulation is used for admin cells*/
245 DISSECTOR_ASSERT_NOT_REACHED();
248 case PWATM_MODE_AAL5_PDU
: /*not applicable*/
250 DISSECTOR_ASSERT_NOT_REACHED();
256 number_of_cells(const pwatm_mode_t mode
257 ,const pwatm_submode_t submode
258 ,const gint payload_size
259 ,gint
* const remainder_size
)
263 DISSECTOR_ASSERT(payload_size
>= 0);
267 case PWATM_MODE_N1_NOCW
:
268 case PWATM_MODE_N1_CW
:
269 case PWATM_MODE_11_VCC
:
270 case PWATM_MODE_11_VPC
:
271 case PWATM_MODE_AAL5_PDU
:
272 cells
= payload_size
/ pw_cell_size(mode
, submode
);
273 *remainder_size
= payload_size
- (cells
* pw_cell_size(mode
, submode
));
275 case PWATM_MODE_AAL5_SDU
:
276 if (PWATM_SUBMODE_ADMIN_CELL
== submode
)
278 cells
= payload_size
/ pw_cell_size(mode
, submode
);
279 if (cells
> 1) cells
= 1; /*max. 1 admin cell may be present in aal5 sdu mode */
280 *remainder_size
= payload_size
- (cells
* pw_cell_size(mode
, submode
));
289 DISSECTOR_ASSERT_NOT_REACHED();
290 *remainder_size
= payload_size
;
298 col_append_pw_info(packet_info
* pinfo
299 ,const int payload_size
301 ,const int padding_size
302 ,pwatm_private_data_t
* pd
)
304 if (pd
->props
& PWC_ANYOF_CW_BAD
)
306 col_append_str(pinfo
->cinfo
, COL_INFO
, "CW:Bad");
309 if (pd
->props
& PWC_PAY_SIZE_BAD
)
311 if (pd
->props
& PWC_ANYOF_CW_BAD
)
313 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
315 col_append_str(pinfo
->cinfo
, COL_INFO
, "Payload size:Bad, ");
316 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d byte%s"
318 ,plurality(payload_size
, "", "s"));
321 if (pd
->props
== 0) /*omit "atm cells" etc if something is wrong*/
323 /* number of cells may be not known */
325 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d ATM cell%s"
327 ,plurality(cells
, "", "s"));
329 * Display ATM-specific attributes which are the same
330 * across all the cells in the pw packet.
331 * Meanings of values:
332 * (-1) unknown - not displayed,
333 * (-2) "not the same in all cells" - not displayed
334 * positive values - ok, displayed
336 if (pd
->cumulative
.vpi
>= 0)
337 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", VPI:%.4d", pd
->cumulative
.vpi
);
338 if (pd
->cumulative
.vci
>= 0)
339 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", VCI:%.5d", pd
->cumulative
.vci
);
340 if (pd
->cumulative
.pti
>= 0)
341 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", PTI:%.1d", pd
->cumulative
.pti
);
342 if (pd
->cumulative
.clp
>= 0)
343 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", CLP:%.1d", pd
->cumulative
.clp
);
346 if (padding_size
!= 0)
348 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %d padding"
355 prepare_pseudo_header_atm(
356 union wtap_pseudo_header
* const ph
,
357 const pwatm_private_data_t
* const pdata
,
360 DISSECTOR_ASSERT(NULL
!= pdata
);
361 DISSECTOR_ASSERT(NULL
!= ph
);
363 memset(ph
, 0 , sizeof(*ph
)); /* it is OK to clear unknown values */
364 ph
->atm
.flags
= 0; /* status flags */
366 ph
->atm
.type
= TRAF_UNKNOWN
;
367 ph
->atm
.subtype
= TRAF_ST_UNKNOWN
;
368 ph
->atm
.vpi
= (pdata
->vpi
>= 0) ? pdata
->vpi
: 0 /*unknown*/;
369 ph
->atm
.vci
= (pdata
->vci
>= 0) ? pdata
->vci
: 0 /*unknown*/;
370 ph
->atm
.aal2_cid
= 0; /*not applicable*//* channel id */
371 ph
->atm
.channel
= 0; /*unknown*//* link: 0 for DTE->DCE, 1 for DCE->DTE */
372 ph
->atm
.cells
= 0; /*zero indicates that we do not have trailer info*/
373 /*user-to-user indicator & CPI*/
374 ph
->atm
.aal5t_u2u
= 0; /* all bits unknown except lsb of UU */
375 if (pdata
->aal5_sdu_frame_relay_cr_bit
)
376 { /* Let's give Frame Relay C/R bit to ATM dissector.*/
377 ph
->atm
.aal5t_u2u
|= (1<<8); /*UU octet is at << 8 in aal5t_u2u*/
379 ph
->atm
.aal5t_len
= 0; /*unknown*//* length of the packet from trailer*/
380 ph
->atm
.aal5t_chksum
= 0; /*unknown*//* checksum for AAL5 packet from trailer */
386 dissect_payload_and_padding(
390 ,const gint payload_size
391 ,const gint padding_size
392 ,pwatm_private_data_t
* pd
)
397 for(dissected
= 0, pd
->pw_cell_number
= 0;
398 payload_size
> dissected
;
399 ++(pd
->pw_cell_number
))
401 tvb_2
= tvb_new_subset_remaining(tvb
, dissected
);
402 dissected
+= call_dissector_with_data(dh_cell_header
, tvb_2
, pinfo
, tree
, pd
);
404 tvb_2
= tvb_new_subset_remaining(tvb
, dissected
);
406 /*dissect as oam for specific vci/pti, just like atm dissector does*/
407 if ((pd
->vci
>= 0) && (pd
->pti
>=0))
409 if (atm_is_oam_cell(pd
->vci
, pd
->pti
))
411 pd
->cell_mode_oam
= TRUE
;
415 if (pd
->cell_mode_oam
)
417 union wtap_pseudo_header
* pseudo_header_save
;
418 union wtap_pseudo_header ph
;
420 int bytes_to_dissect
;
421 /* prepare buffer for old-style dissector */
422 /* oam cell is always 48 bytes, but payload_size maybe too small */
423 if ((payload_size
- dissected
) >= SIZEOF_ATM_CELL_PAYLOAD
)
424 bytes_to_dissect
= SIZEOF_ATM_CELL_PAYLOAD
;
426 bytes_to_dissect
= (payload_size
- dissected
);
427 tvb_3
= tvb_new_subset(tvb_2
, 0, bytes_to_dissect
, -1);
428 /*aal5_sdu: disable filling columns after 1st (valid) oam cell*/
429 if (pd
->mode
== PWATM_MODE_AAL5_SDU
&& (pd
->pw_cell_number
> 0))
431 pd
->enable_fill_columns_by_atm_dissector
= FALSE
;
433 /* save & prepare new pseudo header for atm aal5 decoding */
434 pseudo_header_save
= pinfo
->pseudo_header
;
435 pinfo
->pseudo_header
= &ph
;
436 prepare_pseudo_header_atm(&ph
, pd
, AAL_OAMCELL
);
438 call_dissector_with_data(dh_atm_oam_cell
, tvb_3
, pinfo
, tree
, pd
);
439 dissected
+= bytes_to_dissect
;
440 /* restore pseudo header */
441 pinfo
->pseudo_header
= pseudo_header_save
;
445 dissected
+= call_dissector(dh_cell
, tvb_2
, pinfo
, tree
);
449 if (padding_size
!= 0)
451 tvb_2
= tvb_new_subset_remaining(tvb
, -padding_size
);
452 call_dissector(dh_padding
, tvb_2
, pinfo
, tree
);
459 too_small_packet_or_notpw(tvbuff_t
* tvb
462 ,const int proto_handler
463 ,const char * const proto_name_column
)
466 packet_size
= tvb_reported_length_remaining(tvb
, 0);
469 * "4" below should be replaced by something like "min_packet_size_this_dissector"
470 * Also call to dissect_try_cw_first_nibble() should be moved before this block
472 if (packet_size
< 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
475 item
= proto_tree_add_item(tree
, proto_handler
, tvb
, 0, -1, ENC_NA
);
476 expert_add_info_format(pinfo
, item
, &ei_pw_packet_size_too_small
,
477 "PW packet size (%d) is too small to carry sensible information"
479 /* represent problems in the Packet List pane */
480 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
481 col_set_str(pinfo
->cinfo
, COL_INFO
, "Malformed: PW packet is too small");
484 if (dissect_try_cw_first_nibble(tvb
, pinfo
, tree
))
493 * NOTE. RFC describes ATM-specific byte in a cumbersome way.
494 * It is a part of CW, but at the same time, it must be repeated
495 * with each cell, _except_ first.
497 * Alternatively, ATM-specific byte may be considered as part of
498 * PW payload (i.e., as part of pw atm cell header), so we can say that
499 * it is being repeated with each cell.
501 * This dissector is written according to the latter consideration.
504 dissect_11_or_aal5_pdu(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
)
506 const char * proto_name_column
;
507 const char * proto_name_tree
= NULL
;
510 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
512 proto_name_column
= &shortname_11_or_aal5_pdu
[0];
513 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_11_or_aal5_pdu
, proto_name_column
))
517 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
520 * Guess encapsulation mode according to M & V bits from the 3rd byte of CW.
521 * Also adjust protocol name strings.
525 third_byte
= tvb_get_guint8(tvb
, 3);
526 if (0 == (third_byte
& 0x80 /*generic_cw.m*/))
528 if (0 != (third_byte
& 0x40 /*generic_cw.v*/))
530 pd
.mode
= PWATM_MODE_11_VPC
;
531 proto_name_column
= &shortname_11_vpc
[0];
532 proto_name_tree
= &longname_pw_atm_11_vpc
[0];
536 pd
.mode
= PWATM_MODE_11_VCC
;
537 proto_name_column
= &shortname_11_vcc
[0];
538 proto_name_tree
= &longname_pw_atm_11_vcc
[0];
543 pd
.mode
= PWATM_MODE_AAL5_PDU
;
544 proto_name_column
= &shortname_aal5_pdu
[0];
545 proto_name_tree
= &longname_pw_atm_aal5_pdu
[0];
550 /* check how "good" is this packet */
551 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
552 if (0 != (tvb_get_guint8(tvb
, 0) & 0xf0 /*bits03*/))
554 pd
.props
|= PWC_CW_BAD_BITS03
;
556 if (0 != (tvb_get_guint8(tvb
, 0) & 0x0f /*generic_cw.rsvd*/))
558 pd
.props
|= PWC_CW_BAD_RSV
;
562 * Do not dissect and validate atm-specific byte (3rd byte of CW).
563 * It will be dissected/validated as pw cell header.
567 * Decide about payload length and padding.
569 * Is padding allowed?
570 * eth header length == 14
571 * mpls label length == 4
573 * min payload length == 48
574 * => 14 + 4 + 4 + 48 == 70
576 * => no padding allowed
578 if (MODE_11(pd
.mode
))
580 gint bad_padding_size
;
581 payload_size
= pd
.packet_size
- (PWC_SIZEOF_CW
-1);
582 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
583 if ((0 == cells
) || (0 != bad_padding_size
))
585 pd
.props
|= PWC_PAY_SIZE_BAD
;
590 gint bad_padding_size
;
591 payload_size
= pd
.packet_size
- PWC_SIZEOF_CW
;
592 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
593 /* at least 1 cell must be present in the packet in this mode*/
594 if ((1 > cells
) || (0 != bad_padding_size
))
596 pd
.props
|= PWC_PAY_SIZE_BAD
;
598 cells
= -1; /*this value not needed anymore, suppress pinting of it*/
601 if (PWATM_MODE_AAL5_PDU
== pd
.mode
)
603 /* sub-dissectors _may_ overwrite columns in aal5_pdu mode */
604 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
605 col_clear(pinfo
->cinfo
, COL_INFO
);
606 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
611 item
= proto_tree_add_item(tree
, proto_11_or_aal5_pdu
, tvb
, 0, -1, ENC_NA
);
612 /*overwrite heading line*/
613 proto_item_set_text(item
, proto_name_tree
, 0/*-warn gcc 3.4.4*/);
614 pwc_item_append_text_n_items(item
, cells
, "good ATM cell");
617 tree2
= proto_item_add_subtree(item
, ett_encaps
);
620 item2
= proto_tree_add_boolean(tree2
621 ,VALUE_SELECTOR_VPC_VCC_PDU(pd
.mode
624 ,hf_pw_type_aal5_pdu
)
626 PROTO_ITEM_SET_GENERATED(item2
);
627 if (MODE_11(pd
.mode
))
629 item2
= proto_tree_add_int(tree2
, hf_11_ncells
, tvb
, 0, 0, cells
);
630 PROTO_ITEM_SET_GENERATED(item2
);
634 if (pd
.props
& PWC_PAY_SIZE_BAD
)
636 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
637 "PW payload size (%d) must be <> 0 and multiple of %d",
638 (int)payload_size
, pw_cell_size(pd
.mode
, pd
.submode
));
639 if ((payload_size
!= 0) && MODE_11(pd
.mode
))
641 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
642 "PW ATM cell [%.3d] is broken", (int)cells
);
649 tvb_2
= tvb_new_subset(tvb
, 0, PWC_SIZEOF_CW
, PWC_SIZEOF_CW
);
650 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
652 tvb_2
= tvb_new_subset_remaining(tvb
, (PWC_SIZEOF_CW
-1));
653 if (MODE_11(pd
.mode
))
655 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, 0, &pd
);
659 if (payload_size
!= 0)
662 union wtap_pseudo_header
* pseudo_header_save
;
663 union wtap_pseudo_header ph
;
665 tvb_3
= tvb_new_subset_remaining(tvb_2
, 1);
666 /* prepare pseudo header for atm aal5 decoding */
667 pseudo_header_save
= pinfo
->pseudo_header
;
668 pinfo
->pseudo_header
= &ph
;
669 prepare_pseudo_header_atm(&ph
, &pd
, AAL_5
);
670 call_dissector_with_data(dh_atm_untruncated
, tvb_3
, pinfo
, tree
, &pd
);
671 /* restore pseudo header */
672 pinfo
->pseudo_header
= pseudo_header_save
;
677 if (MODE_11(pd
.mode
))
679 /* overwrite everything written by sub-dissectors in 1:1 modes*/
680 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
681 col_clear(pinfo
->cinfo
, COL_INFO
);
682 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
690 dissect_aal5_sdu(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
)
692 const char * proto_name_column
;
696 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
698 pd
.mode
= PWATM_MODE_AAL5_SDU
;
700 proto_name_column
= &shortname_aal5_sdu
[0];
701 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_aal5_sdu
, proto_name_column
))
705 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
707 /* check how "good" is this packet */
708 /* also decide payload length from packet size and CW */
709 if (0 != (tvb_get_guint8(tvb
, 0) & 0xf0 /*bits03*/))
711 pd
.props
|= PWC_CW_BAD_BITS03
;
714 pd
.submode
= PWATM_SUBMODE_DEFAULT
;
715 if (0 != (tvb_get_guint8(tvb
, 0) & 0x08 /*preferred_cw.T*/))
717 pd
.submode
= PWATM_SUBMODE_ADMIN_CELL
;
720 if (! pref_aal5_sdu_extend_cw_length_with_rsvd
)
722 if (0 != (tvb_get_guint8(tvb
, 1) & 0xc0 /*preferred_cw.rsvd*/))
724 pd
.props
|= PWC_CW_BAD_RSV
;
729 * [ If the packet's length (defined as the length of the layer 2 payload
730 * plus the length of the control word) is less than 64 bytes, the
731 * length field MUST be set to the packet's length. Otherwise, the
732 * length field MUST be set to zero... Note that the length field
733 * is not used in the N-to-one mode and MUST be set to 0. ]
735 * Also we allow some "extensions"conducted by pref_xxx.
737 gint payload_size_from_packet
;
738 int cw_len
; /*length field from cw*/
740 payload_size_from_packet
= pd
.packet_size
- PWC_SIZEOF_CW
;
741 if (pref_aal5_sdu_extend_cw_length_with_rsvd
)
743 cw_len
= tvb_get_guint8(tvb
, 1) & 0xff;
747 cw_len
= tvb_get_guint8(tvb
, 1) & 0x3f;
751 * Initial assumptions: no padding,
752 * payload size derived from psn packet size.
754 payload_size
= payload_size_from_packet
;
759 /*keep initial assumptions*/
761 else if (!pref_aal5_sdu_allow_cw_length_nonzero
762 && (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
))
765 * The "allow CW.Length != 0" option affects
766 * ATM admin cell submode only, because this submode
767 * is equal to N:1 encapsulation.
768 * CW.Length !=0 is always OK for normal (AAL5 payload) submode.
770 pd
.props
|= PWC_CW_BAD_LEN_MUST_BE_0
;
774 gint payload_size_from_cw
;
775 payload_size_from_cw
= cw_len
- PWC_SIZEOF_CW
;
776 if (payload_size_from_cw
<= 0)
778 pd
.props
|= PWC_CW_BAD_PAYLEN_LE_0
;
780 else if (payload_size_from_cw
> payload_size_from_packet
)
782 pd
.props
|= PWC_CW_BAD_PAYLEN_GT_PACKET
;
787 payload_size
= payload_size_from_cw
;
788 padding_size
= payload_size_from_packet
- payload_size_from_cw
; /* >=0 */
789 if (padding_size
!= 0)
792 * Padding is not allowed in ATM admin cell submode only,
793 * because this submode is equal to N:1 encapsulation.
794 * Padding is OK for normal (AAL5 payload) submode.
796 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
798 pd
.props
|= PWC_CW_BAD_PADDING_NE_0
;
800 payload_size
= payload_size_from_packet
;
807 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
809 gint bad_padding_size
;
810 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
811 /* only one atm admin cell is allowed in the packet in this mode*/
812 if ((1 != cells
) || (0 != bad_padding_size
))
814 pd
.props
|= PWC_PAY_SIZE_BAD
;
819 cells
= -1; /*unknown*/
820 /* Any size is allowed for AAL5 SDU payload */
824 /* fill columns in Packet List */
825 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
826 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
828 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, ", OAM cell");
831 col_clear(pinfo
->cinfo
, COL_INFO
);
832 col_append_pw_info(pinfo
, payload_size
, cells
, padding_size
, &pd
);
836 item
= proto_tree_add_item(tree
, proto_aal5_sdu
, tvb
, 0, -1, ENC_NA
);
839 tree2
= proto_item_add_subtree(item
, ett_encaps
);
841 item
= proto_tree_add_boolean(tree2
, hf_pw_type_aal5_sdu
, tvb
, 0, 0, TRUE
);
842 PROTO_ITEM_SET_GENERATED(item
);
845 if (pd
.props
& PWC_PAY_SIZE_BAD
)
847 DISSECTOR_ASSERT(PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
);
848 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
849 "In ATM admin cell mode,"
850 " PW payload size (%d) must be == %d (exactly 1 admin cell)",
851 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
857 tvb_2
= tvb_new_subset(tvb
, 0, PWC_SIZEOF_CW
, PWC_SIZEOF_CW
);
858 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
860 tvb_2
= tvb_new_subset_remaining(tvb
, PWC_SIZEOF_CW
);
861 if (PWATM_SUBMODE_ADMIN_CELL
== pd
.submode
)
863 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, padding_size
, &pd
);
865 else /*AAL5 payload*/
867 if (payload_size
!= 0)
870 union wtap_pseudo_header
* pseudo_header_save
;
871 union wtap_pseudo_header ph
;
873 tvb_3
= tvb_new_subset(tvb_2
, 0, payload_size
, payload_size
);
874 /* prepare pseudo header for atm aal5 decoding */
875 pseudo_header_save
= pinfo
->pseudo_header
;
876 pinfo
->pseudo_header
= &ph
;
877 prepare_pseudo_header_atm(&ph
, &pd
, AAL_5
);
878 call_dissector_with_data(dh_atm_truncated
, tvb_3
, pinfo
, tree
, &pd
); /* no PAD and trailer */
879 /* restore pseudo header */
880 pinfo
->pseudo_header
= pseudo_header_save
;
882 if (padding_size
!= 0)
885 tvb_3
= tvb_new_subset(tvb_2
, payload_size
, padding_size
, -1);
886 call_dissector(dh_padding
, tvb_3
, pinfo
, tree
);
894 dissect_n1_cw(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
)
896 const char * proto_name_column
;
900 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
902 pd
.mode
= PWATM_MODE_N1_CW
;
904 proto_name_column
= &shortname_n1_cw
[0];
905 if (too_small_packet_or_notpw(tvb
, pinfo
, tree
, proto_n1_cw
, proto_name_column
))
909 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
911 /* check how "good" is this packet */
912 /* also decide payload length from packet size and CW */
913 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
914 if (0 != (tvb_get_guint8(tvb
, 0) & 0xf0 /*bits03*/))
916 pd
.props
|= PWC_CW_BAD_BITS03
;
918 if (0 != (tvb_get_guint8(tvb
, 0) & 0x0f /*preferred_cw.flags*/))
920 pd
.props
|= PWC_CW_BAD_FLAGS
;
922 if (! pref_n1_cw_extend_cw_length_with_rsvd
)
924 if (0 != (tvb_get_guint8(tvb
, 1) & 0xc0 /*preferred_cw.rsvd*/))
926 pd
.props
|= PWC_CW_BAD_RSV
;
931 * [ If the packet's length (defined as the length of the layer 2 payload
932 * plus the length of the control word) is less than 64 bytes, the
933 * length field MUST be set to the packet's length. Otherwise, the
934 * length field MUST be set to zero... Note that the length field
935 * is not used in the N-to-one mode and MUST be set to 0. ]
937 * Also we allow some "extensions"conducted by pref_xxx.
939 gint payload_size_from_packet
;
940 int cw_len
; /*length field from cw*/
942 payload_size_from_packet
= pd
.packet_size
- PWC_SIZEOF_CW
;
943 if (pref_n1_cw_extend_cw_length_with_rsvd
)
945 cw_len
= tvb_get_guint8(tvb
, 1) & 0xff;
949 cw_len
= tvb_get_guint8(tvb
, 1) & 0x3f;
953 * Initial assumptions: no padding,
954 * payload size derived from psn packet size.
956 payload_size
= payload_size_from_packet
;
961 /*keep initial assumptions*/
963 else if (!pref_n1_cw_allow_cw_length_nonzero
)
965 pd
.props
|= PWC_CW_BAD_LEN_MUST_BE_0
;
969 gint payload_size_from_cw
;
970 payload_size_from_cw
= cw_len
- PWC_SIZEOF_CW
;
971 if (payload_size_from_cw
<= 0)
973 pd
.props
|= PWC_CW_BAD_PAYLEN_LE_0
;
975 else if (payload_size_from_cw
> payload_size_from_packet
)
977 pd
.props
|= PWC_CW_BAD_PAYLEN_GT_PACKET
;
982 payload_size
= payload_size_from_cw
;
983 padding_size
= payload_size_from_packet
- payload_size_from_cw
; /* >=0 */
984 if (padding_size
!= 0)
986 pd
.props
|= PWC_CW_BAD_PADDING_NE_0
;
988 payload_size
= payload_size_from_packet
;
994 gint bad_padding_size
;
995 cells
= number_of_cells(pd
.mode
, pd
.submode
, payload_size
, &bad_padding_size
);
996 if ((0 == cells
) || (0 != bad_padding_size
))
998 pd
.props
|= PWC_PAY_SIZE_BAD
;
1005 item
= proto_tree_add_item(tree
, proto_n1_cw
, tvb
, 0, -1, ENC_NA
);
1006 pwc_item_append_text_n_items(item
, cells
, "good ATM cell");
1009 tree2
= proto_item_add_subtree(item
, ett_encaps
);
1012 item2
= proto_tree_add_boolean(tree2
, hf_pw_type_n1_cw
, tvb
, 0, 0, TRUE
);
1013 PROTO_ITEM_SET_GENERATED(item2
);
1014 item2
= proto_tree_add_int(tree2
, hf_n1_cw_ncells
, tvb
, 0, 0, cells
);
1015 PROTO_ITEM_SET_GENERATED(item2
);
1018 if (pd
.props
& PWC_PAY_SIZE_BAD
)
1020 if (payload_size
!= 0)
1022 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
1023 "PW ATM cell [%.3d] is broken", (int)cells
);
1024 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_note
,
1025 "PW payload size (%d) must be <>0 and multiple of %d",
1026 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1030 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1031 "PW payload size (%d) must be <>0 and multiple of %d",
1032 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1039 tvb_2
= tvb_new_subset(tvb
, 0, PWC_SIZEOF_CW
, PWC_SIZEOF_CW
);
1040 call_dissector_with_data(dh_control_word
, tvb_2
, pinfo
, tree
, &pd
);
1042 tvb_2
= tvb_new_subset_remaining(tvb
, PWC_SIZEOF_CW
);
1043 dissect_payload_and_padding(tvb_2
, pinfo
, tree
, payload_size
, padding_size
, &pd
);
1046 /* fill columns in Packet List */
1047 /* overwrite everything written by sub-dissectors */
1048 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
1050 col_clear(pinfo
->cinfo
, COL_INFO
);
1051 col_append_pw_info(pinfo
, payload_size
, cells
, padding_size
, &pd
);
1056 dissect_n1_nocw(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
)
1058 const char * proto_name_column
= &shortname_n1_nocw
[0];
1061 pwatm_private_data_t pd
= PWATM_PRIVATE_DATA_T_INITIALIZER
;
1063 pd
.mode
= PWATM_MODE_N1_NOCW
;
1064 pd
.packet_size
= tvb_reported_length_remaining(tvb
, 0);
1066 /* check how "good" is this packet */
1067 /* also decide payload length from packet size */
1068 pd
.props
= PWC_PACKET_PROPERTIES_T_INITIALIZER
;
1069 payload_size
= pd
.packet_size
;
1071 gint bad_padding_size
;
1072 cells
= number_of_cells(pd
.mode
, pd
.submode
, pd
.packet_size
, &bad_padding_size
);
1073 if ((cells
== 0) || (bad_padding_size
!= 0))
1075 pd
.props
|= PWC_PAY_SIZE_BAD
;
1081 item
= proto_tree_add_item(tree
, proto_n1_nocw
, tvb
, 0, -1, ENC_NA
);
1082 pwc_item_append_text_n_items(item
, cells
, "ATM cell");
1085 tree2
= proto_item_add_subtree(item
, ett_encaps
);
1088 item2
= proto_tree_add_boolean(tree2
, hf_pw_type_n1_nocw
, tvb
, 0, 0, TRUE
);
1089 PROTO_ITEM_SET_GENERATED(item2
);
1090 item2
= proto_tree_add_int(tree2
, hf_n1_nocw_ncells
, tvb
, 0, 0, cells
);
1091 PROTO_ITEM_SET_GENERATED(item2
);
1094 if (pd
.props
& PWC_PAY_SIZE_BAD
)
1096 if (payload_size
!= 0)
1098 expert_add_info_format(pinfo
, item
, &ei_cell_broken
,
1099 "Last PW ATM cell [%.3d] is broken", (int)cells
);
1100 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_note
,
1101 "PW payload size (%d) must be <>0 and multiple of %d",
1102 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1106 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1107 "PW payload size (%d) must be <>0 and multiple of %d",
1108 (int)payload_size
, (int)SIZEOF_N1_PW_CELL
);
1113 dissect_payload_and_padding(tvb
, pinfo
, tree
, payload_size
, 0, &pd
);
1115 /* fill columns in Packet List */
1116 /* overwrite everything written by sub-dissectors */
1117 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, proto_name_column
);
1119 col_clear(pinfo
->cinfo
, COL_INFO
);
1120 col_append_pw_info(pinfo
, payload_size
, cells
, 0, &pd
);
1125 proto_item_append_text_cwb3_fields(proto_item
* item
, const pwatm_private_data_t
* const pd
)
1127 if (NULL
== item
) return;
1128 DISSECTOR_ASSERT(NULL
!= pd
);
1129 if (pd
->cwb3
.m
>= 0)
1130 proto_item_append_text(item
, "M:%.1u " , (unsigned)(pd
->cwb3
.m
));
1131 if (pd
->cwb3
.v
>= 0)
1132 proto_item_append_text(item
, "V:%.1u " , (unsigned)(pd
->cwb3
.v
));
1133 if (pd
->cwb3
.rsv
>= 0)
1134 proto_item_append_text(item
, "RSV:%.1u ", (unsigned)(pd
->cwb3
.rsv
));
1135 if (pd
->cwb3
.u
>= 0)
1136 proto_item_append_text(item
, "U:%.1u " , (unsigned)(pd
->cwb3
.u
));
1137 if (pd
->cwb3
.e
>= 0)
1138 proto_item_append_text(item
, "EFCI:%.1u ",(unsigned)(pd
->cwb3
.e
));
1139 if (pd
->cwb3
.clp
>= 0)
1140 proto_item_append_text(item
, "CLP:%.1u ", (unsigned)(pd
->cwb3
.clp
));
1146 dissect_control_word(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
)
1148 pwatm_private_data_t
* pd
= (pwatm_private_data_t
*)data
;
1149 DISSECTOR_ASSERT(pd
!= NULL
);
1152 * NB: do not touch columns -- keep info from previous dissector
1157 size
= tvb_reported_length_remaining(tvb
, 0);
1158 if (size
< PWC_SIZEOF_CW
)
1161 item
= proto_tree_add_item(tree
, proto_control_word
, tvb
, 0, -1, ENC_NA
);
1162 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1163 "Packet (size: %d) is too small to carry MPLS PW Control Word"
1165 return tvb_length(tvb
);
1170 proto_item
* item_top
;
1174 item_top
= proto_tree_add_item(tree
, proto_control_word
, tvb
, 0, -1, ENC_NA
);
1175 pwc_item_append_cw(item_top
, tvb_get_ntohl(tvb
, 0), FALSE
);
1177 tree2
= proto_item_add_subtree(item_top
, ett_cw
);
1180 item
= proto_tree_add_item(tree2
, hf_cw_bits03
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1181 if (pd
->props
& PWC_CW_BAD_BITS03
)
1183 /* add item to tree (and show it) only if its value is wrong*/
1184 expert_add_info(pinfo
, item
, &ei_cw_bits03
);
1188 PROTO_ITEM_SET_HIDDEN(item
); /* show only in error cases */
1192 if (MODE_N1(pd
->mode
))
1194 item
= proto_tree_add_item(tree2
, hf_pref_cw_flags
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1195 if (pd
->props
& PWC_CW_BAD_FLAGS
)
1197 expert_add_info(pinfo
, item
, &ei_pref_cw_flags
);
1200 if (pd
->mode
== PWATM_MODE_AAL5_SDU
)
1202 proto_tree_add_item(tree2
, hf_pref_cw_a5s_t
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1203 proto_tree_add_item(tree2
, hf_pref_cw_a5s_e
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1204 proto_tree_add_item(tree2
, hf_pref_cw_a5s_c
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1205 proto_tree_add_item(tree2
, hf_pref_cw_a5s_u
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1207 * rfc4717: [When FRF.8.1 Frame Relay/ATM PVC Service Interworking [RFC3916]
1208 * traffic is being transported, the CPCS-UU Least Significant Bit
1209 * (LSB) of the AAL5 CPCS-PDU may contain the Frame Relay C/R bit.
1210 * The ingress router, PE1, SHOULD copy this bit to the U bit of the
1211 * control word. The egress router, PE2, SHOULD copy the U bit to
1212 * the CPCS-UU Least Significant Bit (LSB) of the AAL5 CPCS PDU.]
1214 * Let's remember this bit (and then transfer it to ATM dissector).
1216 pd
->aal5_sdu_frame_relay_cr_bit
=
1217 (0 == (tvb_get_guint8(tvb
, 0) & 0x01 /*preferred_cw.U*/))
1222 if (MODE_11_OR_AAL5_PDU(pd
->mode
)
1223 || (MODE_N1(pd
->mode
) && !pref_n1_cw_extend_cw_length_with_rsvd
)
1224 /* for N:1 add RSV only if it is NOT used in length */
1225 || ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && !pref_aal5_sdu_extend_cw_length_with_rsvd
)
1226 /* for AAl5 SDU add RSV only if it is NOT used in length */)
1228 if (MODE_11_OR_AAL5_PDU(pd
->mode
))
1230 item
= proto_tree_add_item(tree2
1231 ,hf_generic_cw_rsv
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1235 item
= proto_tree_add_item(tree2
1236 ,hf_pref_cw_rsv
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
1239 if (pd
->props
& PWC_CW_BAD_RSV
)
1241 expert_add_info(pinfo
, item
, &ei_cw_bits03
);
1245 PROTO_ITEM_SET_HIDDEN(item
); /*...and show only in error cases */
1250 if (MODE_N1(pd
->mode
)
1251 || (PWATM_MODE_AAL5_SDU
== pd
->mode
))
1254 int hf_len
= hf_pref_cw_len
;
1255 if (MODE_N1(pd
->mode
))
1257 if (pref_n1_cw_extend_cw_length_with_rsvd
)
1258 hf_len
= hf_pref_cw_rsvlen
;
1260 else /*PW_MODE_AAL5_SDU*/
1262 if (pref_aal5_sdu_extend_cw_length_with_rsvd
)
1263 hf_len
= hf_pref_cw_rsvlen
;
1265 item
= proto_tree_add_item(tree2
, hf_len
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
1267 if (pd
->props
& PWC_CW_BAD_LEN_MUST_BE_0
)
1269 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1270 "Bad Length: must be 0 for this encapsulation");
1272 if (pd
->props
& PWC_CW_BAD_PAYLEN_LE_0
)
1274 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1275 "Bad Length: too small, must be >= %d",
1276 (int)(PWC_SIZEOF_CW
+SIZEOF_N1_PW_CELL
));
1278 if (pd
->props
& PWC_CW_BAD_PAYLEN_GT_PACKET
)
1280 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1281 "Bad Length: must be <= than PSN packet size (%d)",
1282 (int)pd
->packet_size
);
1284 if (pd
->props
& PWC_CW_BAD_PADDING_NE_0
)
1286 expert_add_info_format(pinfo
, item
, &ei_pref_cw_len
,
1287 "Bad Length: must be == PSN packet size (%d), no padding allowed",
1288 (int)pd
->packet_size
);
1292 /* sequence number */
1293 proto_tree_add_item(tree2
, hf_cw_seq
, tvb
1294 ,MODE_11_OR_AAL5_PDU(pd
->mode
) ? 1 : 2, 2, ENC_BIG_ENDIAN
);
1296 /* atm-specific byte */
1297 if (MODE_11(pd
->mode
))
1299 proto_tree_add_item(tree2
, hf_gen_cw_atmbyte
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1301 * no need to highlight item in the tree, therefore
1302 * expert_add_info_format() is not used here.
1304 item
= proto_tree_add_text(tree2
, tvb
, 3, 1
1305 ,"ATM-specific byte of CW is fully dissected below as %s%s"
1306 ,(PWATM_MODE_11_VPC
== pd
->mode
) ? "a part of " : ""
1307 ,"PW ATM Cell Header [000]");
1308 PROTO_ITEM_SET_GENERATED(item
);
1310 * Note: if atm-specific byte contains something wrong
1311 * (e.g. non-zero RSV or inadequate V), CW is not
1317 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1320 tvb_2
= tvb_new_subset_remaining(tvb
, (PWC_SIZEOF_CW
-1));
1321 call_dissector_with_data(dh_cell_header
, tvb_2
, pinfo
, tree2
, pd
);
1322 proto_item_append_text(item_top
, ", ");
1323 proto_item_append_text_cwb3_fields(item_top
, pd
);
1327 return tvb_length(tvb
);
1332 * This function is also used to dissect 3rd byte of CW in AAL5 PDU mode.
1335 dissect_cell_header(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
)
1337 pwatm_private_data_t
* pd
= (pwatm_private_data_t
*)data
;
1338 gboolean is_enough_data
;
1341 DISSECTOR_ASSERT (NULL
!= pd
);
1342 pd
->vpi
= pd
->vci
= pd
->pti
= -1;
1343 pd
->cwb3
.clp
= pd
->cwb3
.m
= pd
->cwb3
.v
= pd
->cwb3
.rsv
= pd
->cwb3
.u
= pd
->cwb3
.e
= -1;
1345 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1347 if (tvb_reported_length_remaining(tvb
, 0) < 1)
1349 is_enough_data
= FALSE
;
1354 is_enough_data
= TRUE
;
1361 size
= tvb_reported_length_remaining(tvb
, 0);
1363 if (size
< pw_cell_header_size(pd
->mode
, pd
->submode
))
1365 is_enough_data
= FALSE
;
1366 dissect_size
= size
;
1370 is_enough_data
= TRUE
;
1371 dissect_size
= pw_cell_header_size(pd
->mode
, pd
->submode
);
1376 * NB: do not touch columns -- keep info from previous dissector
1379 /* Collect info for upper-level dissectors regardless of
1380 * the presence of the tree
1387 case PWATM_MODE_AAL5_SDU
:
1388 DISSECTOR_ASSERT(pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
);
1389 /*fallthrough for ATM admin cell submode only*/
1390 case PWATM_MODE_N1_CW
:
1391 case PWATM_MODE_N1_NOCW
:
1392 pd
->vpi
= (tvb_get_ntohs (tvb
, 0) >> 4);
1393 pd
->vci
= (tvb_get_ntoh24(tvb
, 1) >> 4) & 0xffff;
1394 tmp8
= (tvb_get_guint8(tvb
, 3));
1395 pd
->pti
= (tmp8
>> 1) & 0x07;
1396 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x01;
1397 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vpi
, pd
->vpi
);
1398 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vci
, pd
->vci
);
1399 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.pti
, pd
->pti
);
1400 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1402 * OAM cell mode is always used for aal5_sdu/admin_cell mode,
1403 * even if pti indicates user cell.
1406 ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && (pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
))
1407 || PTI_IS_ADMIN(pd
->pti
);
1409 case PWATM_MODE_11_VPC
:
1410 pd
->vci
= tvb_get_ntohs(tvb
, 1);
1411 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.vci
, pd
->vci
);
1413 case PWATM_MODE_11_VCC
:
1414 tmp8
= (tvb_get_guint8(tvb
, 0));
1415 pd
->cwb3
.m
= (tmp8
>> 7) & 0x1;
1416 pd
->cwb3
.v
= (tmp8
>> 6) & 0x1;
1417 pd
->cwb3
.rsv
= (tmp8
>> 4) & 0x3;
1418 pd
->pti
= (tmp8
>> 1) & 0x7;
1419 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x1;
1420 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.pti
, pd
->pti
);
1421 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1423 * OAM cell mode is possible if packet contains atm cell (m == 0).
1425 pd
->cell_mode_oam
= PTI_IS_ADMIN(pd
->pti
) && (pd
->cwb3
.m
== 0);
1427 case PWATM_MODE_AAL5_PDU
:
1428 tmp8
= (tvb_get_guint8(tvb
, 0));
1429 pd
->cwb3
.m
= (tmp8
>> 7) & 0x1;
1430 pd
->cwb3
.v
= (tmp8
>> 6) & 0x1;
1431 pd
->cwb3
.rsv
= (tmp8
>> 3) & 0x7;
1432 pd
->cwb3
.u
= (tmp8
>> 2) & 0x1;
1433 pd
->cwb3
.e
= (tmp8
>> 1) & 0x1;
1434 pd
->cwb3
.clp
= (tmp8
>> 0) & 0x1;
1435 UPDATE_CUMULATIVE_VALUE(pd
->cumulative
.clp
, pd
->cwb3
.clp
);
1438 DISSECTOR_ASSERT_NOT_REACHED();
1446 item
= proto_tree_add_item(tree
, proto_cell_header
, tvb
1450 if (PWATM_MODE_AAL5_PDU
== pd
->mode
)
1452 proto_item_set_text(item
, "Third byte of Control Word"); /*overwrite heading line*/
1453 /* cwb3 fileds are appended to CW heading line, not here */
1457 proto_item_append_text(item
, " [%.3d]", pd
->pw_cell_number
);
1458 proto_item_append_text(item
, ", ");
1460 proto_item_append_text(item
, "VPI:%.4u ", (unsigned)(pd
->vpi
));
1462 proto_item_append_text(item
, "VCI:%.5u ", (unsigned)(pd
->vci
));
1464 proto_item_append_text(item
, "PTI:%.1u ", (unsigned)(pd
->pti
));
1465 proto_item_append_text_cwb3_fields(item
, pd
);
1470 tree2
= proto_item_add_subtree(item
, ett_cell_header
);
1474 if (MODE_N1(pd
->mode
)
1475 || ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && (pd
->submode
== PWATM_SUBMODE_ADMIN_CELL
)))
1477 proto_tree_add_uint(tree2
, hf_cell_h_vpi
, tvb
, 0, 2, (unsigned)pd
->vpi
);
1478 proto_tree_add_uint(tree2
, hf_cell_h_vci
, tvb
, 1, 3, (unsigned)pd
->vci
);
1480 item2
= proto_tree_add_item(tree2
, hf_cell_h_pti
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1481 if (NULL
== try_val_to_str(pd
->pti
, atm_pt_vals
))
1483 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_undecoded
,
1484 "Unknown value of PTI field (%d) in the ATM cell header",
1487 else if ((pd
->mode
== PWATM_MODE_AAL5_SDU
) && !PTI_IS_ADMIN(pd
->pti
))
1489 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_malformed
,
1490 "ATM admin cell is transerred;"
1491 " PTI field (%d) should be 4, 5 or 6.",
1495 proto_tree_add_item(tree2
, hf_cell_h_clp
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1497 else if (MODE_11_OR_AAL5_PDU(pd
->mode
))
1499 item2
= proto_tree_add_item(tree2
, hf_cell_h_m
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1500 if ((0 != pd
->cwb3
.m
) && MODE_11(pd
->mode
))
1502 expert_add_info(pinfo
, item2
, &ei_cell_h_m
);
1505 item2
= proto_tree_add_item(tree2
, hf_cell_h_v
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1506 if ((0 == pd
->cwb3
.v
) && (PWATM_MODE_11_VPC
== pd
->mode
))
1508 expert_add_info(pinfo
, item2
, &ei_cell_h_v_not_zero
);
1510 if ((0 != pd
->cwb3
.v
) && (PWATM_MODE_11_VCC
== pd
->mode
))
1512 expert_add_info_format(pinfo
, item2
, &ei_cell_h_v_not_one
,
1514 " V bit must be 0 to indicate that VCI is absent");
1516 if ((0 != pd
->cwb3
.v
) && (PWATM_MODE_AAL5_PDU
== pd
->mode
))
1518 expert_add_info_format(pinfo
, item2
, &ei_cell_h_v_not_one
,
1520 " V bit must be 0 to indicate that VCI is absent");
1523 item2
= proto_tree_add_item(tree2
1524 ,(PWATM_MODE_AAL5_PDU
== pd
->mode
)
1527 ,tvb
, 0, 1, ENC_BIG_ENDIAN
);
1528 if (0 != pd
->cwb3
.rsv
)
1530 expert_add_info(pinfo
, item2
, &ei_cell_h_rsv
);
1534 PROTO_ITEM_SET_HIDDEN(item2
); /*...and show only in error cases */
1537 if (MODE_11(pd
->mode
))
1539 item2
= proto_tree_add_item(tree2
, hf_cell_h_pti
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1540 if (NULL
== try_val_to_str(pd
->pti
, atm_pt_vals
))
1542 expert_add_info_format(pinfo
, item2
, &ei_cell_h_pti_undecoded
,
1543 "Unknown value of PTI field (%d) in the atm-specific byte"
1549 proto_tree_add_item(tree2
, hf_aal5_pdu_u
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1550 proto_tree_add_item(tree2
, hf_aal5_pdu_e
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1553 proto_tree_add_item(tree2
, hf_cell_h_clp
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1555 if (PWATM_MODE_11_VPC
== pd
->mode
)
1557 proto_tree_add_uint(tree2
, hf_cell_h_vci
, tvb
, 1, 2
1558 ,(unsigned)pd
->vci
);
1563 DISSECTOR_ASSERT_NOT_REACHED();
1568 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1569 "Not enough data (size: %d), impossible to decode",
1574 return dissect_size
;
1580 dissect_cell(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
)
1582 gboolean is_enough_data
;
1586 pwatm_private_data_t
* pd
= (pwatm_private_data_t
*)data
;
1588 size
= tvb_reported_length_remaining(tvb
, 0);
1589 if (size
< SIZEOF_ATM_CELL_PAYLOAD
)
1591 is_enough_data
= FALSE
;
1592 dissect_size
= size
;
1596 is_enough_data
= TRUE
;
1597 dissect_size
= SIZEOF_ATM_CELL_PAYLOAD
;
1601 * NB: do not touch columns -- keep info from previous dissector
1604 item
= proto_tree_add_item(tree
, proto_cell
, tvb
, 0, dissect_size
, ENC_NA
);
1606 proto_item_append_text(item
, " [%.3d]", pd
->pw_cell_number
);
1608 pwc_item_append_text_n_items(item
, dissect_size
, "byte");
1609 if (!is_enough_data
)
1611 expert_add_info_format(pinfo
, item
, &ei_pw_payload_size_invalid_error
,
1612 "Bad length of cell payload: must be == %d",
1613 (int)SIZEOF_ATM_CELL_PAYLOAD
);
1619 tree2
= proto_item_add_subtree(item
, ett_cell
);
1620 tvb_d
= tvb_new_subset(tvb
, 0, dissect_size
, -1);
1621 call_dissector(dh_data
, tvb_d
, pinfo
, tree2
);
1622 item
= proto_tree_add_int(tree2
, hf_cell_payload_len
, tvb
, 0, 0, dissect_size
);
1623 PROTO_ITEM_SET_HIDDEN(item
);
1626 return dissect_size
;
1631 proto_register_pw_atm_ata(void)
1633 static const value_string clp_vals
[] = {
1634 { 0, "High priority" },
1635 { 1, "Low priority" },
1638 static const value_string m_vals
[] = {
1640 { 1, "AAL5 payload" },
1643 static const value_string u_vals
[] = {
1644 { 0, "This frame does not contain the last cell of AAL5 PDU" },
1645 { 1, "This frame contains the last cell of AAL5 PDU" },
1648 static const value_string e_vals
[] = {
1649 { 0, "Congestion is not experienced" },
1650 { 1, "Congestion is experienced for one or more ATM AAL5 cells" },
1653 static hf_register_info hfa_cell_header
[] = {
1654 { &hf_cell_h_vpi
,{"VPI" ,"atm.vpi"
1655 ,FT_UINT16
,BASE_DEC
,NULL
,0
1658 { &hf_cell_h_vci
,{"VCI" ,"atm.vci"
1659 ,FT_UINT16
,BASE_DEC
,NULL
,0
1662 { &hf_cell_h_pti
,{"Payload Type" ,"atm.pti"
1663 ,FT_UINT8
,BASE_DEC
,VALS(atm_pt_vals
),0x0e
1664 ,"The 3-bit Payload Type Identifier (PTI) incorporates ATM Layer"
1665 " PTI coding of the cell. These bits are set to the value of the"
1666 " PTI of the encapsulated ATM cell."
1669 { &hf_cell_h_clp
,{"Cell Loss Priority" ,"atm.clp"
1670 ,FT_UINT8
,BASE_DEC
,VALS(clp_vals
) ,0x01
1671 ,"The Cell Loss Priority (CLP) field indicates CLP value"
1672 " of the encapsulated cell."
1675 { &hf_cell_h_m
,{"Transport Mode" ,"atm.pw_control_byte.m"
1676 ,FT_UINT8
,BASE_DEC
,VALS(m_vals
) ,0x80
1677 ,"Bit (M) of the control byte indicates whether the packet"
1678 " contains an ATM cell or a frame payload. If set to 0,"
1679 " the packet contains an ATM cell. If set to 1, the PDU"
1680 " contains an AAL5 payload."
1683 { &hf_cell_h_v
,{"VCI Present" ,"atm.pw_control_byte.v"
1684 ,FT_BOOLEAN
,8 ,TFS(&tfs_yes_no
),0x40
1685 ,"Bit (V) of the control byte indicates whether the VCI field"
1686 " is present in the packet. If set to 1, the VCI field is present"
1687 " for the cell. If set to 0, no VCI field is present."
1690 { &hf_cell_h_rsv
,{"Reserved bits" ,"atm.pw_control_byte.rsv"
1691 ,FT_UINT8
,BASE_DEC
,NULL
,0x30
1692 ,"The reserved bits should be set to 0 at the transmitter and"
1693 " ignored upon reception."
1696 { &hf_aal5_pdu_rsv
,{"Reserved bits" ,"atm.pw_control_byte.rsv"
1697 ,FT_UINT8
,BASE_DEC
,NULL
,0x38
1698 ,"The reserved bits should be set to 0 at the transmitter and"
1699 " ignored upon reception."
1702 { &hf_aal5_pdu_u
,{"U bit" ,"atm.pw_control_byte.u"
1703 ,FT_UINT8
,BASE_DEC
,VALS(u_vals
) ,0x04
1704 ,"Indicates whether this frame contains the last cell of"
1705 " an AAL5 PDU and represents the value of the ATM User-to-User"
1706 " bit for the last ATM cell of the PSN frame. Note: The ATM"
1707 " User-to-User bit is the least significant bit of the PTI"
1708 " in the ATM header."
1711 { &hf_aal5_pdu_e
,{"EFCI" ,"atm.pw_control_byte.efci"
1712 ,FT_UINT8
,BASE_DEC
,VALS(e_vals
) ,0x02
1713 ,"EFCI is set to the EFCI state of the last cell of the"
1714 " AAL5 PDU or AAL5 fragment. Note: The EFCI state is"
1715 " indicated in the middle bit of each ATM cell's PTI."
1718 static hf_register_info hfa_cell
[] = {
1719 {&hf_cell_payload_len
,{"Length" ,"atm.cell.len"
1720 ,FT_INT32
,BASE_DEC
,NULL
,0
1724 #define HF_INITIALIZER_NCELLS(hf_handle) \
1725 { &hf_handle ,{"Number of good encapsulated cells","pw.atm.cells" \
1726 ,FT_INT32 ,BASE_DEC ,NULL ,0 \
1729 #define HF_INITIALIZER_PWTYPE(hf_handle,name) \
1730 { &hf_handle ,{name ,name \
1731 ,FT_BOOLEAN ,0 ,NULL ,0x0 \
1732 ,"Identifies type of ATM PW. May be used for filtering.",HFILL}}
1735 static hf_register_info hfa_n1_nocw
[] = {
1736 HF_INITIALIZER_NCELLS(hf_n1_nocw_ncells
)
1737 ,HF_INITIALIZER_PWTYPE(hf_pw_type_n1_nocw
,"pw.type.atm.n1nocw")
1740 static hf_register_info hfa_n1_cw
[] = {
1741 HF_INITIALIZER_NCELLS(hf_n1_cw_ncells
)
1742 ,HF_INITIALIZER_PWTYPE(hf_pw_type_n1_cw
,"pw.type.atm.n1cw")
1745 static hf_register_info hfa_11_aal5pdu
[] = {
1746 HF_INITIALIZER_NCELLS(hf_11_ncells
)
1747 ,HF_INITIALIZER_PWTYPE(hf_pw_type_11_vcc
,"pw.type.atm.11vcc")
1748 ,HF_INITIALIZER_PWTYPE(hf_pw_type_11_vpc
,"pw.type.atm.11vpc")
1749 ,HF_INITIALIZER_PWTYPE(hf_pw_type_aal5_pdu
,"pw.type.atm.aal5pdu")
1752 static hf_register_info hfa_aal5_sdu
[] = {
1753 HF_INITIALIZER_PWTYPE(hf_pw_type_aal5_sdu
,"pw.type.atm.aal5sdu")
1756 static const value_string a5s_t_vals
[] = {
1757 { 0, "AAL5 payload" },
1758 { 1, "ATM admin cell" },
1762 static const value_string a5s_e_vals
[] = {
1763 { 0, "No congestion" },
1764 { 1, "Congestion experienced" },
1768 static hf_register_info hfa_cw
[] = {
1769 { &hf_cw_bits03
,{"Bits 0 to 3" ,"pw.cw.bits03"
1770 ,FT_UINT8
,BASE_HEX
,NULL
,0xf0
1773 { &hf_pref_cw_flags
,{"Flags" ,"pw.cw.flags"
1774 ,FT_UINT8
,BASE_HEX
,NULL
,0x0f
1777 { &hf_pref_cw_a5s_t
,{"Payload type" ,"atm.pt"
1778 ,FT_UINT8
,BASE_DEC
,VALS(a5s_t_vals
),0x08
1779 ,"Bit (T) of the control word indicates whether the packet contains"
1780 " an ATM admin cell or an AAL5 payload. If T = 1, the packet"
1781 " contains an ATM admin cell, encapsulated according to the N:1"
1782 " cell relay encapsulation. If not set, the PDU"
1783 " contains an AAL5 payload."
1786 { &hf_pref_cw_a5s_e
,{"EFCI bit" ,"atm.efci"
1787 ,FT_UINT8
,BASE_DEC
,VALS(a5s_e_vals
),0x04
1788 ,"The ingress router sets this bit to 1 if the EFCI bit"
1789 " of the final cell of those that transported the AAL5 CPCS-SDU is"
1790 " set to 1, or if the EFCI bit of the single ATM cell to be"
1791 " transported in the packet is set to 1. Otherwise, this bit"
1795 { &hf_pref_cw_a5s_c
,{"CLP bit" ,"atm.clp"
1796 ,FT_UINT8
,BASE_DEC
,VALS(clp_vals
) ,0x02
1797 ,"The ingress router sets this bit to 1 if the CLP bit"
1798 " of any of the ATM cells that transported the AAL5 CPCS-SDU is set"
1799 " to 1, or if the CLP bit of the single ATM cell to be transported"
1800 " in the packet is set to 1. Otherwise this bit is set to 0."
1803 { &hf_pref_cw_a5s_u
,{"U bit (Command/Response)" ,"pw.cw.aal5sdu.u"
1804 ,FT_UINT8
,BASE_DEC
,NULL
,0x01
1805 ,"When FRF.8.1 Frame Relay/ATM PVC Service Interworking [RFC3916]"
1806 " traffic is being transported, the Least-Significant Bit of CPCS-UU"
1807 " of the AAL5 CPCS-PDU may contain the Frame Relay C/R bit."
1808 " The ingress router copies this bit here."
1811 { &hf_pref_cw_rsv
,{"Reserved bits" ,"pw.cw.rsv"
1812 ,FT_UINT8
,BASE_DEC
,NULL
,0xc0
1815 { &hf_generic_cw_rsv
,{"Reserved bits" ,"pw.cw.rsv"
1816 ,FT_UINT8
,BASE_DEC
,NULL
,0x0f
1819 { &hf_pref_cw_len
,{"Length" ,"pw.cw.length"
1820 ,FT_UINT8
,BASE_DEC
,NULL
,0x3f
1823 { &hf_pref_cw_rsvlen
,{"Length (extended)" ,"pw.cw.length"
1824 ,FT_UINT8
,BASE_DEC
,NULL
,0xff
1827 { &hf_cw_seq
,{"Sequence number" ,"pw.cw.seqno"
1828 ,FT_UINT16
,BASE_DEC
,NULL
,0
1831 { &hf_gen_cw_atmbyte
,{"ATM-specific byte" ,"pw.cw.3rd_byte"
1832 ,FT_UINT8
,BASE_HEX
,NULL
,0xFF
1835 static gint
*ett_array
[] = {
1841 static ei_register_info ei
[] = {
1842 { &ei_pw_packet_size_too_small
, { "pw.packet_size_too_small", PI_MALFORMED
, PI_ERROR
, "PW packet size too small", EXPFILL
}},
1843 { &ei_pw_payload_size_invalid_error
, { "pw.payload.size_invalid", PI_MALFORMED
, PI_ERROR
, "PW payload size invalid", EXPFILL
}},
1844 { &ei_cell_broken
, { "atm.cell_broken", PI_MALFORMED
, PI_ERROR
, "PW ATM cell is broken", EXPFILL
}},
1845 { &ei_pw_payload_size_invalid_note
, { "pw.payload.size_invalid", PI_MALFORMED
, PI_NOTE
, "PW payload size invalid", EXPFILL
}},
1846 { &ei_cw_bits03
, { "pw.cw.bits03.not_zero", PI_MALFORMED
, PI_ERROR
, "Bits 0..3 of Control Word must be 0", EXPFILL
}},
1847 { &ei_pref_cw_flags
, { "pw.cw.flags.not_zero", PI_MALFORMED
, PI_ERROR
, "Flags must be 0 for PW ATM N:1 encapsulation", EXPFILL
}},
1848 { &ei_pref_cw_len
, { "pw.cw.length.invalid", PI_MALFORMED
, PI_ERROR
, "Bad Length: must be 0 for this encapsulation", EXPFILL
}},
1849 { &ei_cell_h_pti_undecoded
, { "atm.pti.invalid", PI_UNDECODED
, PI_WARN
, "Unknown value of PTI field in the ATM cell header", EXPFILL
}},
1850 { &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
}},
1851 { &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
}},
1852 { &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
}},
1853 { &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
}},
1854 { &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
}},
1856 expert_module_t
* expert_cell
;
1859 proto_register_protocol(pwc_longname_pw_atm_n1_cw
1862 proto_11_or_aal5_pdu
=
1863 proto_register_protocol(pwc_longname_pw_atm_11_or_aal5_pdu
1864 ,shortname_11_or_aal5_pdu
1865 ,"mplspwatm11_or_aal5pdu");
1867 proto_register_protocol(pwc_longname_pw_atm_aal5_sdu
1869 ,"mplspwatmaal5sdu");
1871 proto_register_protocol(pwc_longname_pw_atm_n1_nocw
1873 ,"mplspwatmn1nocw");
1874 proto_control_word
=
1875 proto_register_protocol("MPLS PW ATM Control Word"
1876 ,"MPLS PW ATM Control Word"
1877 ,"mplspwatmcontrolword");
1879 proto_register_protocol("MPLS PW ATM Cell Header"
1880 ,"MPLS PW ATM Cell Header"
1881 ,"mplspwatmcellheader");
1883 proto_register_protocol("ATM Cell"
1887 proto_register_field_array( proto_cell
,hfa_cell
,array_length(hfa_cell
));
1888 expert_cell
= expert_register_protocol(proto_cell
);
1889 expert_register_field_array(expert_cell
, ei
, array_length(ei
));
1891 proto_register_field_array( proto_cell_header
,hfa_cell_header
,array_length(hfa_cell_header
));
1892 proto_register_field_array( proto_control_word
,hfa_cw
,array_length(hfa_cw
));
1893 proto_register_field_array( proto_n1_nocw
,hfa_n1_nocw
,array_length(hfa_n1_nocw
));
1894 proto_register_field_array( proto_n1_cw
,hfa_n1_cw
,array_length(hfa_n1_cw
));
1895 proto_register_field_array( proto_11_or_aal5_pdu
,hfa_11_aal5pdu
,array_length(hfa_11_aal5pdu
));
1896 proto_register_field_array( proto_aal5_sdu
,hfa_aal5_sdu
,array_length(hfa_aal5_sdu
));
1898 proto_register_subtree_array(ett_array
, array_length(ett_array
));
1900 register_dissector("mpls_pw_atm_aal5_sdu" ,dissect_aal5_sdu
,proto_aal5_sdu
);
1901 register_dissector("mpls_pw_atm_11_or_aal5_pdu" ,dissect_11_or_aal5_pdu
,proto_11_or_aal5_pdu
);
1902 register_dissector("mpls_pw_atm_n1_cw" ,dissect_n1_cw
,proto_n1_cw
);
1903 register_dissector("mpls_pw_atm_n1_nocw" ,dissect_n1_nocw
,proto_n1_nocw
);
1904 new_register_dissector("mpls_pw_atm_control_word" ,dissect_control_word
,proto_control_word
);
1905 new_register_dissector("mpls_pw_atm_cell" ,dissect_cell
,proto_cell
);
1906 new_register_dissector("mpls_pw_atm_cell_header",dissect_cell_header
,proto_cell_header
);
1908 static const char description_allow_cw_length_nonzero
[] =
1909 "Enable to allow non-zero Length in Control Word."
1910 " This may be needed to correctly decode traffic from some legacy devices"
1911 " which generate non-zero Length even if there is no padding in the packet."
1912 " Note that Length should have proper value (dissector checks this anyway)."
1914 "Disable to blame all packets with CW.Length <> 0. This conforms to RFC4717."
1916 static const char description_extend_cw_length_with_rsvd
[] =
1917 "Enable to use reserved bits (8..9) of Control Word as an extension of CW.Length."
1918 " This may be needed to correctly decode traffic from some legacy devices"
1919 " which uses reserved bits as extension of Length"
1921 "Disable to blame all packets with CW.Reserved <> 0. This conforms to RFC4717."
1923 module_t
* module_n1_cw
;
1924 module_t
* module_aal5_sdu
;
1926 module_n1_cw
= prefs_register_protocol(proto_n1_cw
,NULL
);
1927 prefs_register_bool_preference(module_n1_cw
1928 ,"allow_cw_length_nonzero"
1929 ,"Allow CW.Length <> 0"
1930 ,&description_allow_cw_length_nonzero
[0]
1931 ,&pref_n1_cw_allow_cw_length_nonzero
);
1932 prefs_register_bool_preference(module_n1_cw
1933 ,"extend_cw_length_with_rsvd"
1934 ,"Use CW.Reserved as extension of CW.Length"
1935 ,&description_extend_cw_length_with_rsvd
[0]
1936 ,&pref_n1_cw_extend_cw_length_with_rsvd
);
1938 module_aal5_sdu
= prefs_register_protocol(proto_aal5_sdu
,NULL
);
1939 prefs_register_bool_preference(module_aal5_sdu
1940 ,"allow_cw_length_nonzero_aal5"
1941 ,"Allow CW.Length <> 0"
1942 ,&description_allow_cw_length_nonzero
[0]
1943 ,&pref_aal5_sdu_allow_cw_length_nonzero
);
1944 prefs_register_bool_preference(module_aal5_sdu
1945 ,"extend_cw_length_with_rsvd_aal5"
1946 ,"Use CW.Reserved as extension of CW.Length"
1947 ,&description_extend_cw_length_with_rsvd
[0]
1948 ,&pref_aal5_sdu_extend_cw_length_with_rsvd
);
1954 proto_reg_handoff_pw_atm_ata(void)
1956 dissector_handle_t h
;
1957 h
= find_dissector("mpls_pw_atm_n1_cw");
1958 dissector_add_uint( "mpls.label", MPLS_LABEL_INVALID
, h
);
1959 h
= find_dissector("mpls_pw_atm_n1_nocw");
1960 dissector_add_uint( "mpls.label", MPLS_LABEL_INVALID
, h
);
1961 h
= find_dissector("mpls_pw_atm_11_or_aal5_pdu");
1962 dissector_add_uint( "mpls.label", MPLS_LABEL_INVALID
, h
);
1963 h
= find_dissector("mpls_pw_atm_aal5_sdu");
1964 dissector_add_uint( "mpls.label", MPLS_LABEL_INVALID
, h
);
1966 dh_cell
= find_dissector("mpls_pw_atm_cell");
1967 dh_cell_header
= find_dissector("mpls_pw_atm_cell_header");
1968 dh_control_word
= find_dissector("mpls_pw_atm_control_word");
1969 dh_atm_truncated
= find_dissector("atm_truncated");
1970 dh_atm_untruncated
= find_dissector("atm_untruncated");
1971 dh_atm_oam_cell
= find_dissector("atm_oam_cell");
1972 dh_padding
= find_dissector("pw_padding");
1973 dh_data
= find_dissector("data");