2 * Routines for ATM packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <epan/packet.h>
14 #include <epan/capture_dissectors.h>
15 #include <wsutil/pint.h>
17 #include <epan/ppptypes.h>
18 #include <epan/expert.h>
19 #include <epan/crc10-tvb.h>
20 #include <epan/crc32-tvb.h>
21 #include <epan/decode_as.h>
24 #include "packet-atm.h"
25 #include "packet-snmp.h"
26 #include <epan/prefs.h>
27 #include "packet-pw-atm.h"
29 void proto_register_atm(void);
30 void proto_reg_handoff_atm(void);
33 static int hf_atm_aal
;
34 static int hf_atm_gfc
;
35 static int hf_atm_vpi
;
36 static int hf_atm_vci
;
37 static int hf_atm_cid
;
38 static int hf_atm_reserved
;
39 static int proto_atm_lane
;
40 static int proto_ilmi
;
41 static int proto_aal1
;
42 static int proto_aal3_4
;
43 static int proto_oamaal
;
45 static int hf_atm_le_client_client
;
46 static int hf_atm_lan_destination_tag
;
47 static int hf_atm_lan_destination_mac
;
48 static int hf_atm_le_control_tlv_type
;
49 static int hf_atm_le_control_tlv_length
;
50 static int hf_atm_lan_destination_route_desc
;
51 static int hf_atm_lan_destination_lan_id
;
52 static int hf_atm_lan_destination_bridge_num
;
53 static int hf_atm_source_atm
;
54 static int hf_atm_target_atm
;
55 static int hf_atm_le_configure_join_frame_lan_type
;
56 static int hf_atm_le_configure_join_frame_max_frame_size
;
57 static int hf_atm_le_configure_join_frame_num_tlvs
;
58 static int hf_atm_le_configure_join_frame_elan_name_size
;
59 static int hf_atm_le_configure_join_frame_elan_name
;
60 static int hf_atm_le_registration_frame_num_tlvs
;
61 static int hf_atm_le_arp_frame_num_tlvs
;
62 static int hf_atm_le_verify_frame_num_tlvs
;
63 static int hf_atm_le_control_marker
;
64 static int hf_atm_le_control_protocol
;
65 static int hf_atm_le_control_version
;
66 static int hf_atm_le_control_opcode
;
67 static int hf_atm_le_control_status
;
68 static int hf_atm_le_control_transaction_id
;
69 static int hf_atm_le_control_requester_lecid
;
70 static int hf_atm_le_control_flags
;
71 static int hf_atm_le_control_flag_v2_capable
;
72 static int hf_atm_le_control_flag_selective_multicast
;
73 static int hf_atm_le_control_flag_v2_required
;
74 static int hf_atm_le_control_flag_proxy
;
75 static int hf_atm_le_control_flag_exclude_explorer_frames
;
76 static int hf_atm_le_control_flag_address
;
77 static int hf_atm_le_control_topology_change
;
78 static int hf_atm_traffic_type
;
79 static int hf_atm_traffic_vcmx
;
80 static int hf_atm_traffic_lane
;
81 static int hf_atm_traffic_ipsilon
;
82 static int hf_atm_cells
;
83 static int hf_atm_aal5_uu
;
84 static int hf_atm_aal5_cpi
;
85 static int hf_atm_aal5_len
;
86 static int hf_atm_aal5_crc
;
87 static int hf_atm_payload_type
;
88 static int hf_atm_cell_loss_priority
;
89 static int hf_atm_header_error_check
;
90 static int hf_atm_channel
;
91 static int hf_atm_aa1_csi
;
92 static int hf_atm_aa1_seq_count
;
93 static int hf_atm_aa1_crc
;
94 static int hf_atm_aa1_parity
;
95 static int hf_atm_aa1_payload
;
96 static int hf_atm_aal3_4_seg_type
;
97 static int hf_atm_aal3_4_seq_num
;
98 static int hf_atm_aal3_4_multiplex_id
;
99 static int hf_atm_aal3_4_information
;
100 static int hf_atm_aal3_4_length_indicator
;
101 static int hf_atm_aal3_4_crc
;
102 static int hf_atm_aal_oamcell_type
;
103 static int hf_atm_aal_oamcell_type_fm
;
104 static int hf_atm_aal_oamcell_type_pm
;
105 static int hf_atm_aal_oamcell_type_ad
;
106 static int hf_atm_aal_oamcell_type_ft
;
107 static int hf_atm_aal_oamcell_func_spec
;
108 static int hf_atm_aal_oamcell_crc
;
109 static int hf_atm_padding
;
112 static int ett_atm_lane
;
113 static int ett_atm_lane_lc_lan_dest
;
114 static int ett_atm_lane_lc_lan_dest_rd
;
115 static int ett_atm_lane_lc_flags
;
116 static int ett_atm_lane_lc_tlv
;
119 static int ett_aal3_4
;
120 static int ett_oamaal
;
122 static expert_field ei_atm_reassembly_failed
;
124 static dissector_handle_t atm_handle
;
125 static dissector_handle_t atm_untruncated_handle
;
127 static dissector_handle_t eth_withoutfcs_handle
;
128 static dissector_handle_t tr_handle
;
129 static dissector_handle_t fr_handle
;
130 static dissector_handle_t llc_handle
;
131 static dissector_handle_t sscop_handle
;
132 static dissector_handle_t ppp_handle
;
133 static dissector_handle_t eth_maybefcs_handle
;
134 static dissector_handle_t ip_handle
;
136 static bool dissect_lanesscop
;
138 static dissector_table_t atm_type_aal2_table
;
139 static dissector_table_t atm_type_aal5_table
;
140 static dissector_table_t atm_cell_payload_vpi_vci_table
;
141 static dissector_table_t atm_reassembled_vpi_vci_table
;
146 * https://www.broadband-forum.org/index.php?option=com_sppagebuilder&view=page&id=185
148 * for a number of ATM Forum specifications, e.g. the LAN Emulation
149 * over ATM 1.0 spec, whence I got most of this.
152 /* LE Control opcodes */
153 #define LE_CONFIGURE_REQUEST 0x0001
154 #define LE_CONFIGURE_RESPONSE 0x0101
155 #define LE_JOIN_REQUEST 0x0002
156 #define LE_JOIN_RESPONSE 0x0102
157 #define READY_QUERY 0x0003
158 #define READY_IND 0x0103
159 #define LE_REGISTER_REQUEST 0x0004
160 #define LE_REGISTER_RESPONSE 0x0104
161 #define LE_UNREGISTER_REQUEST 0x0005
162 #define LE_UNREGISTER_RESPONSE 0x0105
163 #define LE_ARP_REQUEST 0x0006
164 #define LE_ARP_RESPONSE 0x0106
165 #define LE_FLUSH_REQUEST 0x0007
166 #define LE_FLUSH_RESPONSE 0x0107
167 #define LE_NARP_REQUEST 0x0008
168 #define LE_TOPOLOGY_REQUEST 0x0009
169 #define LE_VERIFY_REQUEST 0x000A
170 #define LE_VERIFY_RESPONSE 0x010A
172 static const value_string le_control_opcode_vals
[] = {
173 { LE_CONFIGURE_REQUEST
, "LE_CONFIGURE_REQUEST" },
174 { LE_CONFIGURE_RESPONSE
, "LE_CONFIGURE_RESPONSE" },
175 { LE_JOIN_REQUEST
, "LE_JOIN_REQUEST" },
176 { LE_JOIN_RESPONSE
, "LE_JOIN_RESPONSE" },
177 { READY_QUERY
, "READY_QUERY" },
178 { READY_IND
, "READY_IND" },
179 { LE_REGISTER_REQUEST
, "LE_REGISTER_REQUEST" },
180 { LE_REGISTER_RESPONSE
, "LE_REGISTER_RESPONSE" },
181 { LE_UNREGISTER_REQUEST
, "LE_UNREGISTER_REQUEST" },
182 { LE_UNREGISTER_RESPONSE
, "LE_UNREGISTER_RESPONSE" },
183 { LE_ARP_REQUEST
, "LE_ARP_REQUEST" },
184 { LE_ARP_RESPONSE
, "LE_ARP_RESPONSE" },
185 { LE_FLUSH_REQUEST
, "LE_FLUSH_REQUEST" },
186 { LE_FLUSH_RESPONSE
, "LE_FLUSH_RESPONSE" },
187 { LE_NARP_REQUEST
, "LE_NARP_REQUEST" },
188 { LE_TOPOLOGY_REQUEST
, "LE_TOPOLOGY_REQUEST" },
189 { LE_VERIFY_REQUEST
, "LE_VERIFY_REQUEST" },
190 { LE_VERIFY_RESPONSE
, "LE_VERIFY_RESPONSE" },
194 /* LE Control statuses */
195 static const value_string le_control_status_vals
[] = {
197 { 1, "Version not supported" },
198 { 2, "Invalid request parameters" },
199 { 4, "Duplicate LAN destination registration" },
200 { 5, "Duplicate ATM address" },
201 { 6, "Insufficient resources to grant request" },
202 { 7, "Access denied" },
203 { 8, "Invalid REQUESTOR-ID" },
204 { 9, "Invalid LAN destination" },
205 { 10, "Invalid ATM address" },
206 { 20, "No configuration" },
207 { 21, "LE_CONFIGURE error" },
208 { 22, "Insufficient information" },
209 { 24, "TLV not found" },
213 /* LE Control LAN destination tags */
214 #define TAG_NOT_PRESENT 0x0000
215 #define TAG_MAC_ADDRESS 0x0001
216 #define TAG_ROUTE_DESCRIPTOR 0x0002
218 static const value_string le_control_landest_tag_vals
[] = {
219 { TAG_NOT_PRESENT
, "Not present" },
220 { TAG_MAC_ADDRESS
, "MAC address" },
221 { TAG_ROUTE_DESCRIPTOR
, "Route descriptor" },
225 /* LE Control LAN types */
226 #define LANT_UNSPEC 0x00
227 #define LANT_802_3 0x01
228 #define LANT_802_5 0x02
230 static const value_string le_control_lan_type_vals
[] = {
231 { LANT_UNSPEC
, "Unspecified" },
232 { LANT_802_3
, "Ethernet/802.3" },
233 { LANT_802_5
, "802.5" },
237 static const value_string le_control_frame_size_vals
[] = {
238 { 0x00, "Unspecified" },
239 { 0x01, "1516/1528/1580/1592" },
240 { 0x02, "4544/4556/1580/1592" },
241 { 0x03, "9234/9246" },
242 { 0x04, "18190/18202" },
246 static const value_string atm_channel_vals
[] = {
252 static const true_false_string tfs_remote_local
= { "Remote", "Local" };
253 static const true_false_string tfs_low_high_priority
= { "Low priority", "High priority" };
257 dissect_le_client(tvbuff_t
*tvb
, proto_tree
*tree
)
260 proto_tree
*lane_tree
;
263 ti
= proto_tree_add_protocol_format(tree
, proto_atm_lane
, tvb
, 0, 2, "ATM LANE");
264 lane_tree
= proto_item_add_subtree(ti
, ett_atm_lane
);
266 proto_tree_add_item(lane_tree
, hf_atm_le_client_client
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
271 dissect_lan_destination(tvbuff_t
*tvb
, int offset
, const char *type
, proto_tree
*tree
)
274 proto_tree
*dest_tree
;
278 dest_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 8,
279 ett_atm_lane_lc_lan_dest
, NULL
, "%s LAN destination", type
);
280 tag
= tvb_get_ntohs(tvb
, offset
);
281 proto_tree_add_item(dest_tree
, hf_atm_lan_destination_tag
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
286 case TAG_MAC_ADDRESS
:
287 proto_tree_add_item(dest_tree
, hf_atm_lan_destination_mac
, tvb
, offset
, 6, ENC_NA
);
290 case TAG_ROUTE_DESCRIPTOR
:
292 td
= proto_tree_add_item(dest_tree
, hf_atm_lan_destination_route_desc
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
293 rd_tree
= proto_item_add_subtree(td
, ett_atm_lane_lc_lan_dest_rd
);
294 proto_tree_add_item(rd_tree
, hf_atm_lan_destination_lan_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
295 proto_tree_add_item(rd_tree
, hf_atm_lan_destination_bridge_num
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
301 * TLV values in LE Control frames.
303 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
305 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
306 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
307 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
308 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
309 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
310 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
311 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
312 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
313 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
314 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
315 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
316 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
317 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
318 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
319 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
320 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
321 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
322 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
323 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
324 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
325 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
326 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
328 static const value_string le_tlv_type_vals
[] = {
329 { LE_CONTROL_TIMEOUT
, "Control Time-out" },
330 { LE_MAX_UNK_FRAME_COUNT
, "Maximum Unknown Frame Count" },
331 { LE_MAX_UNK_FRAME_TIME
, "Maximum Unknown Frame Time" },
332 { LE_VCC_TIMEOUT_PERIOD
, "VCC Time-out" },
333 { LE_MAX_RETRY_COUNT
, "Maximum Retry Count" },
334 { LE_AGING_TIME
, "Aging Time" },
335 { LE_FORWARD_DELAY_TIME
, "Forwarding Delay Time" },
336 { LE_EXPECTED_ARP_RESPONSE_TIME
, "Expected LE_ARP Response Time" },
337 { LE_FLUSH_TIMEOUT
, "Flush Time-out" },
338 { LE_PATH_SWITCHING_DELAY
, "Path Switching Delay" },
339 { LE_LOCAL_SEGMENT_ID
, "Local Segment ID" },
340 { LE_MCAST_SEND_VCC_TYPE
, "Mcast Send VCC Type" },
341 { LE_MCAST_SEND_VCC_AVGRATE
, "Mcast Send VCC AvgRate" },
342 { LE_MCAST_SEND_VCC_PEAKRATE
, "Mcast Send VCC PeakRate" },
343 { LE_CONN_COMPLETION_TIMER
, "Connection Completion Timer" },
344 { LE_CONFIG_FRAG_INFO
, "Config Frag Info" },
345 { LE_LAYER_3_ADDRESS
, "Layer 3 Address" },
346 { LE_ELAN_ID
, "ELAN ID" },
347 { LE_SERVICE_CATEGORY
, "Service Category" },
348 { LE_LLC_MUXED_ATM_ADDRESS
, "LLC-muxed ATM Address" },
349 { LE_X5_ADJUSTMENT
, "X5 Adjustment" },
350 { LE_PREFERRED_LES
, "Preferred LES" },
355 dissect_le_control_tlvs(tvbuff_t
*tvb
, int offset
, unsigned num_tlvs
,
360 proto_tree
*tlv_tree
;
362 while (num_tlvs
!= 0) {
363 tlv_type
= tvb_get_ntohl(tvb
, offset
);
364 tlv_length
= tvb_get_uint8(tvb
, offset
+4);
365 tlv_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 5+tlv_length
, ett_atm_lane_lc_tlv
, NULL
,
366 "TLV type: %s", val_to_str(tlv_type
, le_tlv_type_vals
, "Unknown (0x%08x)"));
367 proto_tree_add_item(tlv_tree
, hf_atm_le_control_tlv_type
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
368 proto_tree_add_item(tlv_tree
, hf_atm_le_control_tlv_length
, tvb
, offset
+4, 1, ENC_BIG_ENDIAN
);
369 offset
+= 5+tlv_length
;
375 dissect_le_configure_join_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
380 dissect_lan_destination(tvb
, offset
, "Source", tree
);
383 dissect_lan_destination(tvb
, offset
, "Target", tree
);
386 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
389 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_lan_type
, tvb
, offset
, 1, ENC_NA
);
392 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_max_frame_size
, tvb
, offset
, 1, ENC_NA
);
395 num_tlvs
= tvb_get_uint8(tvb
, offset
);
396 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
399 name_size
= tvb_get_uint8(tvb
, offset
);
400 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_elan_name_size
, tvb
, offset
, 1, ENC_NA
);
403 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
408 if (name_size
!= 0) {
409 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_elan_name
, tvb
, offset
, name_size
, ENC_NA
);
413 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
417 dissect_le_registration_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
421 dissect_lan_destination(tvb
, offset
, "Source", tree
);
424 dissect_lan_destination(tvb
, offset
, "Target", tree
);
427 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
430 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 2, ENC_NA
);
433 num_tlvs
= tvb_get_uint8(tvb
, offset
);
434 proto_tree_add_item(tree
, hf_atm_le_registration_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
437 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 53, ENC_NA
);
440 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
444 dissect_le_arp_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
448 dissect_lan_destination(tvb
, offset
, "Source", tree
);
451 dissect_lan_destination(tvb
, offset
, "Target", tree
);
454 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
457 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 2, ENC_NA
);
460 num_tlvs
= tvb_get_uint8(tvb
, offset
);
461 proto_tree_add_item(tree
, hf_atm_le_arp_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
464 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 1, ENC_NA
);
467 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
470 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 32, ENC_NA
);
473 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
477 dissect_le_verify_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
481 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 38, ENC_NA
);
484 num_tlvs
= tvb_get_uint8(tvb
, offset
);
485 proto_tree_add_item(tree
, hf_atm_le_verify_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
488 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 1, ENC_NA
);
491 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
494 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 32, ENC_NA
);
497 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
501 dissect_le_flush_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
503 dissect_lan_destination(tvb
, offset
, "Source", tree
);
506 dissect_lan_destination(tvb
, offset
, "Target", tree
);
509 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
512 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 4, ENC_NA
);
515 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
518 proto_tree_add_item(tree
, hf_atm_reserved
, tvb
, offset
, 32, ENC_NA
);
525 dissect_le_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
528 proto_tree
*lane_tree
= NULL
;
531 proto_tree
*flags_tree
;
534 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Control");
537 ti
= proto_tree_add_protocol_format(tree
, proto_atm_lane
, tvb
, offset
, 108, "ATM LANE");
538 lane_tree
= proto_item_add_subtree(ti
, ett_atm_lane
);
540 proto_tree_add_item(lane_tree
, hf_atm_le_control_marker
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
545 proto_tree_add_item(lane_tree
, hf_atm_le_control_protocol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
551 proto_tree_add_item(lane_tree
, hf_atm_le_control_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
555 opcode
= tvb_get_ntohs(tvb
, offset
);
556 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s",
557 val_to_str(opcode
, le_control_opcode_vals
,
558 "Unknown opcode (0x%04X)"));
561 proto_tree_add_item(lane_tree
, hf_atm_le_control_opcode
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
565 if (opcode
== READY_QUERY
|| opcode
== READY_IND
) {
566 /* There's nothing more in this packet. */
571 if (opcode
& 0x0100) {
572 /* Response; decode status. */
573 proto_tree_add_item(lane_tree
, hf_atm_le_control_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
577 proto_tree_add_item(lane_tree
, hf_atm_le_control_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
580 proto_tree_add_item(lane_tree
, hf_atm_le_control_requester_lecid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
583 tf
= proto_tree_add_item(lane_tree
, hf_atm_le_control_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
584 flags_tree
= proto_item_add_subtree(tf
, ett_atm_lane_lc_flags
);
588 case LE_CONFIGURE_REQUEST
:
589 case LE_CONFIGURE_RESPONSE
:
590 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_capable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
592 dissect_le_configure_join_frame(tvb
, offset
, lane_tree
);
595 case LE_JOIN_REQUEST
:
596 case LE_JOIN_RESPONSE
:
597 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_capable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
598 if (opcode
== LE_JOIN_REQUEST
) {
599 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_selective_multicast
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
601 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_required
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
604 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_proxy
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
605 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_exclude_explorer_frames
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
608 dissect_le_configure_join_frame(tvb
, offset
, lane_tree
);
611 case LE_REGISTER_REQUEST
:
612 case LE_REGISTER_RESPONSE
:
613 case LE_UNREGISTER_REQUEST
:
614 case LE_UNREGISTER_RESPONSE
:
616 dissect_le_registration_frame(tvb
, offset
, lane_tree
);
620 case LE_ARP_RESPONSE
:
621 case LE_NARP_REQUEST
:
622 if (opcode
!= LE_NARP_REQUEST
) {
623 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
626 dissect_le_arp_frame(tvb
, offset
, lane_tree
);
629 case LE_TOPOLOGY_REQUEST
:
630 proto_tree_add_item(flags_tree
, hf_atm_le_control_topology_change
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
632 proto_tree_add_item(flags_tree
, hf_atm_reserved
, tvb
, offset
, 92, ENC_NA
);
635 case LE_VERIFY_REQUEST
:
636 case LE_VERIFY_RESPONSE
:
638 dissect_le_verify_frame(tvb
, offset
, lane_tree
);
641 case LE_FLUSH_REQUEST
:
642 case LE_FLUSH_RESPONSE
:
644 dissect_le_flush_frame(tvb
, offset
, lane_tree
);
651 capture_lane(const unsigned char *pd
, int offset _U_
,
652 int len
, capture_packet_info_t
*cpinfo
, const union wtap_pseudo_header
*pseudo_header
)
654 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
655 return try_capture_dissector("atm_lane", pseudo_header
->atm
.subtype
, pd
, 2, len
, cpinfo
, pseudo_header
);
659 dissect_lane(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
661 struct atm_phdr
*atm_info
= (struct atm_phdr
*)data
;
663 tvbuff_t
*next_tvb_le_client
;
665 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM LANE");
667 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
668 switch (atm_info
->subtype
) {
670 case TRAF_ST_LANE_LE_CTRL
:
671 dissect_le_control(tvb
, pinfo
, tree
);
674 case TRAF_ST_LANE_802_3
:
675 case TRAF_ST_LANE_802_3_MC
:
676 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Client - Ethernet/802.3");
677 dissect_le_client(tvb
, tree
);
679 /* Dissect as Ethernet */
680 next_tvb_le_client
= tvb_new_subset_remaining(tvb
, 2);
681 call_dissector(eth_withoutfcs_handle
, next_tvb_le_client
, pinfo
, tree
);
684 case TRAF_ST_LANE_802_5
:
685 case TRAF_ST_LANE_802_5_MC
:
686 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Client - 802.5");
687 dissect_le_client(tvb
, tree
);
689 /* Dissect as Token-Ring */
690 next_tvb_le_client
= tvb_new_subset_remaining(tvb
, 2);
691 call_dissector(tr_handle
, next_tvb_le_client
, pinfo
, tree
);
695 /* Dump it as raw data. */
696 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unknown LANE traffic type");
697 next_tvb
= tvb_new_subset_remaining(tvb
, 0);
698 call_data_dissector(next_tvb
, pinfo
, tree
);
701 return tvb_captured_length(tvb
);
705 dissect_ilmi(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
707 return dissect_snmp_pdu(tvb
, 0, pinfo
, tree
, proto_ilmi
, ett_ilmi
, false);
711 static const value_string aal_vals
[] = {
712 { AAL_UNKNOWN
, "Unknown AAL" },
715 { AAL_3_4
, "AAL3/4" },
717 { AAL_USER
, "User AAL" },
718 { AAL_SIGNALLING
, "Signalling AAL" },
719 { AAL_OAMCELL
, "OAM cell" },
723 /* AAL5 higher-level traffic types */
724 static const value_string aal5_hltype_vals
[] = {
725 { TRAF_UNKNOWN
, "Unknown traffic type" },
726 { TRAF_LLCMX
, "LLC multiplexed" },
727 { TRAF_VCMX
, "VC multiplexed" },
728 { TRAF_LANE
, "LANE" },
729 { TRAF_ILMI
, "ILMI" },
730 { TRAF_FR
, "Frame Relay" },
731 { TRAF_SPANS
, "FORE SPANS" },
732 { TRAF_IPSILON
, "Ipsilon" },
733 { TRAF_GPRS_NS
, "GPRS NS" },
734 { TRAF_SSCOP
, "SSCOP" },
738 /* Traffic subtypes for VC multiplexed traffic */
739 static const value_string vcmx_type_vals
[] = {
740 { TRAF_ST_UNKNOWN
, "Unknown VC multiplexed traffic type" },
741 { TRAF_ST_VCMX_802_3_FCS
, "802.3 FCS" },
742 { TRAF_ST_VCMX_802_4_FCS
, "802.4 FCS" },
743 { TRAF_ST_VCMX_802_5_FCS
, "802.5 FCS" },
744 { TRAF_ST_VCMX_FDDI_FCS
, "FDDI FCS" },
745 { TRAF_ST_VCMX_802_6_FCS
, "802.6 FCS" },
746 { TRAF_ST_VCMX_802_3
, "802.3" },
747 { TRAF_ST_VCMX_802_4
, "802.4" },
748 { TRAF_ST_VCMX_802_5
, "802.5" },
749 { TRAF_ST_VCMX_FDDI
, "FDDI" },
750 { TRAF_ST_VCMX_802_6
, "802.6" },
751 { TRAF_ST_VCMX_FRAGMENTS
, "Fragments" },
752 { TRAF_ST_VCMX_BPDU
, "BPDU" },
756 /* Traffic subtypes for LANE traffic */
757 static const value_string lane_type_vals
[] = {
758 { TRAF_ST_UNKNOWN
, "Unknown LANE traffic type" },
759 { TRAF_ST_LANE_LE_CTRL
, "LE Control" },
760 { TRAF_ST_LANE_802_3
, "802.3" },
761 { TRAF_ST_LANE_802_5
, "802.5" },
762 { TRAF_ST_LANE_802_3_MC
, "802.3 multicast" },
763 { TRAF_ST_LANE_802_5_MC
, "802.5 multicast" },
767 /* Traffic subtypes for Ipsilon traffic */
768 static const value_string ipsilon_type_vals
[] = {
769 { TRAF_ST_UNKNOWN
, "Unknown Ipsilon traffic type" },
770 { TRAF_ST_IPSILON_FT0
, "Flow type 0" },
771 { TRAF_ST_IPSILON_FT1
, "Flow type 1" },
772 { TRAF_ST_IPSILON_FT2
, "Flow type 2" },
777 capture_atm(const unsigned char *pd
, int offset
,
778 int len
, capture_packet_info_t
*cpinfo
, const union wtap_pseudo_header
*pseudo_header
)
780 if (pseudo_header
->atm
.aal
== AAL_5
) {
781 return try_capture_dissector("atm.aal5.type", pseudo_header
->atm
.type
, pd
, offset
, len
, cpinfo
, pseudo_header
);
787 dissect_reassembled_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
788 proto_item
*atm_ti
, proto_tree
*atm_tree
, bool truncated
,
789 struct atm_phdr
*atm_info
, bool pseudowire_mode
)
791 unsigned length
, reported_length
;
792 uint16_t aal5_length
;
800 * This is reassembled traffic, so the cell headers are missing;
801 * show the traffic type for AAL5 traffic, and the VPI and VCI,
802 * from the pseudo-header.
804 if (atm_info
->aal
== AAL_5
) {
805 proto_tree_add_uint(atm_tree
, hf_atm_traffic_type
, tvb
, 0, 0, atm_info
->type
);
807 switch (atm_info
->type
) {
810 proto_tree_add_uint(atm_tree
, hf_atm_traffic_vcmx
, tvb
, 0, 0, atm_info
->subtype
);
814 proto_tree_add_uint(atm_tree
, hf_atm_traffic_lane
, tvb
, 0, 0, atm_info
->subtype
);
818 proto_tree_add_uint(atm_tree
, hf_atm_traffic_ipsilon
, tvb
, 0, 0, atm_info
->subtype
);
822 if (!pseudowire_mode
) {
823 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 0, atm_info
->vpi
);
824 proto_tree_add_uint(atm_tree
, hf_atm_vci
, tvb
, 0, 0, atm_info
->vci
);
826 /* Also show vpi/vci in info column */
827 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " VPI=%u, VCI=%u",
828 atm_info
->vpi
, atm_info
->vci
);
832 if (truncated
|| atm_info
->flags
& ATM_REASSEMBLY_ERROR
) {
834 * The packet data does not include stuff such as the AAL5
835 * trailer, either because it was explicitly left out or because
838 if (atm_info
->cells
!= 0) {
840 * If the cell count is 0, assume it means we don't know how
843 * XXX - also assume it means we don't know what was in the AAL5
844 * trailer. We may, however, find some capture program that can
845 * give us the AAL5 trailer information but not the cell count,
846 * in which case we need some other way of indicating whether we
847 * have the AAL5 trailer information.
850 proto_tree_add_uint(atm_tree
, hf_atm_cells
, tvb
, 0, 0, atm_info
->cells
);
851 proto_tree_add_uint(atm_tree
, hf_atm_aal5_uu
, tvb
, 0, 0, atm_info
->aal5t_u2u
>> 8);
852 proto_tree_add_uint(atm_tree
, hf_atm_aal5_cpi
, tvb
, 0, 0, atm_info
->aal5t_u2u
& 0xFF);
853 proto_tree_add_uint(atm_tree
, hf_atm_aal5_len
, tvb
, 0, 0, atm_info
->aal5t_len
);
854 proto_tree_add_uint(atm_tree
, hf_atm_aal5_crc
, tvb
, 0, 0, atm_info
->aal5t_chksum
);
859 * The packet data includes stuff such as the AAL5 trailer, if
860 * it wasn't cut off by the snapshot length, and ATM reassembly
862 * Decode the trailer, if present, and then chop it off.
864 length
= tvb_captured_length(tvb
);
865 reported_length
= tvb_reported_length(tvb
);
866 if ((reported_length
% 48) == 0) {
868 * Reported length is a multiple of 48, so we can presumably
869 * divide it by 48 to get the number of cells.
871 proto_tree_add_uint(atm_tree
, hf_atm_cells
, tvb
, 0, 0, reported_length
/48);
873 if ((atm_info
->aal
== AAL_5
|| atm_info
->aal
== AAL_SIGNALLING
) &&
874 length
>= reported_length
) {
876 * XXX - what if the packet is truncated? Can that happen?
877 * What if you capture with Windows Sniffer on an ATM link
878 * and tell it not to save the entire packet? What happens
881 aal5_length
= tvb_get_ntohs(tvb
, length
- 6);
884 * Check for sanity in the AAL5 length. It must be > 0
885 * and must be less than the amount of space left after
886 * we remove the trailer.
888 * If it's not sane, assume we don't have a trailer.
890 if (aal5_length
> 0 && aal5_length
<= length
- 8) {
892 * How much padding is there?
894 pad_length
= length
- aal5_length
- 8;
897 * There is no reason for more than 47 bytes of padding.
898 * The most padding you can have would be 7 bytes at the
899 * end of the next-to-last cell (8 bytes after the end of
900 * the data means you can fit the trailer in that cell),
901 * plus 40 bytes in the last cell (with the last 8 bytes
904 * If there's more than 47 bytes of padding, assume we don't
907 if (pad_length
<= 47) {
911 if (pad_length
> 0) {
912 proto_tree_add_item(atm_tree
, hf_atm_padding
, tvb
, aal5_length
, pad_length
, ENC_NA
);
915 proto_tree_add_item(atm_tree
, hf_atm_aal5_uu
, tvb
, length
- 8, 1, ENC_BIG_ENDIAN
);
916 proto_tree_add_item(atm_tree
, hf_atm_aal5_cpi
, tvb
, length
- 7, 1, ENC_BIG_ENDIAN
);
917 proto_tree_add_item(atm_tree
, hf_atm_aal5_len
, tvb
, length
- 6, 2, ENC_BIG_ENDIAN
);
919 crc
= tvb_get_ntohl(tvb
, length
- 4);
920 calc_crc
= crc32_mpeg2_tvb(tvb
, length
);
921 ti
= proto_tree_add_uint(atm_tree
, hf_atm_aal5_crc
, tvb
, length
- 4, 4, crc
);
922 proto_item_append_text(ti
, (calc_crc
== 0xC704DD7B) ? " (correct)" : " (incorrect)");
924 next_tvb
= tvb_new_subset_length(tvb
, 0, aal5_length
);
930 * First check whether custom dissection table
931 * was set up to dissect this VPI+VCI combination
933 if (dissector_try_uint_new(atm_reassembled_vpi_vci_table
,
934 ((atm_info
->vpi
) << 16) | atm_info
->vci
,
935 next_tvb
, pinfo
, tree
, true, atm_info
))
942 * Don't try to dissect the payload of PDUs with a reassembly
945 switch (atm_info
->aal
) {
948 if (!(atm_info
->flags
& ATM_REASSEMBLY_ERROR
)) {
949 call_dissector(sscop_handle
, next_tvb
, pinfo
, tree
);
955 if (!(atm_info
->flags
& ATM_REASSEMBLY_ERROR
)) {
956 if (dissector_try_uint_new(atm_type_aal5_table
, atm_info
->type
, next_tvb
, pinfo
, tree
, true, atm_info
))
962 if (tvb_reported_length(next_tvb
) > 7) /* sizeof(octet) */
965 tvb_memcpy(next_tvb
, octet
, 0, sizeof(octet
));
969 && octet
[2] == 0x03) /* LLC SNAP as per RFC2684 */
971 call_dissector(llc_handle
, next_tvb
, pinfo
, tree
);
974 else if ((pntoh16(octet
) & 0xff) == PPP_IP
)
976 call_dissector(ppp_handle
, next_tvb
, pinfo
, tree
);
979 else if (pntoh16(octet
) == 0x00)
982 * Assume VC multiplexed bridged Ethernet.
983 * Whether there's an FCS is an option negotiated
984 * over the VC, so we call the "do heuristic checks
985 * to see if there's an FCS" version of the Ethernet
988 * See RFC 2684 section 6.2 "VC Multiplexing of Bridged
991 proto_tree_add_item(tree
, hf_atm_padding
, tvb
, 0, 2, ENC_NA
);
992 next_tvb
= tvb_new_subset_remaining(tvb
, 2);
993 call_dissector(eth_maybefcs_handle
, next_tvb
, pinfo
, tree
);
996 else if (octet
[2] == 0x03 && /* NLPID */
997 ((octet
[3] == 0xcc || /* IPv4 */
998 octet
[3] == 0x8e) || /* IPv6 */
999 (octet
[3] == 0x00 && /* Eth */
1000 octet
[4] == 0x80))) /* Eth */
1002 /* assume network interworking with FR 2 byte header */
1003 call_dissector(fr_handle
, next_tvb
, pinfo
, tree
);
1006 else if (octet
[4] == 0x03 && /* NLPID */
1007 ((octet
[5] == 0xcc || /* IPv4 */
1008 octet
[5] == 0x8e) || /* IPv6 */
1009 (octet
[5] == 0x00 && /* Eth */
1010 octet
[6] == 0x80))) /* Eth */
1012 /* assume network interworking with FR 4 byte header */
1013 call_dissector(fr_handle
, next_tvb
, pinfo
, tree
);
1016 else if (((octet
[0] & 0xf0)== 0x40) ||
1017 ((octet
[0] & 0xf0) == 0x60))
1019 call_dissector(ip_handle
, next_tvb
, pinfo
, tree
);
1029 proto_tree_add_uint(atm_tree
, hf_atm_cid
, tvb
, 0, 0,
1030 atm_info
->aal2_cid
);
1031 proto_item_append_text(atm_ti
, " (vpi=%u vci=%u cid=%u)",
1034 atm_info
->aal2_cid
);
1036 if (!(atm_info
->flags
& ATM_REASSEMBLY_ERROR
)) {
1037 if (atm_info
->flags
& ATM_AAL2_NOPHDR
) {
1040 /* Skip first 4 bytes of message
1044 Ignoring for now... */
1045 next_tvb
= tvb_new_subset_remaining(tvb
, 4);
1048 if (dissector_try_uint(atm_type_aal2_table
, atm_info
->type
, next_tvb
, pinfo
, tree
))
1056 /* Dump it as raw data. */
1061 /* Dump it as raw data. */
1062 call_data_dissector(next_tvb
, pinfo
, tree
);
1067 * Charles Michael Heard's HEC code, from
1069 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1071 * with the syndrome and error position tables initialized with values
1072 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1073 * rather than by calling those routines at run time, and with various data
1074 * type cleanups and changes not to correct the header if a correctible
1075 * error was detected.
1077 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1079 static const uint8_t syndrome_table
[256] = {
1080 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1081 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1082 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1083 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1084 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1085 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1086 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1087 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1088 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1089 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1090 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1091 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1092 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1093 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1094 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1095 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1096 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1097 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1098 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1099 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1100 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1101 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1102 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1103 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1104 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1105 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1106 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1107 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1108 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1109 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1110 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1111 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1114 #define NO_ERROR_DETECTED -128
1115 #define UNCORRECTIBLE_ERROR 128
1117 static const int err_posn_table
[256] = {
1118 NO_ERROR_DETECTED
, 39,
1119 38, UNCORRECTIBLE_ERROR
,
1120 37, UNCORRECTIBLE_ERROR
,
1121 UNCORRECTIBLE_ERROR
, 31,
1122 36, UNCORRECTIBLE_ERROR
,
1123 UNCORRECTIBLE_ERROR
, 8,
1124 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1125 30, UNCORRECTIBLE_ERROR
,
1126 35, UNCORRECTIBLE_ERROR
,
1127 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1128 UNCORRECTIBLE_ERROR
, 23,
1129 7, UNCORRECTIBLE_ERROR
,
1130 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1131 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1132 29, UNCORRECTIBLE_ERROR
,
1133 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1134 34, UNCORRECTIBLE_ERROR
,
1135 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1136 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1137 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1138 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1139 22, UNCORRECTIBLE_ERROR
,
1140 6, UNCORRECTIBLE_ERROR
,
1141 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1142 UNCORRECTIBLE_ERROR
, 0,
1143 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1144 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1145 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1146 28, UNCORRECTIBLE_ERROR
,
1147 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1148 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1149 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1150 33, UNCORRECTIBLE_ERROR
,
1151 UNCORRECTIBLE_ERROR
, 10,
1152 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1153 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1154 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1155 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1156 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1157 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1158 UNCORRECTIBLE_ERROR
, 12,
1159 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1160 21, UNCORRECTIBLE_ERROR
,
1161 UNCORRECTIBLE_ERROR
, 19,
1162 5, UNCORRECTIBLE_ERROR
,
1163 UNCORRECTIBLE_ERROR
, 17,
1164 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1165 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1166 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1167 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1168 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1169 UNCORRECTIBLE_ERROR
, 3,
1170 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1171 UNCORRECTIBLE_ERROR
, 15,
1172 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1173 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1174 27, UNCORRECTIBLE_ERROR
,
1175 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1176 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1177 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1178 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1179 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1180 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1181 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1182 32, UNCORRECTIBLE_ERROR
,
1183 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1184 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1185 9, UNCORRECTIBLE_ERROR
,
1186 UNCORRECTIBLE_ERROR
, 24,
1187 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1188 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1189 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1190 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1191 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1192 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1193 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1194 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1195 UNCORRECTIBLE_ERROR
, 1,
1196 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1197 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1198 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1199 11, UNCORRECTIBLE_ERROR
,
1200 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1201 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1202 20, UNCORRECTIBLE_ERROR
,
1203 UNCORRECTIBLE_ERROR
, 13,
1204 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1205 18, UNCORRECTIBLE_ERROR
,
1206 4, UNCORRECTIBLE_ERROR
,
1207 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1208 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1209 16, UNCORRECTIBLE_ERROR
,
1210 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1211 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1212 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1213 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1214 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1215 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1216 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1217 UNCORRECTIBLE_ERROR
, 25,
1218 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1219 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1220 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1221 2, UNCORRECTIBLE_ERROR
,
1222 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1223 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1224 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1225 14, UNCORRECTIBLE_ERROR
,
1226 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1227 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1228 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1229 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1230 26, UNCORRECTIBLE_ERROR
,
1231 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1232 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1233 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1234 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1235 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1236 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1237 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1238 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1239 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1240 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1241 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1242 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1243 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1244 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1245 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1249 * Return an indication of whether there was an error in the cell header
1250 * and, if so, where the error was, if it was correctable.
1253 get_header_err(const uint8_t *cell_header
)
1255 register uint8_t syndrome
;
1256 register int i
, err_posn
;
1259 for (i
= 0; i
< 4; i
++)
1260 syndrome
= syndrome_table
[syndrome
^ cell_header
[i
]];
1261 syndrome
^= cell_header
[4] ^ COSET_LEADER
;
1263 err_posn
= err_posn_table
[syndrome
];
1266 return NO_ERROR_DETECTED
;
1267 else if (err_posn
< 40)
1270 return UNCORRECTIBLE_ERROR
;
1273 const value_string atm_pt_vals
[] = {
1274 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1275 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1276 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1277 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1278 { 4, "Segment OAM F5 flow related cell" },
1279 { 5, "End-to-end OAM F5 flow related cell" },
1280 { 6, "VC resource management cell" },
1284 static const value_string st_vals
[] = {
1292 #define OAM_TYPE_FM 1 /* Fault Management */
1293 #define OAM_TYPE_PM 2 /* Performance Management */
1294 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1296 static const value_string oam_type_vals
[] = {
1297 { OAM_TYPE_FM
, "Fault Management" },
1298 { OAM_TYPE_PM
, "Performance Management" },
1299 { OAM_TYPE_AD
, "Activation/Deactivation" },
1303 static const value_string ft_fm_vals
[] = {
1304 { 0, "Alarm Indication Signal" },
1305 { 1, "Far End Receive Failure" },
1306 { 8, "OAM Cell Loopback" },
1307 { 4, "Continuity Check" },
1311 static const value_string ft_pm_vals
[] = {
1312 { 0, "Forward Monitoring" },
1313 { 1, "Backward Reporting" },
1314 { 2, "Monitoring and Reporting" },
1318 static const value_string ft_ad_vals
[] = {
1319 { 0, "Performance Monitoring" },
1320 { 1, "Continuity Check" },
1326 dissect_atm_cell_payload(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1327 proto_tree
*tree
, unsigned aal
, bool fill_columns
,
1328 struct atm_phdr
*atm_info
)
1330 proto_tree
*aal_tree
;
1334 uint16_t aal3_4_hdr
, crc10
;
1337 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1339 * First check whether custom dissection table
1340 * was set up to dissect this VPI+VCI combination
1342 if (dissector_try_uint_new(atm_cell_payload_vpi_vci_table
,
1343 ((atm_info
->vpi
) << 16) | atm_info
->vci
,
1344 next_tvb
, pinfo
, tree
, true, atm_info
))
1352 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AAL1");
1353 col_clear(pinfo
->cinfo
, COL_INFO
);
1354 ti
= proto_tree_add_item(tree
, proto_aal1
, tvb
, offset
, -1, ENC_NA
);
1355 aal_tree
= proto_item_add_subtree(ti
, ett_aal1
);
1356 octet
= tvb_get_uint8(tvb
, offset
);
1358 proto_tree_add_item(aal_tree
, hf_atm_aa1_csi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1359 proto_tree_add_item(aal_tree
, hf_atm_aa1_seq_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1360 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Sequence count = %u",
1361 (octet
>> 4) & 0x7);
1362 proto_tree_add_item(aal_tree
, hf_atm_aa1_crc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1363 proto_tree_add_item(aal_tree
, hf_atm_aa1_parity
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1366 proto_tree_add_item(aal_tree
, hf_atm_aa1_payload
, tvb
, offset
, 47, ENC_NA
);
1371 * XXX - or should this be the CS PDU?
1373 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AAL3/4");
1374 col_clear(pinfo
->cinfo
, COL_INFO
);
1375 ti
= proto_tree_add_item(tree
, proto_aal3_4
, tvb
, offset
, -1, ENC_NA
);
1376 aal_tree
= proto_item_add_subtree(ti
, ett_aal3_4
);
1377 aal3_4_hdr
= tvb_get_ntohs(tvb
, offset
);
1378 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s, sequence number = %u",
1379 val_to_str(aal3_4_hdr
>> 14, st_vals
, "Unknown (%u)"),
1380 (aal3_4_hdr
>> 10) & 0xF);
1381 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_seg_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1382 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_seq_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1383 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_multiplex_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1385 length
= tvb_reported_length_remaining(tvb
, offset
);
1386 crc10
= update_crc10_by_bytes_tvb(0, tvb
, offset
, length
);
1389 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_information
, tvb
, offset
, 44, ENC_NA
);
1392 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_length_indicator
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1393 ti
= proto_tree_add_item(aal_tree
, hf_atm_aal3_4_crc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1394 proto_item_append_text(ti
, " (%s)", (crc10
== 0) ? " (correct)" : " (incorrect)");
1400 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "OAM AAL");
1401 col_clear(pinfo
->cinfo
, COL_INFO
);
1403 ti
= proto_tree_add_item(tree
, proto_oamaal
, tvb
, offset
, -1, ENC_NA
);
1404 aal_tree
= proto_item_add_subtree(ti
, ett_oamaal
);
1405 octet
= tvb_get_uint8(tvb
, offset
);
1408 col_add_str(pinfo
->cinfo
, COL_INFO
,
1409 val_to_str(octet
>> 4, oam_type_vals
, "Unknown (%u)"));
1412 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1413 switch (octet
>> 4) {
1416 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_fm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1420 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_pm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1424 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_ad
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1428 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_ft
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1431 length
= tvb_reported_length_remaining(tvb
, offset
);
1432 crc10
= update_crc10_by_bytes_tvb(0, tvb
, offset
, length
);
1435 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_func_spec
, tvb
, offset
, 45, ENC_NA
);
1438 ti
= proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_crc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1439 proto_item_append_text(ti
, " (%s)", (crc10
== 0) ? " (correct)" : " (incorrect)");
1443 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1444 call_data_dissector(next_tvb
, pinfo
, tree
);
1450 * Check for OAM cells.
1451 * OAM F4 is VCI 3 or 4 and PT 0X0.
1455 atm_is_oam_cell(const uint16_t vci
, const uint8_t pt
)
1457 return (((vci
== 3 || vci
== 4) && ((pt
& 0x5) == 0))
1458 || ((pt
& 0x6) == 0x4));
1463 dissect_atm_cell(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1464 proto_tree
*atm_tree
, unsigned aal
, bool nni
,
1465 bool crc_stripped
, const struct atm_phdr
*atm_info
)
1472 struct atm_phdr atm_info_local
;
1476 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1477 * and encoding at UNI reference point as:
1492 octet
= tvb_get_uint8(tvb
, 0);
1493 proto_tree_add_item(atm_tree
, hf_atm_gfc
, tvb
, 0, 1, ENC_NA
);
1494 vpi
= (octet
& 0xF) << 4;
1495 octet
= tvb_get_uint8(tvb
, 1);
1497 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 2, vpi
);
1500 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1501 * and encoding at NNI reference point as:
1516 octet
= tvb_get_uint8(tvb
, 0);
1518 octet
= tvb_get_uint8(tvb
, 1);
1519 vpi
|= (octet
& 0xF0) >> 4;
1520 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 2, vpi
);
1523 vci
= (octet
& 0x0F) << 12;
1524 octet
= tvb_get_uint8(tvb
, 2);
1526 octet
= tvb_get_uint8(tvb
, 3);
1528 proto_tree_add_uint(atm_tree
, hf_atm_vci
, tvb
, 1, 3, vci
);
1529 pt
= (octet
>> 1) & 0x7;
1530 proto_tree_add_item(atm_tree
, hf_atm_payload_type
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1531 proto_tree_add_item(atm_tree
, hf_atm_cell_loss_priority
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1533 if (!crc_stripped
) {
1535 * FF: parse the Header Error Check (HEC).
1537 ti
= proto_tree_add_item(atm_tree
, hf_atm_header_error_check
, tvb
, 4, 1, ENC_BIG_ENDIAN
);
1538 err
= get_header_err((const uint8_t*)tvb_memdup(pinfo
->pool
, tvb
, 0, 5));
1539 if (err
== NO_ERROR_DETECTED
)
1540 proto_item_append_text(ti
, " (correct)");
1541 else if (err
== UNCORRECTIBLE_ERROR
)
1542 proto_item_append_text(ti
, " (uncorrectable error)");
1544 proto_item_append_text(ti
, " (error in bit %d)", err
);
1548 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1549 * Cell Mode) the Header Error Check (HEC) field is stripped.
1550 * So we do nothing here.
1556 * Check for OAM cells.
1557 * XXX - do this for all AAL values, overriding whatever information
1558 * Wiretap got from the file?
1560 if (aal
== AAL_USER
|| aal
== AAL_UNKNOWN
) {
1561 if (atm_is_oam_cell(vci
,pt
)) {
1566 memset(&atm_info_local
, 0, sizeof(atm_info_local
));
1568 atm_info_local
.flags
= atm_info
->flags
;
1569 atm_info_local
.aal
= atm_info
->aal
;
1570 atm_info_local
.type
= atm_info
->type
;
1571 atm_info_local
.subtype
= atm_info
->subtype
;
1572 atm_info_local
.vpi
= atm_info
->vpi
;
1573 atm_info_local
.vci
= atm_info
->vci
;
1574 atm_info_local
.aal2_cid
= atm_info
->aal2_cid
;
1575 atm_info_local
.channel
= atm_info
->channel
;
1576 atm_info_local
.cells
= atm_info
->cells
;
1577 atm_info_local
.aal5t_u2u
= atm_info
->aal5t_u2u
;
1578 atm_info_local
.aal5t_len
= atm_info
->aal5t_len
;
1579 atm_info_local
.aal5t_chksum
= atm_info
->aal5t_chksum
;
1581 atm_info_local
.aal
= aal
;
1582 atm_info_local
.type
= pt
;
1583 atm_info_local
.vpi
= vpi
;
1584 atm_info_local
.vci
= vci
;
1587 dissect_atm_cell_payload(tvb
, offset
, pinfo
, tree
, aal
, true, &atm_info_local
);
1591 dissect_atm_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1592 bool truncated
, struct atm_phdr
*atm_info
, bool pseudowire_mode
)
1594 proto_tree
*atm_tree
= NULL
;
1595 proto_item
*atm_ti
= NULL
;
1597 if ( atm_info
->aal
== AAL_5
&& atm_info
->type
== TRAF_LANE
&&
1598 dissect_lanesscop
) {
1599 atm_info
->aal
= AAL_SIGNALLING
;
1602 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM");
1604 if (!pseudowire_mode
) {
1605 switch (atm_info
->channel
) {
1608 /* Traffic from DTE to DCE. */
1609 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "DCE");
1610 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "DTE");
1614 /* Traffic from DCE to DTE. */
1615 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "DTE");
1616 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "DCE");
1621 if (atm_info
->aal
== AAL_5
) {
1622 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "AAL5 %s",
1623 val_to_str(atm_info
->type
, aal5_hltype_vals
,
1624 "Unknown traffic type (%u)"));
1626 col_add_str(pinfo
->cinfo
, COL_INFO
,
1627 val_to_str(atm_info
->aal
, aal_vals
,
1628 "Unknown AAL (%u)"));
1632 atm_ti
= proto_tree_add_item(tree
, proto_atm
, tvb
, 0, -1, ENC_NA
);
1633 atm_tree
= proto_item_add_subtree(atm_ti
, ett_atm
);
1635 if (!pseudowire_mode
) {
1636 proto_tree_add_uint(atm_tree
, hf_atm_channel
, tvb
, 0, 0, atm_info
->channel
);
1637 if (atm_info
->flags
& ATM_REASSEMBLY_ERROR
)
1638 expert_add_info(pinfo
, atm_ti
, &ei_atm_reassembly_failed
);
1641 proto_tree_add_uint_format_value(atm_tree
, hf_atm_aal
, tvb
, 0, 0,
1644 val_to_str(atm_info
->aal
, aal_vals
,
1645 "Unknown AAL (%u)"));
1647 if (atm_info
->flags
& ATM_RAW_CELL
) {
1648 /* This is a single cell, with the cell header at the beginning. */
1649 if (atm_info
->flags
& ATM_NO_HEC
) {
1650 proto_item_set_len(atm_ti
, 4);
1652 proto_item_set_len(atm_ti
, 5);
1654 dissect_atm_cell(tvb
, pinfo
, tree
, atm_tree
,
1655 atm_info
->aal
, false,
1656 atm_info
->flags
& ATM_NO_HEC
, atm_info
);
1658 /* This is a reassembled PDU. */
1661 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
1662 * In such cases, the dissector data parameter is used to pass info from/to
1663 * PW dissector to ATM dissector. For decoding normal ATM traffic
1664 * data parameter should be NULL.
1666 dissect_reassembled_pdu(tvb
, pinfo
, tree
, atm_tree
, atm_ti
, truncated
,
1667 atm_info
, pseudowire_mode
);
1670 return tvb_reported_length(tvb
);
1674 dissect_atm_truncated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1676 struct atm_phdr
*atm_info
= (struct atm_phdr
*)data
;
1678 DISSECTOR_ASSERT(atm_info
!= NULL
);
1680 return dissect_atm_common(tvb
, pinfo
, tree
, true, atm_info
, false);
1684 dissect_atm_pw_truncated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1686 struct atm_phdr
*atm_info
= (struct atm_phdr
*)data
;
1688 DISSECTOR_ASSERT(atm_info
!= NULL
);
1690 return dissect_atm_common(tvb
, pinfo
, tree
, true, atm_info
, true);
1694 dissect_atm_untruncated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1696 struct atm_phdr
*atm_info
= (struct atm_phdr
*)data
;
1698 DISSECTOR_ASSERT(atm_info
!= NULL
);
1700 return dissect_atm_common(tvb
, pinfo
, tree
, false, atm_info
, false);
1704 dissect_atm_pw_untruncated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1706 struct atm_phdr
*atm_info
= (struct atm_phdr
*)data
;
1708 DISSECTOR_ASSERT(atm_info
!= NULL
);
1710 return dissect_atm_common(tvb
, pinfo
, tree
, false, atm_info
, true);
1714 dissect_atm_oam_cell(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1716 proto_tree
*atm_tree
;
1719 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM");
1721 atm_ti
= proto_tree_add_item(tree
, proto_atm
, tvb
, 0, 0, ENC_NA
);
1722 atm_tree
= proto_item_add_subtree(atm_ti
, ett_atm
);
1724 dissect_atm_cell(tvb
, pinfo
, tree
, atm_tree
, AAL_OAMCELL
, false, false, NULL
);
1725 return tvb_reported_length(tvb
);
1729 dissect_atm_pw_oam_cell(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1731 struct pw_atm_phdr
*pw_atm_info
= (struct pw_atm_phdr
*)data
;
1733 DISSECTOR_ASSERT(pw_atm_info
!= NULL
);
1735 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM");
1737 dissect_atm_cell_payload(tvb
, 0, pinfo
, tree
, AAL_OAMCELL
,
1738 pw_atm_info
->enable_fill_columns_by_atm_dissector
,
1739 &pw_atm_info
->info
);
1741 return tvb_reported_length(tvb
);
1744 static void atm_prompt(packet_info
*pinfo _U_
, char* result
)
1746 snprintf(result
, MAX_DECODE_AS_PROMPT_LEN
, "Decode AAL2 traffic as");
1749 static void *atm_value(packet_info
*pinfo
)
1751 return GUINT_TO_POINTER((unsigned)pinfo
->pseudo_header
->atm
.type
);
1755 proto_register_atm(void)
1757 static hf_register_info hf
[] = {
1759 { "AAL", "atm.aal", FT_UINT8
, BASE_DEC
, VALS(aal_vals
), 0x0,
1762 { "GFC", "atm.GFC", FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1765 { "VPI", "atm.vpi", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1769 { "VCI", "atm.vci", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1773 { "CID", "atm.cid", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1777 { "Reserved", "atm.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1780 { &hf_atm_le_client_client
,
1781 { "LE Client", "atm.le_client.client", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1783 { &hf_atm_lan_destination_tag
,
1784 { "Tag", "atm.lan_destination.tag", FT_UINT16
, BASE_HEX
, VALS(le_control_landest_tag_vals
), 0x0,
1786 { &hf_atm_lan_destination_mac
,
1787 { "MAC address", "atm.lan_destination.mac", FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1789 { &hf_atm_le_control_tlv_type
,
1790 { "TLV Type", "atm.le_control.tlv_type", FT_UINT32
, BASE_HEX
, VALS(le_tlv_type_vals
), 0x0,
1792 { &hf_atm_le_control_tlv_length
,
1793 { "TLV Length", "atm.le_control.tlv_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1795 { &hf_atm_lan_destination_route_desc
,
1796 { "Route descriptor", "atm.lan_destination.route_desc", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1798 { &hf_atm_lan_destination_lan_id
,
1799 { "LAN ID", "atm.lan_destination.lan_id", FT_UINT16
, BASE_DEC
, NULL
, 0xFFF0,
1801 { &hf_atm_lan_destination_bridge_num
,
1802 { "Bridge number", "atm.lan_destination.bridge_num", FT_UINT16
, BASE_DEC
, NULL
, 0x000F,
1804 { &hf_atm_source_atm
,
1805 { "Source ATM address", "atm.source_atm", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1807 { &hf_atm_target_atm
,
1808 { "Target ATM address", "atm.target_atm", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1810 { &hf_atm_le_configure_join_frame_lan_type
,
1811 { "LAN type", "atm.le_configure_join_frame.lan_type", FT_UINT8
, BASE_HEX
, VALS(le_control_lan_type_vals
), 0x0,
1813 { &hf_atm_le_configure_join_frame_max_frame_size
,
1814 { "Maximum frame size", "atm.le_configure_join_frame.max_frame_size", FT_UINT8
, BASE_HEX
, VALS(le_control_frame_size_vals
), 0x0,
1816 { &hf_atm_le_configure_join_frame_num_tlvs
,
1817 { "Number of TLVs", "atm.le_configure_join_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1819 { &hf_atm_le_configure_join_frame_elan_name_size
,
1820 { "ELAN name size", "atm.le_configure_join_frame.elan_name_size", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1822 { &hf_atm_le_registration_frame_num_tlvs
,
1823 { "Number of TLVs", "atm.le_registration_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1825 { &hf_atm_le_arp_frame_num_tlvs
,
1826 { "Number of TLVs", "atm.le_arp_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1828 { &hf_atm_le_verify_frame_num_tlvs
,
1829 { "Number of TLVs", "atm.le_verify_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1831 { &hf_atm_le_configure_join_frame_elan_name
,
1832 { "ELAN name", "atm.le_configure_join_frame.elan_name", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1834 { &hf_atm_le_control_marker
,
1835 { "Marker", "atm.le_control.marker", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1837 { &hf_atm_le_control_protocol
,
1838 { "Protocol", "atm.le_control.protocol", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1840 { &hf_atm_le_control_version
,
1841 { "Version", "atm.le_control.version", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1843 { &hf_atm_le_control_opcode
,
1844 { "Opcode", "atm.le_control.opcode", FT_UINT16
, BASE_HEX
, VALS(le_control_opcode_vals
), 0x0,
1846 { &hf_atm_le_control_status
,
1847 { "Status", "atm.le_control.status", FT_UINT16
, BASE_HEX
, VALS(le_control_status_vals
), 0x0,
1849 { &hf_atm_le_control_transaction_id
,
1850 { "Transaction ID", "atm.le_control.transaction_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1852 { &hf_atm_le_control_requester_lecid
,
1853 { "Requester LECID", "atm.le_control.requester_lecid", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1855 { &hf_atm_le_control_flags
,
1856 { "Flags", "atm.le_control.flag", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1858 { &hf_atm_le_control_flag_v2_capable
,
1859 { "V2 capable", "atm.le_control.flag.v2_capable", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0002,
1861 { &hf_atm_le_control_flag_selective_multicast
,
1862 { "Selective multicast", "atm.le_control.flag.selective_multicast", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0004,
1864 { &hf_atm_le_control_flag_v2_required
,
1865 { "V2 required", "atm.le_control.flag.v2_required", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0008,
1867 { &hf_atm_le_control_flag_proxy
,
1868 { "Proxy", "atm.le_control.flag.flag_proxy", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0080,
1870 { &hf_atm_le_control_flag_exclude_explorer_frames
,
1871 { "Exclude explorer frames", "atm.le_control.flag.exclude_explorer_frames", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0200,
1873 { &hf_atm_le_control_flag_address
,
1874 { "Address", "atm.le_control.flag.address", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0001,
1876 { &hf_atm_le_control_topology_change
,
1877 { "Topology change", "atm.le_control.flag.topology_change", FT_BOOLEAN
, 16, TFS(&tfs_remote_local
), 0x0100,
1879 { &hf_atm_traffic_type
,
1880 { "Traffic type", "atm.traffic_type", FT_UINT8
, BASE_DEC
, VALS(aal5_hltype_vals
), 0x0,
1882 { &hf_atm_traffic_vcmx
,
1883 { "VC multiplexed traffic type", "atm.traffic.vcmx", FT_UINT8
, BASE_DEC
, VALS(vcmx_type_vals
), 0x0,
1885 { &hf_atm_traffic_lane
,
1886 { "LANE traffic type", "atm.traffic.lane", FT_UINT8
, BASE_DEC
, VALS(lane_type_vals
), 0x0,
1888 { &hf_atm_traffic_ipsilon
,
1889 { "Ipsilon traffic type", "atm.traffic.ipsilon", FT_UINT8
, BASE_DEC
, VALS(ipsilon_type_vals
), 0x0,
1892 { "Cells", "atm.cells", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1895 { "AAL5 UU", "atm.hf_atm.aal5t_uu", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1898 { "AAL5 CPI", "atm.hf_atm.aal5t_cpi", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1901 { "AAL5 len", "atm.aal5t_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1904 { "AAL5 CRC", "atm.aal5t_crc", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1906 { &hf_atm_payload_type
,
1907 { "Payload Type", "atm.payload_type", FT_UINT8
, BASE_DEC
, NULL
, 0x0E,
1909 { &hf_atm_cell_loss_priority
,
1910 { "Cell Loss Priority", "atm.cell_loss_priority", FT_BOOLEAN
, 8, TFS(&tfs_low_high_priority
), 0x01,
1912 { &hf_atm_header_error_check
,
1913 { "Header Error Check", "atm.header_error_check", FT_UINT8
, BASE_HEX
, NULL
, 0,
1916 { "Channel", "atm.channel", FT_UINT16
, BASE_DEC
, VALS(atm_channel_vals
), 0,
1919 { "CSI", "atm.aa1.csi", FT_UINT8
, BASE_DEC
, NULL
, 0x80,
1921 { &hf_atm_aa1_seq_count
,
1922 { "Sequence Count", "atm.aa1.seq_count", FT_UINT8
, BASE_DEC
, NULL
, 0x70,
1925 { "CRC", "atm.aa1.crc", FT_UINT8
, BASE_DEC
, NULL
, 0x08,
1927 { &hf_atm_aa1_parity
,
1928 { "Parity", "atm.aa1.parity", FT_UINT8
, BASE_DEC
, NULL
, 0x07,
1930 { &hf_atm_aa1_payload
,
1931 { "Payload", "atm.aa1.payload", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1933 { &hf_atm_aal3_4_seg_type
,
1934 { "Segment Type", "atm.aal3_4.seg_type", FT_UINT16
, BASE_DEC
, VALS(st_vals
), 0xC000,
1936 { &hf_atm_aal3_4_seq_num
,
1937 { "Sequence Number", "atm.aal3_4.seq_num", FT_UINT16
, BASE_DEC
, NULL
, 0x3C00,
1939 { &hf_atm_aal3_4_multiplex_id
,
1940 { "Multiplex ID", "atm.aal3_4.multiplex_id", FT_UINT16
, BASE_DEC
, NULL
, 0x03FF,
1942 { &hf_atm_aal3_4_information
,
1943 { "Information", "atm.aal3_4.information", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1945 { &hf_atm_aal3_4_length_indicator
,
1946 { "Length Indicator", "atm.aal3_4.length_indicator", FT_UINT16
, BASE_DEC
, VALS(st_vals
), 0xFC00,
1948 { &hf_atm_aal3_4_crc
,
1949 { "CRC", "atm.aal3_4.crc", FT_UINT16
, BASE_DEC
, NULL
, 0x03FF,
1951 { &hf_atm_aal_oamcell_type
,
1952 { "OAM Type", "atm.aal_oamcell.type", FT_UINT8
, BASE_DEC
, VALS(oam_type_vals
), 0xF0,
1954 { &hf_atm_aal_oamcell_type_fm
,
1955 { "Function Type", "atm.aal_oamcell.type.fm", FT_UINT8
, BASE_DEC
, VALS(ft_fm_vals
), 0x0F,
1957 { &hf_atm_aal_oamcell_type_pm
,
1958 { "Function Type", "atm.aal_oamcell.type.pm", FT_UINT8
, BASE_DEC
, VALS(ft_pm_vals
), 0x0F,
1960 { &hf_atm_aal_oamcell_type_ad
,
1961 { "Function Type", "atm.aal_oamcell.type.ad", FT_UINT8
, BASE_DEC
, VALS(ft_ad_vals
), 0x0F,
1963 { &hf_atm_aal_oamcell_type_ft
,
1964 { "Function Type", "atm.aal_oamcell.type.ft", FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
1966 { &hf_atm_aal_oamcell_func_spec
,
1967 { "Function-specific information", "atm.aal_oamcell.func_spec", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1969 { &hf_atm_aal_oamcell_crc
,
1970 { "CRC-10", "atm.aal_oamcell.crc", FT_UINT16
, BASE_HEX
, NULL
, 0x03FF,
1973 { "Padding", "atm.padding", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1978 static int *ett
[] = {
1985 &ett_atm_lane_lc_lan_dest
,
1986 &ett_atm_lane_lc_lan_dest_rd
,
1987 &ett_atm_lane_lc_flags
,
1988 &ett_atm_lane_lc_tlv
,
1991 static ei_register_info ei
[] = {
1992 { &ei_atm_reassembly_failed
, { "atm.reassembly_failed", PI_REASSEMBLE
, PI_ERROR
, "PDU reassembly failed", EXPFILL
}},
1995 expert_module_t
* expert_atm
;
1996 module_t
*atm_module
;
1998 /* Decode As handling */
1999 static build_valid_func atm_da_build_value
[1] = {atm_value
};
2000 static decode_as_value_t atm_da_values
= {atm_prompt
, 1, atm_da_build_value
};
2001 static decode_as_t atm_da
= {"atm", "atm.aal2.type", 1, 0, &atm_da_values
, NULL
, NULL
,
2002 decode_as_default_populate_list
, decode_as_default_reset
, decode_as_default_change
, NULL
};
2004 proto_atm
= proto_register_protocol("Asynchronous Transfer Mode", "ATM", "atm");
2005 proto_aal1
= proto_register_protocol("ATM AAL1", "AAL1", "aal1");
2006 proto_aal3_4
= proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
2007 proto_oamaal
= proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
2008 proto_register_field_array(proto_atm
, hf
, array_length(hf
));
2009 proto_register_subtree_array(ett
, array_length(ett
));
2010 expert_atm
= expert_register_protocol(proto_atm
);
2011 expert_register_field_array(expert_atm
, ei
, array_length(ei
));
2013 proto_ilmi
= proto_register_protocol("ILMI", "ILMI", "ilmi");
2015 proto_atm_lane
= proto_register_protocol("ATM LAN Emulation", "ATM LANE", "lane");
2017 atm_type_aal2_table
= register_dissector_table("atm.aal2.type", "ATM AAL_2 type", proto_atm
, FT_UINT32
, BASE_DEC
);
2018 atm_type_aal5_table
= register_dissector_table("atm.aal5.type", "ATM AAL_5 type", proto_atm
, FT_UINT32
, BASE_DEC
);
2019 atm_cell_payload_vpi_vci_table
= register_dissector_table("atm.cell_payload.vpi_vci", "ATM Cell Payload VPI VCI",
2020 proto_atm
, FT_UINT32
, BASE_DEC
);
2021 atm_reassembled_vpi_vci_table
= register_dissector_table("atm.reassembled.vpi_vci", "ATM Reassembled VPI VCI",
2022 proto_atm
, FT_UINT32
, BASE_DEC
);
2024 register_capture_dissector_table("atm.aal5.type", "ATM AAL_5");
2025 register_capture_dissector_table("atm_lane", "ATM LAN Emulation");
2027 atm_handle
= register_dissector("atm_truncated", dissect_atm_truncated
, proto_atm
);
2028 register_dissector("atm_pw_truncated", dissect_atm_pw_truncated
, proto_atm
);
2029 atm_untruncated_handle
= register_dissector("atm_untruncated", dissect_atm_untruncated
, proto_atm
);
2030 register_dissector("atm_pw_untruncated", dissect_atm_pw_untruncated
, proto_atm
);
2031 register_dissector("atm_oam_cell", dissect_atm_oam_cell
, proto_oamaal
);
2032 register_dissector("atm_pw_oam_cell", dissect_atm_pw_oam_cell
, proto_oamaal
);
2034 atm_module
= prefs_register_protocol ( proto_atm
, NULL
);
2035 prefs_register_bool_preference(atm_module
, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
2036 "Autodetection between LANE and SSCOP is hard. As default LANE is preferred",
2037 &dissect_lanesscop
);
2038 prefs_register_obsolete_preference(atm_module
, "unknown_aal2_type");
2040 register_decode_as(&atm_da
);
2044 proto_reg_handoff_atm(void)
2046 capture_dissector_handle_t atm_cap_handle
;
2049 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
2050 * SSCOP, LANE, and ILMI dissectors.
2052 eth_withoutfcs_handle
= find_dissector_add_dependency("eth_withoutfcs", proto_atm_lane
);
2053 tr_handle
= find_dissector_add_dependency("tr", proto_atm_lane
);
2054 fr_handle
= find_dissector_add_dependency("fr", proto_atm
);
2055 llc_handle
= find_dissector_add_dependency("llc", proto_atm
);
2056 sscop_handle
= find_dissector_add_dependency("sscop", proto_atm
);
2057 ppp_handle
= find_dissector_add_dependency("ppp", proto_atm
);
2058 eth_maybefcs_handle
= find_dissector_add_dependency("eth_maybefcs", proto_atm
);
2059 ip_handle
= find_dissector_add_dependency("ip", proto_atm
);
2061 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS
, atm_handle
);
2062 dissector_add_uint("atm.aal5.type", TRAF_LANE
, create_dissector_handle(dissect_lane
, proto_atm_lane
));
2063 dissector_add_uint("atm.aal5.type", TRAF_ILMI
, create_dissector_handle(dissect_ilmi
, proto_ilmi
));
2065 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED
,
2066 atm_untruncated_handle
);
2068 atm_cap_handle
= create_capture_dissector_handle(capture_atm
, proto_atm
);
2069 capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS
, atm_cap_handle
);
2070 atm_cap_handle
= create_capture_dissector_handle(capture_lane
, proto_atm_lane
);
2071 capture_dissector_add_uint("atm.aal5.type", TRAF_LANE
, atm_cap_handle
);
2075 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2080 * indent-tabs-mode: nil
2083 * ex: set shiftwidth=2 tabstop=8 expandtab:
2084 * :indentSize=2:tabSize=8:noTabs=true: