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/addr_resolv.h>
18 #include <epan/ppptypes.h>
19 #include <epan/expert.h>
20 #include <epan/crc10-tvb.h>
21 #include <epan/crc32-tvb.h>
22 #include <epan/decode_as.h>
24 #include "packet-atm.h"
25 #include "packet-snmp.h"
26 #include "packet-eth.h"
27 #include "packet-tr.h"
28 #include "packet-llc.h"
29 #include <epan/prefs.h>
30 #include "packet-pw-atm.h"
32 void proto_register_atm(void);
33 void proto_reg_handoff_atm(void);
35 static int proto_atm = -1;
36 static int hf_atm_aal = -1;
37 static int hf_atm_gfc = -1;
38 static int hf_atm_vpi = -1;
39 static int hf_atm_vci = -1;
40 static int hf_atm_cid = -1;
41 static int hf_atm_reserved = -1;
42 static int proto_atm_lane = -1;
43 static int proto_ilmi = -1;
44 static int proto_aal1 = -1;
45 static int proto_aal3_4 = -1;
46 static int proto_oamaal = -1;
48 static int hf_atm_le_client_client = -1;
49 static int hf_atm_lan_destination_tag = -1;
50 static int hf_atm_lan_destination_mac = -1;
51 static int hf_atm_le_control_tlv_type = -1;
52 static int hf_atm_le_control_tlv_length = -1;
53 static int hf_atm_lan_destination_route_desc = -1;
54 static int hf_atm_lan_destination_lan_id = -1;
55 static int hf_atm_lan_destination_bridge_num = -1;
56 static int hf_atm_source_atm = -1;
57 static int hf_atm_target_atm = -1;
58 static int hf_atm_le_configure_join_frame_lan_type = -1;
59 static int hf_atm_le_configure_join_frame_max_frame_size = -1;
60 static int hf_atm_le_configure_join_frame_num_tlvs = -1;
61 static int hf_atm_le_configure_join_frame_elan_name_size = -1;
62 static int hf_atm_le_configure_join_frame_elan_name = -1;
63 static int hf_atm_le_registration_frame_num_tlvs = -1;
64 static int hf_atm_le_arp_frame_num_tlvs = -1;
65 static int hf_atm_le_verify_frame_num_tlvs = -1;
66 static int hf_atm_le_control_marker = -1;
67 static int hf_atm_le_control_protocol = -1;
68 static int hf_atm_le_control_version = -1;
69 static int hf_atm_le_control_opcode = -1;
70 static int hf_atm_le_control_status = -1;
71 static int hf_atm_le_control_transaction_id = -1;
72 static int hf_atm_le_control_requester_lecid = -1;
73 static int hf_atm_le_control_flags = -1;
74 static int hf_atm_le_control_flag_v2_capable = -1;
75 static int hf_atm_le_control_flag_selective_multicast = -1;
76 static int hf_atm_le_control_flag_v2_required = -1;
77 static int hf_atm_le_control_flag_proxy = -1;
78 static int hf_atm_le_control_flag_exclude_explorer_frames = -1;
79 static int hf_atm_le_control_flag_address = -1;
80 static int hf_atm_le_control_topology_change = -1;
81 static int hf_atm_traffic_type = -1;
82 static int hf_atm_traffic_vcmx = -1;
83 static int hf_atm_traffic_lane = -1;
84 static int hf_atm_traffic_ipsilon = -1;
85 static int hf_atm_cells = -1;
86 static int hf_atm_aal5_uu = -1;
87 static int hf_atm_aal5_cpi = -1;
88 static int hf_atm_aal5_len = -1;
89 static int hf_atm_aal5_crc = -1;
90 static int hf_atm_payload_type = -1;
91 static int hf_atm_cell_loss_priority = -1;
92 static int hf_atm_header_error_check = -1;
93 static int hf_atm_channel = -1;
94 static int hf_atm_aa1_csi = -1;
95 static int hf_atm_aa1_seq_count = -1;
96 static int hf_atm_aa1_crc = -1;
97 static int hf_atm_aa1_parity = -1;
98 static int hf_atm_aa1_payload = -1;
99 static int hf_atm_aal3_4_seg_type = -1;
100 static int hf_atm_aal3_4_seq_num = -1;
101 static int hf_atm_aal3_4_multiplex_id = -1;
102 static int hf_atm_aal3_4_information = -1;
103 static int hf_atm_aal3_4_length_indicator = -1;
104 static int hf_atm_aal3_4_crc = -1;
105 static int hf_atm_aal_oamcell_type = -1;
106 static int hf_atm_aal_oamcell_type_fm = -1;
107 static int hf_atm_aal_oamcell_type_pm = -1;
108 static int hf_atm_aal_oamcell_type_ad = -1;
109 static int hf_atm_aal_oamcell_type_ft = -1;
110 static int hf_atm_aal_oamcell_func_spec = -1;
111 static int hf_atm_aal_oamcell_crc = -1;
112 static int hf_atm_padding = -1;
114 static gint ett_atm = -1;
115 static gint ett_atm_lane = -1;
116 static gint ett_atm_lane_lc_lan_dest = -1;
117 static gint ett_atm_lane_lc_lan_dest_rd = -1;
118 static gint ett_atm_lane_lc_flags = -1;
119 static gint ett_atm_lane_lc_tlv = -1;
120 static gint ett_ilmi = -1;
121 static gint ett_aal1 = -1;
122 static gint ett_aal3_4 = -1;
123 static gint ett_oamaal = -1;
125 static expert_field ei_atm_reassembly_failed = EI_INIT;
127 static dissector_handle_t atm_handle;
128 static dissector_handle_t atm_untruncated_handle;
130 static dissector_handle_t eth_withoutfcs_handle;
131 static dissector_handle_t tr_handle;
132 static dissector_handle_t fr_handle;
133 static dissector_handle_t llc_handle;
134 static dissector_handle_t sscop_handle;
135 static dissector_handle_t ppp_handle;
136 static dissector_handle_t eth_maybefcs_handle;
137 static dissector_handle_t ip_handle;
139 static gboolean dissect_lanesscop = FALSE;
141 static dissector_table_t atm_type_aal2_table;
142 static dissector_table_t atm_type_aal5_table;
143 static dissector_table_t atm_cell_payload_vpi_vci_table;
144 static dissector_table_t atm_reassembled_vpi_vci_table;
149 * https://www.broadband-forum.org/index.php?option=com_sppagebuilder&view=page&id=185
151 * for a number of ATM Forum specifications, e.g. the LAN Emulation
152 * over ATM 1.0 spec, whence I got most of this.
155 /* LE Control opcodes */
156 #define LE_CONFIGURE_REQUEST 0x0001
157 #define LE_CONFIGURE_RESPONSE 0x0101
158 #define LE_JOIN_REQUEST 0x0002
159 #define LE_JOIN_RESPONSE 0x0102
160 #define READY_QUERY 0x0003
161 #define READY_IND 0x0103
162 #define LE_REGISTER_REQUEST 0x0004
163 #define LE_REGISTER_RESPONSE 0x0104
164 #define LE_UNREGISTER_REQUEST 0x0005
165 #define LE_UNREGISTER_RESPONSE 0x0105
166 #define LE_ARP_REQUEST 0x0006
167 #define LE_ARP_RESPONSE 0x0106
168 #define LE_FLUSH_REQUEST 0x0007
169 #define LE_FLUSH_RESPONSE 0x0107
170 #define LE_NARP_REQUEST 0x0008
171 #define LE_TOPOLOGY_REQUEST 0x0009
172 #define LE_VERIFY_REQUEST 0x000A
173 #define LE_VERIFY_RESPONSE 0x010A
175 static const value_string le_control_opcode_vals[] = {
176 { LE_CONFIGURE_REQUEST, "LE_CONFIGURE_REQUEST" },
177 { LE_CONFIGURE_RESPONSE, "LE_CONFIGURE_RESPONSE" },
178 { LE_JOIN_REQUEST, "LE_JOIN_REQUEST" },
179 { LE_JOIN_RESPONSE, "LE_JOIN_RESPONSE" },
180 { READY_QUERY, "READY_QUERY" },
181 { READY_IND, "READY_IND" },
182 { LE_REGISTER_REQUEST, "LE_REGISTER_REQUEST" },
183 { LE_REGISTER_RESPONSE, "LE_REGISTER_RESPONSE" },
184 { LE_UNREGISTER_REQUEST, "LE_UNREGISTER_REQUEST" },
185 { LE_UNREGISTER_RESPONSE, "LE_UNREGISTER_RESPONSE" },
186 { LE_ARP_REQUEST, "LE_ARP_REQUEST" },
187 { LE_ARP_RESPONSE, "LE_ARP_RESPONSE" },
188 { LE_FLUSH_REQUEST, "LE_FLUSH_REQUEST" },
189 { LE_FLUSH_RESPONSE, "LE_FLUSH_RESPONSE" },
190 { LE_NARP_REQUEST, "LE_NARP_REQUEST" },
191 { LE_TOPOLOGY_REQUEST, "LE_TOPOLOGY_REQUEST" },
192 { LE_VERIFY_REQUEST, "LE_VERIFY_REQUEST" },
193 { LE_VERIFY_RESPONSE, "LE_VERIFY_RESPONSE" },
197 /* LE Control statuses */
198 static const value_string le_control_status_vals[] = {
200 { 1, "Version not supported" },
201 { 2, "Invalid request parameters" },
202 { 4, "Duplicate LAN destination registration" },
203 { 5, "Duplicate ATM address" },
204 { 6, "Insufficient resources to grant request" },
205 { 7, "Access denied" },
206 { 8, "Invalid REQUESTOR-ID" },
207 { 9, "Invalid LAN destination" },
208 { 10, "Invalid ATM address" },
209 { 20, "No configuration" },
210 { 21, "LE_CONFIGURE error" },
211 { 22, "Insufficient information" },
212 { 24, "TLV not found" },
216 /* LE Control LAN destination tags */
217 #define TAG_NOT_PRESENT 0x0000
218 #define TAG_MAC_ADDRESS 0x0001
219 #define TAG_ROUTE_DESCRIPTOR 0x0002
221 static const value_string le_control_landest_tag_vals[] = {
222 { TAG_NOT_PRESENT, "Not present" },
223 { TAG_MAC_ADDRESS, "MAC address" },
224 { TAG_ROUTE_DESCRIPTOR, "Route descriptor" },
228 /* LE Control LAN types */
229 #define LANT_UNSPEC 0x00
230 #define LANT_802_3 0x01
231 #define LANT_802_5 0x02
233 static const value_string le_control_lan_type_vals[] = {
234 { LANT_UNSPEC, "Unspecified" },
235 { LANT_802_3, "Ethernet/802.3" },
236 { LANT_802_5, "802.5" },
240 static const value_string le_control_frame_size_vals[] = {
241 { 0x00, "Unspecified" },
242 { 0x01, "1516/1528/1580/1592" },
243 { 0x02, "4544/4556/1580/1592" },
244 { 0x03, "9234/9246" },
245 { 0x04, "18190/18202" },
249 static const value_string atm_channel_vals[] = {
255 static const true_false_string tfs_remote_local = { "Remote", "Local" };
256 static const true_false_string tfs_low_high_priority = { "Low priority", "High priority" };
260 dissect_le_client(tvbuff_t *tvb, proto_tree *tree)
263 proto_tree *lane_tree;
266 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, 0, 2, "ATM LANE");
267 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
269 proto_tree_add_item(lane_tree, hf_atm_le_client_client, tvb, 0, 2, ENC_BIG_ENDIAN );
274 dissect_lan_destination(tvbuff_t *tvb, int offset, const char *type, proto_tree *tree)
277 proto_tree *dest_tree;
281 dest_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
282 ett_atm_lane_lc_lan_dest, NULL, "%s LAN destination", type);
283 tag = tvb_get_ntohs(tvb, offset);
284 proto_tree_add_item(dest_tree, hf_atm_lan_destination_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
289 case TAG_MAC_ADDRESS:
290 proto_tree_add_item(dest_tree, hf_atm_lan_destination_mac, tvb, offset, 6, ENC_NA);
293 case TAG_ROUTE_DESCRIPTOR:
295 td = proto_tree_add_item(dest_tree, hf_atm_lan_destination_route_desc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
296 rd_tree = proto_item_add_subtree(td, ett_atm_lane_lc_lan_dest_rd);
297 proto_tree_add_item(rd_tree, hf_atm_lan_destination_lan_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
298 proto_tree_add_item(rd_tree, hf_atm_lan_destination_bridge_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
304 * TLV values in LE Control frames.
306 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
308 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
309 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
310 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
311 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
312 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
313 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
314 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
315 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
316 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
317 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
318 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
319 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
320 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
321 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
322 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
323 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
324 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
325 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
326 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
327 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
328 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
329 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
331 static const value_string le_tlv_type_vals[] = {
332 { LE_CONTROL_TIMEOUT, "Control Time-out" },
333 { LE_MAX_UNK_FRAME_COUNT, "Maximum Unknown Frame Count" },
334 { LE_MAX_UNK_FRAME_TIME, "Maximum Unknown Frame Time" },
335 { LE_VCC_TIMEOUT_PERIOD, "VCC Time-out" },
336 { LE_MAX_RETRY_COUNT, "Maximum Retry Count" },
337 { LE_AGING_TIME, "Aging Time" },
338 { LE_FORWARD_DELAY_TIME, "Forwarding Delay Time" },
339 { LE_EXPECTED_ARP_RESPONSE_TIME, "Expected LE_ARP Response Time" },
340 { LE_FLUSH_TIMEOUT, "Flush Time-out" },
341 { LE_PATH_SWITCHING_DELAY, "Path Switching Delay" },
342 { LE_LOCAL_SEGMENT_ID, "Local Segment ID" },
343 { LE_MCAST_SEND_VCC_TYPE, "Mcast Send VCC Type" },
344 { LE_MCAST_SEND_VCC_AVGRATE, "Mcast Send VCC AvgRate" },
345 { LE_MCAST_SEND_VCC_PEAKRATE, "Mcast Send VCC PeakRate" },
346 { LE_CONN_COMPLETION_TIMER, "Connection Completion Timer" },
347 { LE_CONFIG_FRAG_INFO, "Config Frag Info" },
348 { LE_LAYER_3_ADDRESS, "Layer 3 Address" },
349 { LE_ELAN_ID, "ELAN ID" },
350 { LE_SERVICE_CATEGORY, "Service Category" },
351 { LE_LLC_MUXED_ATM_ADDRESS, "LLC-muxed ATM Address" },
352 { LE_X5_ADJUSTMENT, "X5 Adjustment" },
353 { LE_PREFERRED_LES, "Preferred LES" },
358 dissect_le_control_tlvs(tvbuff_t *tvb, int offset, guint num_tlvs,
363 proto_tree *tlv_tree;
365 while (num_tlvs != 0) {
366 tlv_type = tvb_get_ntohl(tvb, offset);
367 tlv_length = tvb_get_guint8(tvb, offset+4);
368 tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, 5+tlv_length, ett_atm_lane_lc_tlv, NULL,
369 "TLV type: %s", val_to_str(tlv_type, le_tlv_type_vals, "Unknown (0x%08x)"));
370 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_type, tvb, offset, 4, ENC_BIG_ENDIAN);
371 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_length, tvb, offset+4, 1, ENC_BIG_ENDIAN);
372 offset += 5+tlv_length;
378 dissect_le_configure_join_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
383 dissect_lan_destination(tvb, offset, "Source", tree);
386 dissect_lan_destination(tvb, offset, "Target", tree);
389 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
392 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_lan_type, tvb, offset, 1, ENC_NA);
395 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_max_frame_size, tvb, offset, 1, ENC_NA);
398 num_tlvs = tvb_get_guint8(tvb, offset);
399 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_num_tlvs, tvb, offset, 1, ENC_NA);
402 name_size = tvb_get_guint8(tvb, offset);
403 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name_size, tvb, offset, 1, ENC_NA);
406 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
411 if (name_size != 0) {
412 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name, tvb, offset, name_size, ENC_NA);
416 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
420 dissect_le_registration_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
424 dissect_lan_destination(tvb, offset, "Source", tree);
427 dissect_lan_destination(tvb, offset, "Target", tree);
430 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
433 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
436 num_tlvs = tvb_get_guint8(tvb, offset);
437 proto_tree_add_item(tree, hf_atm_le_registration_frame_num_tlvs, tvb, offset, 1, ENC_NA);
440 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 53, ENC_NA);
443 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
447 dissect_le_arp_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
451 dissect_lan_destination(tvb, offset, "Source", tree);
454 dissect_lan_destination(tvb, offset, "Target", tree);
457 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
460 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
463 num_tlvs = tvb_get_guint8(tvb, offset);
464 proto_tree_add_item(tree, hf_atm_le_arp_frame_num_tlvs, tvb, offset, 1, ENC_NA);
467 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
470 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
473 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
476 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
480 dissect_le_verify_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
484 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 38, ENC_NA);
487 num_tlvs = tvb_get_guint8(tvb, offset);
488 proto_tree_add_item(tree, hf_atm_le_verify_frame_num_tlvs, tvb, offset, 1, ENC_NA);
491 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
494 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
497 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
500 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
504 dissect_le_flush_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
506 dissect_lan_destination(tvb, offset, "Source", tree);
509 dissect_lan_destination(tvb, offset, "Target", tree);
512 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
515 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 4, ENC_NA);
518 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
521 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
528 dissect_le_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
531 proto_tree *lane_tree = NULL;
534 proto_tree *flags_tree;
537 col_set_str(pinfo->cinfo, COL_INFO, "LE Control");
540 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, offset, 108, "ATM LANE");
541 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
543 proto_tree_add_item(lane_tree, hf_atm_le_control_marker, tvb, offset, 2, ENC_BIG_ENDIAN );
548 proto_tree_add_item(lane_tree, hf_atm_le_control_protocol, tvb, offset, 1, ENC_BIG_ENDIAN );
554 proto_tree_add_item(lane_tree, hf_atm_le_control_version, tvb, offset, 1, ENC_BIG_ENDIAN );
558 opcode = tvb_get_ntohs(tvb, offset);
559 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
560 val_to_str(opcode, le_control_opcode_vals,
561 "Unknown opcode (0x%04X)"));
564 proto_tree_add_item(lane_tree, hf_atm_le_control_opcode, tvb, offset, 2, ENC_BIG_ENDIAN );
568 if (opcode == READY_QUERY || opcode == READY_IND) {
569 /* There's nothing more in this packet. */
574 if (opcode & 0x0100) {
575 /* Response; decode status. */
576 proto_tree_add_item(lane_tree, hf_atm_le_control_status, tvb, offset, 2, ENC_BIG_ENDIAN );
580 proto_tree_add_item(lane_tree, hf_atm_le_control_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN );
583 proto_tree_add_item(lane_tree, hf_atm_le_control_requester_lecid, tvb, offset, 2, ENC_BIG_ENDIAN );
586 tf = proto_tree_add_item(lane_tree, hf_atm_le_control_flags, tvb, offset, 2, ENC_BIG_ENDIAN );
587 flags_tree = proto_item_add_subtree(tf, ett_atm_lane_lc_flags);
591 case LE_CONFIGURE_REQUEST:
592 case LE_CONFIGURE_RESPONSE:
593 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
595 dissect_le_configure_join_frame(tvb, offset, lane_tree);
598 case LE_JOIN_REQUEST:
599 case LE_JOIN_RESPONSE:
600 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
601 if (opcode == LE_JOIN_REQUEST) {
602 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_selective_multicast, tvb, offset, 2, ENC_BIG_ENDIAN);
604 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_required, tvb, offset, 2, ENC_BIG_ENDIAN);
607 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_proxy, tvb, offset, 2, ENC_BIG_ENDIAN);
608 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_exclude_explorer_frames, tvb, offset, 2, ENC_BIG_ENDIAN);
611 dissect_le_configure_join_frame(tvb, offset, lane_tree);
614 case LE_REGISTER_REQUEST:
615 case LE_REGISTER_RESPONSE:
616 case LE_UNREGISTER_REQUEST:
617 case LE_UNREGISTER_RESPONSE:
619 dissect_le_registration_frame(tvb, offset, lane_tree);
623 case LE_ARP_RESPONSE:
624 case LE_NARP_REQUEST:
625 if (opcode != LE_NARP_REQUEST) {
626 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_address, tvb, offset, 2, ENC_BIG_ENDIAN);
629 dissect_le_arp_frame(tvb, offset, lane_tree);
632 case LE_TOPOLOGY_REQUEST:
633 proto_tree_add_item(flags_tree, hf_atm_le_control_topology_change, tvb, offset, 2, ENC_BIG_ENDIAN);
635 proto_tree_add_item(flags_tree, hf_atm_reserved, tvb, offset, 92, ENC_NA);
638 case LE_VERIFY_REQUEST:
639 case LE_VERIFY_RESPONSE:
641 dissect_le_verify_frame(tvb, offset, lane_tree);
644 case LE_FLUSH_REQUEST:
645 case LE_FLUSH_RESPONSE:
647 dissect_le_flush_frame(tvb, offset, lane_tree);
654 capture_lane(const guchar *pd, int offset _U_,
655 int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
657 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
658 return try_capture_dissector("atm_lane", pseudo_header->atm.subtype, pd, 2, len, cpinfo, pseudo_header);
662 dissect_lane(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
664 struct atm_phdr *atm_info = (struct atm_phdr *)data;
666 tvbuff_t *next_tvb_le_client;
668 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM LANE");
670 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
671 switch (atm_info->subtype) {
673 case TRAF_ST_LANE_LE_CTRL:
674 dissect_le_control(tvb, pinfo, tree);
677 case TRAF_ST_LANE_802_3:
678 case TRAF_ST_LANE_802_3_MC:
679 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - Ethernet/802.3");
680 dissect_le_client(tvb, tree);
682 /* Dissect as Ethernet */
683 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
684 call_dissector(eth_withoutfcs_handle, next_tvb_le_client, pinfo, tree);
687 case TRAF_ST_LANE_802_5:
688 case TRAF_ST_LANE_802_5_MC:
689 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - 802.5");
690 dissect_le_client(tvb, tree);
692 /* Dissect as Token-Ring */
693 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
694 call_dissector(tr_handle, next_tvb_le_client, pinfo, tree);
698 /* Dump it as raw data. */
699 col_set_str(pinfo->cinfo, COL_INFO, "Unknown LANE traffic type");
700 next_tvb = tvb_new_subset_remaining(tvb, 0);
701 call_data_dissector(next_tvb, pinfo, tree);
704 return tvb_captured_length(tvb);
708 dissect_ilmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
710 return dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_ilmi, ett_ilmi, FALSE);
714 static const value_string aal_vals[] = {
715 { AAL_UNKNOWN, "Unknown AAL" },
718 { AAL_3_4, "AAL3/4" },
720 { AAL_USER, "User AAL" },
721 { AAL_SIGNALLING, "Signalling AAL" },
722 { AAL_OAMCELL, "OAM cell" },
726 /* AAL5 higher-level traffic types */
727 static const value_string aal5_hltype_vals[] = {
728 { TRAF_UNKNOWN, "Unknown traffic type" },
729 { TRAF_LLCMX, "LLC multiplexed" },
730 { TRAF_VCMX, "VC multiplexed" },
731 { TRAF_LANE, "LANE" },
732 { TRAF_ILMI, "ILMI" },
733 { TRAF_FR, "Frame Relay" },
734 { TRAF_SPANS, "FORE SPANS" },
735 { TRAF_IPSILON, "Ipsilon" },
736 { TRAF_GPRS_NS, "GPRS NS" },
737 { TRAF_SSCOP, "SSCOP" },
741 /* Traffic subtypes for VC multiplexed traffic */
742 static const value_string vcmx_type_vals[] = {
743 { TRAF_ST_UNKNOWN, "Unknown VC multiplexed traffic type" },
744 { TRAF_ST_VCMX_802_3_FCS, "802.3 FCS" },
745 { TRAF_ST_VCMX_802_4_FCS, "802.4 FCS" },
746 { TRAF_ST_VCMX_802_5_FCS, "802.5 FCS" },
747 { TRAF_ST_VCMX_FDDI_FCS, "FDDI FCS" },
748 { TRAF_ST_VCMX_802_6_FCS, "802.6 FCS" },
749 { TRAF_ST_VCMX_802_3, "802.3" },
750 { TRAF_ST_VCMX_802_4, "802.4" },
751 { TRAF_ST_VCMX_802_5, "802.5" },
752 { TRAF_ST_VCMX_FDDI, "FDDI" },
753 { TRAF_ST_VCMX_802_6, "802.6" },
754 { TRAF_ST_VCMX_FRAGMENTS, "Fragments" },
755 { TRAF_ST_VCMX_BPDU, "BPDU" },
759 /* Traffic subtypes for LANE traffic */
760 static const value_string lane_type_vals[] = {
761 { TRAF_ST_UNKNOWN, "Unknown LANE traffic type" },
762 { TRAF_ST_LANE_LE_CTRL, "LE Control" },
763 { TRAF_ST_LANE_802_3, "802.3" },
764 { TRAF_ST_LANE_802_5, "802.5" },
765 { TRAF_ST_LANE_802_3_MC, "802.3 multicast" },
766 { TRAF_ST_LANE_802_5_MC, "802.5 multicast" },
770 /* Traffic subtypes for Ipsilon traffic */
771 static const value_string ipsilon_type_vals[] = {
772 { TRAF_ST_UNKNOWN, "Unknown Ipsilon traffic type" },
773 { TRAF_ST_IPSILON_FT0, "Flow type 0" },
774 { TRAF_ST_IPSILON_FT1, "Flow type 1" },
775 { TRAF_ST_IPSILON_FT2, "Flow type 2" },
780 capture_atm(const guchar *pd, int offset,
781 int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
783 if (pseudo_header->atm.aal == AAL_5) {
784 return try_capture_dissector("atm.aal5.type", pseudo_header->atm.type, pd, offset, len, cpinfo, pseudo_header);
790 dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
791 proto_item *atm_ti, proto_tree *atm_tree, gboolean truncated,
792 struct atm_phdr *atm_info, gboolean pseudowire_mode)
794 guint length, reported_length;
803 * This is reassembled traffic, so the cell headers are missing;
804 * show the traffic type for AAL5 traffic, and the VPI and VCI,
805 * from the pseudo-header.
807 if (atm_info->aal == AAL_5) {
808 proto_tree_add_uint(atm_tree, hf_atm_traffic_type, tvb, 0, 0, atm_info->type);
810 switch (atm_info->type) {
813 proto_tree_add_uint(atm_tree, hf_atm_traffic_vcmx, tvb, 0, 0, atm_info->subtype);
817 proto_tree_add_uint(atm_tree, hf_atm_traffic_lane, tvb, 0, 0, atm_info->subtype);
821 proto_tree_add_uint(atm_tree, hf_atm_traffic_ipsilon, tvb, 0, 0, atm_info->subtype);
825 if (!pseudowire_mode) {
826 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0, atm_info->vpi);
827 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0, atm_info->vci);
829 /* Also show vpi/vci in info column */
830 col_append_fstr(pinfo->cinfo, COL_INFO, " VPI=%u, VCI=%u",
831 atm_info->vpi, atm_info->vci);
835 if (truncated || atm_info->flags & ATM_REASSEMBLY_ERROR) {
837 * The packet data does not include stuff such as the AAL5
838 * trailer, either because it was explicitly left out or because
841 if (atm_info->cells != 0) {
843 * If the cell count is 0, assume it means we don't know how
846 * XXX - also assume it means we don't know what was in the AAL5
847 * trailer. We may, however, find some capture program that can
848 * give us the AAL5 trailer information but not the cell count,
849 * in which case we need some other way of indicating whether we
850 * have the AAL5 trailer information.
853 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, atm_info->cells);
854 proto_tree_add_uint(atm_tree, hf_atm_aal5_uu, tvb, 0, 0, atm_info->aal5t_u2u >> 8);
855 proto_tree_add_uint(atm_tree, hf_atm_aal5_cpi, tvb, 0, 0, atm_info->aal5t_u2u & 0xFF);
856 proto_tree_add_uint(atm_tree, hf_atm_aal5_len, tvb, 0, 0, atm_info->aal5t_len);
857 proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, 0, 0, atm_info->aal5t_chksum);
862 * The packet data includes stuff such as the AAL5 trailer, if
863 * it wasn't cut off by the snapshot length, and ATM reassembly
865 * Decode the trailer, if present, and then chop it off.
867 length = tvb_captured_length(tvb);
868 reported_length = tvb_reported_length(tvb);
869 if ((reported_length % 48) == 0) {
871 * Reported length is a multiple of 48, so we can presumably
872 * divide it by 48 to get the number of cells.
874 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, reported_length/48);
876 if ((atm_info->aal == AAL_5 || atm_info->aal == AAL_SIGNALLING) &&
877 length >= reported_length) {
879 * XXX - what if the packet is truncated? Can that happen?
880 * What if you capture with Windows Sniffer on an ATM link
881 * and tell it not to save the entire packet? What happens
884 aal5_length = tvb_get_ntohs(tvb, length - 6);
887 * Check for sanity in the AAL5 length. It must be > 0
888 * and must be less than the amount of space left after
889 * we remove the trailer.
891 * If it's not sane, assume we don't have a trailer.
893 if (aal5_length > 0 && aal5_length <= length - 8) {
895 * How much padding is there?
897 pad_length = length - aal5_length - 8;
900 * There is no reason for more than 47 bytes of padding.
901 * The most padding you can have would be 7 bytes at the
902 * end of the next-to-last cell (8 bytes after the end of
903 * the data means you can fit the trailer in that cell),
904 * plus 40 bytes in the last cell (with the last 8 bytes
907 * If there's more than 47 bytes of padding, assume we don't
910 if (pad_length <= 47) {
914 if (pad_length > 0) {
915 proto_tree_add_item(atm_tree, hf_atm_padding, tvb, aal5_length, pad_length, ENC_NA);
918 proto_tree_add_item(atm_tree, hf_atm_aal5_uu, tvb, length - 8, 1, ENC_BIG_ENDIAN);
919 proto_tree_add_item(atm_tree, hf_atm_aal5_cpi, tvb, length - 7, 1, ENC_BIG_ENDIAN);
920 proto_tree_add_item(atm_tree, hf_atm_aal5_len, tvb, length - 6, 2, ENC_BIG_ENDIAN);
922 crc = tvb_get_ntohl(tvb, length - 4);
923 calc_crc = crc32_mpeg2_tvb(tvb, length);
924 ti = proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, length - 4, 4, crc);
925 proto_item_append_text(ti, (calc_crc == 0xC704DD7B) ? " (correct)" : " (incorrect)");
927 next_tvb = tvb_new_subset_length(tvb, 0, aal5_length);
933 * First check whether custom dissection table
934 * was set up to dissect this VPI+VCI combination
936 if (dissector_try_uint_new(atm_reassembled_vpi_vci_table,
937 ((atm_info->vpi) << 16) | atm_info->vci,
938 next_tvb, pinfo, tree, TRUE, atm_info))
945 * Don't try to dissect the payload of PDUs with a reassembly
948 switch (atm_info->aal) {
951 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
952 call_dissector(sscop_handle, next_tvb, pinfo, tree);
958 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
959 if (dissector_try_uint_new(atm_type_aal5_table, atm_info->type, next_tvb, pinfo, tree, TRUE, atm_info))
965 if (tvb_reported_length(next_tvb) > 7) /* sizeof(octet) */
968 tvb_memcpy(next_tvb, octet, 0, sizeof(octet));
972 && octet[2] == 0x03) /* LLC SNAP as per RFC2684 */
974 call_dissector(llc_handle, next_tvb, pinfo, tree);
977 else if ((pntoh16(octet) & 0xff) == PPP_IP)
979 call_dissector(ppp_handle, next_tvb, pinfo, tree);
982 else if (pntoh16(octet) == 0x00)
985 * Assume VC multiplexed bridged Ethernet.
986 * Whether there's an FCS is an option negotiated
987 * over the VC, so we call the "do heuristic checks
988 * to see if there's an FCS" version of the Ethernet
991 * See RFC 2684 section 6.2 "VC Multiplexing of Bridged
994 proto_tree_add_item(tree, hf_atm_padding, tvb, 0, 2, ENC_NA);
995 next_tvb = tvb_new_subset_remaining(tvb, 2);
996 call_dissector(eth_maybefcs_handle, next_tvb, pinfo, tree);
999 else if (octet[2] == 0x03 && /* NLPID */
1000 ((octet[3] == 0xcc || /* IPv4 */
1001 octet[3] == 0x8e) || /* IPv6 */
1002 (octet[3] == 0x00 && /* Eth */
1003 octet[4] == 0x80))) /* Eth */
1005 /* assume network interworking with FR 2 byte header */
1006 call_dissector(fr_handle, next_tvb, pinfo, tree);
1009 else if (octet[4] == 0x03 && /* NLPID */
1010 ((octet[5] == 0xcc || /* IPv4 */
1011 octet[5] == 0x8e) || /* IPv6 */
1012 (octet[5] == 0x00 && /* Eth */
1013 octet[6] == 0x80))) /* Eth */
1015 /* assume network interworking with FR 4 byte header */
1016 call_dissector(fr_handle, next_tvb, pinfo, tree);
1019 else if (((octet[0] & 0xf0)== 0x40) ||
1020 ((octet[0] & 0xf0) == 0x60))
1022 call_dissector(ip_handle, next_tvb, pinfo, tree);
1032 proto_tree_add_uint(atm_tree, hf_atm_cid, tvb, 0, 0,
1033 atm_info->aal2_cid);
1034 proto_item_append_text(atm_ti, " (vpi=%u vci=%u cid=%u)",
1037 atm_info->aal2_cid);
1039 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
1040 if (atm_info->flags & ATM_AAL2_NOPHDR) {
1043 /* Skip first 4 bytes of message
1047 Ignoring for now... */
1048 next_tvb = tvb_new_subset_remaining(tvb, 4);
1051 if (dissector_try_uint(atm_type_aal2_table, atm_info->type, next_tvb, pinfo, tree))
1059 /* Dump it as raw data. */
1064 /* Dump it as raw data. */
1065 call_data_dissector(next_tvb, pinfo, tree);
1070 * Charles Michael Heard's HEC code, from
1072 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1074 * with the syndrome and error position tables initialized with values
1075 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1076 * rather than by calling those routines at run time, and with various data
1077 * type cleanups and changes not to correct the header if a correctible
1078 * error was detected.
1080 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1082 static const guint8 syndrome_table[256] = {
1083 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1084 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1085 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1086 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1087 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1088 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1089 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1090 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1091 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1092 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1093 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1094 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1095 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1096 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1097 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1098 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1099 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1100 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1101 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1102 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1103 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1104 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1105 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1106 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1107 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1108 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1109 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1110 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1111 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1112 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1113 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1114 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1117 #define NO_ERROR_DETECTED -128
1118 #define UNCORRECTIBLE_ERROR 128
1120 static const int err_posn_table[256] = {
1121 NO_ERROR_DETECTED, 39,
1122 38, UNCORRECTIBLE_ERROR,
1123 37, UNCORRECTIBLE_ERROR,
1124 UNCORRECTIBLE_ERROR, 31,
1125 36, UNCORRECTIBLE_ERROR,
1126 UNCORRECTIBLE_ERROR, 8,
1127 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1128 30, UNCORRECTIBLE_ERROR,
1129 35, UNCORRECTIBLE_ERROR,
1130 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1131 UNCORRECTIBLE_ERROR, 23,
1132 7, UNCORRECTIBLE_ERROR,
1133 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1134 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1135 29, UNCORRECTIBLE_ERROR,
1136 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1137 34, UNCORRECTIBLE_ERROR,
1138 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1139 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1140 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1141 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1142 22, UNCORRECTIBLE_ERROR,
1143 6, UNCORRECTIBLE_ERROR,
1144 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1145 UNCORRECTIBLE_ERROR, 0,
1146 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1147 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1148 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1149 28, UNCORRECTIBLE_ERROR,
1150 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1151 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1152 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1153 33, UNCORRECTIBLE_ERROR,
1154 UNCORRECTIBLE_ERROR, 10,
1155 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1156 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1157 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1158 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1159 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1160 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1161 UNCORRECTIBLE_ERROR, 12,
1162 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1163 21, UNCORRECTIBLE_ERROR,
1164 UNCORRECTIBLE_ERROR, 19,
1165 5, UNCORRECTIBLE_ERROR,
1166 UNCORRECTIBLE_ERROR, 17,
1167 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1168 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1169 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1170 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1171 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1172 UNCORRECTIBLE_ERROR, 3,
1173 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1174 UNCORRECTIBLE_ERROR, 15,
1175 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1176 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1177 27, UNCORRECTIBLE_ERROR,
1178 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1179 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1180 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1181 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1182 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1183 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1184 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1185 32, UNCORRECTIBLE_ERROR,
1186 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1187 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1188 9, UNCORRECTIBLE_ERROR,
1189 UNCORRECTIBLE_ERROR, 24,
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, UNCORRECTIBLE_ERROR,
1196 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1197 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1198 UNCORRECTIBLE_ERROR, 1,
1199 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1200 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1201 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1202 11, UNCORRECTIBLE_ERROR,
1203 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1204 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1205 20, UNCORRECTIBLE_ERROR,
1206 UNCORRECTIBLE_ERROR, 13,
1207 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1208 18, UNCORRECTIBLE_ERROR,
1209 4, UNCORRECTIBLE_ERROR,
1210 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1211 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1212 16, 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, UNCORRECTIBLE_ERROR,
1218 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1219 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1220 UNCORRECTIBLE_ERROR, 25,
1221 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1222 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1223 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1224 2, UNCORRECTIBLE_ERROR,
1225 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1226 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1227 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1228 14, UNCORRECTIBLE_ERROR,
1229 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1230 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1231 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1232 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1233 26, 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,
1246 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1247 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1248 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1252 * Return an indication of whether there was an error in the cell header
1253 * and, if so, where the error was, if it was correctable.
1256 get_header_err(const guint8 *cell_header)
1258 register guint8 syndrome;
1259 register int i, err_posn;
1262 for (i = 0; i < 4; i++)
1263 syndrome = syndrome_table[syndrome ^ cell_header[i]];
1264 syndrome ^= cell_header[4] ^ COSET_LEADER;
1266 err_posn = err_posn_table [syndrome];
1269 return NO_ERROR_DETECTED;
1270 else if (err_posn < 40)
1273 return UNCORRECTIBLE_ERROR;
1276 const value_string atm_pt_vals[] = {
1277 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1278 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1279 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1280 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1281 { 4, "Segment OAM F5 flow related cell" },
1282 { 5, "End-to-end OAM F5 flow related cell" },
1283 { 6, "VC resource management cell" },
1287 static const value_string st_vals[] = {
1295 #define OAM_TYPE_FM 1 /* Fault Management */
1296 #define OAM_TYPE_PM 2 /* Performance Management */
1297 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1299 static const value_string oam_type_vals[] = {
1300 { OAM_TYPE_FM, "Fault Management" },
1301 { OAM_TYPE_PM, "Performance Management" },
1302 { OAM_TYPE_AD, "Activation/Deactivation" },
1306 static const value_string ft_fm_vals[] = {
1307 { 0, "Alarm Indication Signal" },
1308 { 1, "Far End Receive Failure" },
1309 { 8, "OAM Cell Loopback" },
1310 { 4, "Continuity Check" },
1314 static const value_string ft_pm_vals[] = {
1315 { 0, "Forward Monitoring" },
1316 { 1, "Backward Reporting" },
1317 { 2, "Monitoring and Reporting" },
1321 static const value_string ft_ad_vals[] = {
1322 { 0, "Performance Monitoring" },
1323 { 1, "Continuity Check" },
1329 dissect_atm_cell_payload(tvbuff_t *tvb, int offset, packet_info *pinfo,
1330 proto_tree *tree, guint aal, gboolean fill_columns,
1331 struct atm_phdr *atm_info)
1333 proto_tree *aal_tree;
1337 guint16 aal3_4_hdr, crc10;
1340 next_tvb = tvb_new_subset_remaining(tvb, offset);
1342 * First check whether custom dissection table
1343 * was set up to dissect this VPI+VCI combination
1345 if (dissector_try_uint_new(atm_cell_payload_vpi_vci_table,
1346 ((atm_info->vpi) << 16) | atm_info->vci,
1347 next_tvb, pinfo, tree, TRUE, atm_info))
1355 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL1");
1356 col_clear(pinfo->cinfo, COL_INFO);
1357 ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, ENC_NA);
1358 aal_tree = proto_item_add_subtree(ti, ett_aal1);
1359 octet = tvb_get_guint8(tvb, offset);
1361 proto_tree_add_item(aal_tree, hf_atm_aa1_csi, tvb, offset, 1, ENC_BIG_ENDIAN);
1362 proto_tree_add_item(aal_tree, hf_atm_aa1_seq_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1363 col_add_fstr(pinfo->cinfo, COL_INFO, "Sequence count = %u",
1364 (octet >> 4) & 0x7);
1365 proto_tree_add_item(aal_tree, hf_atm_aa1_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1366 proto_tree_add_item(aal_tree, hf_atm_aa1_parity, tvb, offset, 1, ENC_BIG_ENDIAN);
1369 proto_tree_add_item(aal_tree, hf_atm_aa1_payload, tvb, offset, 47, ENC_NA);
1374 * XXX - or should this be the CS PDU?
1376 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL3/4");
1377 col_clear(pinfo->cinfo, COL_INFO);
1378 ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, ENC_NA);
1379 aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
1380 aal3_4_hdr = tvb_get_ntohs(tvb, offset);
1381 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, sequence number = %u",
1382 val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"),
1383 (aal3_4_hdr >> 10) & 0xF);
1384 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1385 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seq_num, tvb, offset, 2, ENC_BIG_ENDIAN);
1386 proto_tree_add_item(aal_tree, hf_atm_aal3_4_multiplex_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1388 length = tvb_reported_length_remaining(tvb, offset);
1389 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1392 proto_tree_add_item(aal_tree, hf_atm_aal3_4_information, tvb, offset, 44, ENC_NA);
1395 proto_tree_add_item(aal_tree, hf_atm_aal3_4_length_indicator, tvb, offset, 2, ENC_BIG_ENDIAN);
1396 ti = proto_tree_add_item(aal_tree, hf_atm_aal3_4_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1397 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1403 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
1404 col_clear(pinfo->cinfo, COL_INFO);
1406 ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, ENC_NA);
1407 aal_tree = proto_item_add_subtree(ti, ett_oamaal);
1408 octet = tvb_get_guint8(tvb, offset);
1411 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
1412 val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
1415 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1416 switch (octet >> 4) {
1419 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_fm, tvb, offset, 1, ENC_BIG_ENDIAN);
1423 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_pm, tvb, offset, 1, ENC_BIG_ENDIAN);
1427 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ad, tvb, offset, 1, ENC_BIG_ENDIAN);
1431 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1434 length = tvb_reported_length_remaining(tvb, offset);
1435 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1438 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_func_spec, tvb, offset, 45, ENC_NA);
1441 ti = proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1442 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1446 next_tvb = tvb_new_subset_remaining(tvb, offset);
1447 call_data_dissector(next_tvb, pinfo, tree);
1453 * Check for OAM cells.
1454 * OAM F4 is VCI 3 or 4 and PT 0X0.
1458 atm_is_oam_cell(const guint16 vci, const guint8 pt)
1460 return (((vci == 3 || vci == 4) && ((pt & 0x5) == 0))
1461 || ((pt & 0x6) == 0x4));
1466 dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1467 proto_tree *atm_tree, guint aal, gboolean nni,
1468 gboolean crc_stripped, const struct atm_phdr *atm_info)
1475 struct atm_phdr atm_info_local;
1479 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1480 * and encoding at UNI reference point as:
1495 octet = tvb_get_guint8(tvb, 0);
1496 proto_tree_add_item(atm_tree, hf_atm_gfc, tvb, 0, 1, ENC_NA);
1497 vpi = (octet & 0xF) << 4;
1498 octet = tvb_get_guint8(tvb, 1);
1500 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1503 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1504 * and encoding at NNI reference point as:
1519 octet = tvb_get_guint8(tvb, 0);
1521 octet = tvb_get_guint8(tvb, 1);
1522 vpi |= (octet & 0xF0) >> 4;
1523 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1526 vci = (octet & 0x0F) << 12;
1527 octet = tvb_get_guint8(tvb, 2);
1529 octet = tvb_get_guint8(tvb, 3);
1531 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 1, 3, vci);
1532 pt = (octet >> 1) & 0x7;
1533 proto_tree_add_item(atm_tree, hf_atm_payload_type, tvb, 3, 1, ENC_BIG_ENDIAN);
1534 proto_tree_add_item(atm_tree, hf_atm_cell_loss_priority, tvb, 3, 1, ENC_BIG_ENDIAN);
1536 if (!crc_stripped) {
1538 * FF: parse the Header Error Check (HEC).
1540 ti = proto_tree_add_item(atm_tree, hf_atm_header_error_check, tvb, 4, 1, ENC_BIG_ENDIAN);
1541 err = get_header_err((const guint8*)tvb_memdup(wmem_packet_scope(), tvb, 0, 5));
1542 if (err == NO_ERROR_DETECTED)
1543 proto_item_append_text(ti, " (correct)");
1544 else if (err == UNCORRECTIBLE_ERROR)
1545 proto_item_append_text(ti, " (uncorrectable error)");
1547 proto_item_append_text(ti, " (error in bit %d)", err);
1551 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1552 * Cell Mode) the Header Error Check (HEC) field is stripped.
1553 * So we do nothing here.
1559 * Check for OAM cells.
1560 * XXX - do this for all AAL values, overriding whatever information
1561 * Wiretap got from the file?
1563 if (aal == AAL_USER || aal == AAL_UNKNOWN) {
1564 if (atm_is_oam_cell(vci,pt)) {
1569 memset(&atm_info_local, 0, sizeof(atm_info_local));
1571 atm_info_local.flags = atm_info->flags;
1572 atm_info_local.aal = atm_info->aal;
1573 atm_info_local.type = atm_info->type;
1574 atm_info_local.subtype = atm_info->subtype;
1575 atm_info_local.vpi = atm_info->vpi;
1576 atm_info_local.vci = atm_info->vci;
1577 atm_info_local.aal2_cid = atm_info->aal2_cid;
1578 atm_info_local.channel = atm_info->channel;
1579 atm_info_local.cells = atm_info->cells;
1580 atm_info_local.aal5t_u2u = atm_info->aal5t_u2u;
1581 atm_info_local.aal5t_len = atm_info->aal5t_len;
1582 atm_info_local.aal5t_chksum = atm_info->aal5t_chksum;
1584 atm_info_local.aal = aal;
1585 atm_info_local.type = pt;
1586 atm_info_local.vpi = vpi;
1587 atm_info_local.vci = vci;
1590 dissect_atm_cell_payload(tvb, offset, pinfo, tree, aal, TRUE, &atm_info_local);
1594 dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1595 gboolean truncated, struct atm_phdr *atm_info, gboolean pseudowire_mode)
1597 proto_tree *atm_tree = NULL;
1598 proto_item *atm_ti = NULL;
1600 if ( atm_info->aal == AAL_5 && atm_info->type == TRAF_LANE &&
1601 dissect_lanesscop ) {
1602 atm_info->aal = AAL_SIGNALLING;
1605 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1607 if (!pseudowire_mode) {
1608 switch (atm_info->channel) {
1611 /* Traffic from DTE to DCE. */
1612 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
1613 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
1617 /* Traffic from DCE to DTE. */
1618 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
1619 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
1624 if (atm_info->aal == AAL_5) {
1625 col_add_fstr(pinfo->cinfo, COL_INFO, "AAL5 %s",
1626 val_to_str(atm_info->type, aal5_hltype_vals,
1627 "Unknown traffic type (%u)"));
1629 col_add_str(pinfo->cinfo, COL_INFO,
1630 val_to_str(atm_info->aal, aal_vals,
1631 "Unknown AAL (%u)"));
1635 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, -1, ENC_NA);
1636 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1638 if (!pseudowire_mode) {
1639 proto_tree_add_uint(atm_tree, hf_atm_channel, tvb, 0, 0, atm_info->channel);
1640 if (atm_info->flags & ATM_REASSEMBLY_ERROR)
1641 expert_add_info(pinfo, atm_ti, &ei_atm_reassembly_failed);
1644 proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0,
1647 val_to_str(atm_info->aal, aal_vals,
1648 "Unknown AAL (%u)"));
1650 if (atm_info->flags & ATM_RAW_CELL) {
1651 /* This is a single cell, with the cell header at the beginning. */
1652 if (atm_info->flags & ATM_NO_HEC) {
1653 proto_item_set_len(atm_ti, 4);
1655 proto_item_set_len(atm_ti, 5);
1657 dissect_atm_cell(tvb, pinfo, tree, atm_tree,
1658 atm_info->aal, FALSE,
1659 atm_info->flags & ATM_NO_HEC, atm_info);
1661 /* This is a reassembled PDU. */
1664 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
1665 * In such cases, the dissector data parameter is used to pass info from/to
1666 * PW dissector to ATM dissector. For decoding normal ATM traffic
1667 * data parameter should be NULL.
1669 dissect_reassembled_pdu(tvb, pinfo, tree, atm_tree, atm_ti, truncated,
1670 atm_info, pseudowire_mode);
1673 return tvb_reported_length(tvb);
1677 dissect_atm_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1679 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1681 DISSECTOR_ASSERT(atm_info != NULL);
1683 return dissect_atm_common(tvb, pinfo, tree, TRUE, atm_info, FALSE);
1687 dissect_atm_pw_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1689 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1691 DISSECTOR_ASSERT(atm_info != NULL);
1693 return dissect_atm_common(tvb, pinfo, tree, TRUE, atm_info, TRUE);
1697 dissect_atm_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1699 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1701 DISSECTOR_ASSERT(atm_info != NULL);
1703 return dissect_atm_common(tvb, pinfo, tree, FALSE, atm_info, FALSE);
1707 dissect_atm_pw_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1709 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1711 DISSECTOR_ASSERT(atm_info != NULL);
1713 return dissect_atm_common(tvb, pinfo, tree, FALSE, atm_info, TRUE);
1717 dissect_atm_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1719 proto_tree *atm_tree;
1722 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1724 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, 0, ENC_NA);
1725 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1727 dissect_atm_cell(tvb, pinfo, tree, atm_tree, AAL_OAMCELL, FALSE, FALSE, NULL);
1728 return tvb_reported_length(tvb);
1732 dissect_atm_pw_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1734 struct pw_atm_phdr *pw_atm_info = (struct pw_atm_phdr *)data;
1736 DISSECTOR_ASSERT(pw_atm_info != NULL);
1738 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1740 dissect_atm_cell_payload(tvb, 0, pinfo, tree, AAL_OAMCELL,
1741 pw_atm_info->enable_fill_columns_by_atm_dissector,
1742 &pw_atm_info->info);
1744 return tvb_reported_length(tvb);
1747 static void atm_prompt(packet_info *pinfo _U_, gchar* result)
1749 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode AAL2 traffic as");
1752 static gpointer atm_value(packet_info *pinfo)
1754 return GUINT_TO_POINTER((guint)pinfo->pseudo_header->atm.type);
1758 proto_register_atm(void)
1760 static hf_register_info hf[] = {
1762 { "AAL", "atm.aal", FT_UINT8, BASE_DEC, VALS(aal_vals), 0x0,
1765 { "GFC", "atm.GFC", FT_UINT8, BASE_DEC, NULL, 0xF0,
1768 { "VPI", "atm.vpi", FT_UINT8, BASE_DEC, NULL, 0x0,
1772 { "VCI", "atm.vci", FT_UINT16, BASE_DEC, NULL, 0x0,
1776 { "CID", "atm.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
1780 { "Reserved", "atm.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
1783 { &hf_atm_le_client_client,
1784 { "LE Client", "atm.le_client.client", FT_UINT16, BASE_HEX, NULL, 0x0,
1786 { &hf_atm_lan_destination_tag,
1787 { "Tag", "atm.lan_destination.tag", FT_UINT16, BASE_HEX, VALS(le_control_landest_tag_vals), 0x0,
1789 { &hf_atm_lan_destination_mac,
1790 { "MAC address", "atm.lan_destination.mac", FT_ETHER, BASE_NONE, NULL, 0x0,
1792 { &hf_atm_le_control_tlv_type,
1793 { "TLV Type", "atm.le_control.tlv_type", FT_UINT32, BASE_HEX, VALS(le_tlv_type_vals), 0x0,
1795 { &hf_atm_le_control_tlv_length,
1796 { "TLV Length", "atm.le_control.tlv_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1798 { &hf_atm_lan_destination_route_desc,
1799 { "Route descriptor", "atm.lan_destination.route_desc", FT_UINT16, BASE_HEX, NULL, 0x0,
1801 { &hf_atm_lan_destination_lan_id,
1802 { "LAN ID", "atm.lan_destination.lan_id", FT_UINT16, BASE_DEC, NULL, 0xFFF0,
1804 { &hf_atm_lan_destination_bridge_num,
1805 { "Bridge number", "atm.lan_destination.bridge_num", FT_UINT16, BASE_DEC, NULL, 0x000F,
1807 { &hf_atm_source_atm,
1808 { "Source ATM address", "atm.source_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1810 { &hf_atm_target_atm,
1811 { "Target ATM address", "atm.target_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1813 { &hf_atm_le_configure_join_frame_lan_type,
1814 { "LAN type", "atm.le_configure_join_frame.lan_type", FT_UINT8, BASE_HEX, VALS(le_control_lan_type_vals), 0x0,
1816 { &hf_atm_le_configure_join_frame_max_frame_size,
1817 { "Maximum frame size", "atm.le_configure_join_frame.max_frame_size", FT_UINT8, BASE_HEX, VALS(le_control_frame_size_vals), 0x0,
1819 { &hf_atm_le_configure_join_frame_num_tlvs,
1820 { "Number of TLVs", "atm.le_configure_join_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1822 { &hf_atm_le_configure_join_frame_elan_name_size,
1823 { "ELAN name size", "atm.le_configure_join_frame.elan_name_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1825 { &hf_atm_le_registration_frame_num_tlvs,
1826 { "Number of TLVs", "atm.le_registration_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1828 { &hf_atm_le_arp_frame_num_tlvs,
1829 { "Number of TLVs", "atm.le_arp_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1831 { &hf_atm_le_verify_frame_num_tlvs,
1832 { "Number of TLVs", "atm.le_verify_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1834 { &hf_atm_le_configure_join_frame_elan_name,
1835 { "ELAN name", "atm.le_configure_join_frame.elan_name", FT_BYTES, BASE_NONE, NULL, 0x0,
1837 { &hf_atm_le_control_marker,
1838 { "Marker", "atm.le_control.marker", FT_UINT16, BASE_HEX, NULL, 0x0,
1840 { &hf_atm_le_control_protocol,
1841 { "Protocol", "atm.le_control.protocol", FT_UINT8, BASE_HEX, NULL, 0x0,
1843 { &hf_atm_le_control_version,
1844 { "Version", "atm.le_control.version", FT_UINT8, BASE_HEX, NULL, 0x0,
1846 { &hf_atm_le_control_opcode,
1847 { "Opcode", "atm.le_control.opcode", FT_UINT16, BASE_HEX, VALS(le_control_opcode_vals), 0x0,
1849 { &hf_atm_le_control_status,
1850 { "Status", "atm.le_control.status", FT_UINT16, BASE_HEX, VALS(le_control_status_vals), 0x0,
1852 { &hf_atm_le_control_transaction_id,
1853 { "Transaction ID", "atm.le_control.transaction_id", FT_UINT32, BASE_HEX, NULL, 0x0,
1855 { &hf_atm_le_control_requester_lecid,
1856 { "Requester LECID", "atm.le_control.requester_lecid", FT_UINT16, BASE_HEX, NULL, 0x0,
1858 { &hf_atm_le_control_flags,
1859 { "Flags", "atm.le_control.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
1861 { &hf_atm_le_control_flag_v2_capable,
1862 { "V2 capable", "atm.le_control.flag.v2_capable", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002,
1864 { &hf_atm_le_control_flag_selective_multicast,
1865 { "Selective multicast", "atm.le_control.flag.selective_multicast", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004,
1867 { &hf_atm_le_control_flag_v2_required,
1868 { "V2 required", "atm.le_control.flag.v2_required", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008,
1870 { &hf_atm_le_control_flag_proxy,
1871 { "Proxy", "atm.le_control.flag.flag_proxy", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0080,
1873 { &hf_atm_le_control_flag_exclude_explorer_frames,
1874 { "Exclude explorer frames", "atm.le_control.flag.exclude_explorer_frames", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0200,
1876 { &hf_atm_le_control_flag_address,
1877 { "Address", "atm.le_control.flag.address", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001,
1879 { &hf_atm_le_control_topology_change,
1880 { "Topology change", "atm.le_control.flag.topology_change", FT_BOOLEAN, 16, TFS(&tfs_remote_local), 0x0100,
1882 { &hf_atm_traffic_type,
1883 { "Traffic type", "atm.traffic_type", FT_UINT8, BASE_DEC, VALS(aal5_hltype_vals), 0x0,
1885 { &hf_atm_traffic_vcmx,
1886 { "VC multiplexed traffic type", "atm.traffic.vcmx", FT_UINT8, BASE_DEC, VALS(vcmx_type_vals), 0x0,
1888 { &hf_atm_traffic_lane,
1889 { "LANE traffic type", "atm.traffic.lane", FT_UINT8, BASE_DEC, VALS(lane_type_vals), 0x0,
1891 { &hf_atm_traffic_ipsilon,
1892 { "Ipsilon traffic type", "atm.traffic.ipsilon", FT_UINT8, BASE_DEC, VALS(ipsilon_type_vals), 0x0,
1895 { "Cells", "atm.cells", FT_UINT16, BASE_DEC, NULL, 0x0,
1898 { "AAL5 UU", "atm.hf_atm.aal5t_uu", FT_UINT8, BASE_HEX, NULL, 0x0,
1901 { "AAL5 CPI", "atm.hf_atm.aal5t_cpi", FT_UINT8, BASE_HEX, NULL, 0x0,
1904 { "AAL5 len", "atm.aal5t_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1907 { "AAL5 CRC", "atm.aal5t_crc", FT_UINT32, BASE_HEX, NULL, 0x0,
1909 { &hf_atm_payload_type,
1910 { "Payload Type", "atm.payload_type", FT_UINT8, BASE_DEC, NULL, 0x0E,
1912 { &hf_atm_cell_loss_priority,
1913 { "Cell Loss Priority", "atm.cell_loss_priority", FT_BOOLEAN, 8, TFS(&tfs_low_high_priority), 0x01,
1915 { &hf_atm_header_error_check,
1916 { "Header Error Check", "atm.header_error_check", FT_UINT8, BASE_HEX, NULL, 0,
1919 { "Channel", "atm.channel", FT_UINT16, BASE_DEC, VALS(atm_channel_vals), 0,
1922 { "CSI", "atm.aa1.csi", FT_UINT8, BASE_DEC, NULL, 0x80,
1924 { &hf_atm_aa1_seq_count,
1925 { "Sequence Count", "atm.aa1.seq_count", FT_UINT8, BASE_DEC, NULL, 0x70,
1928 { "CRC", "atm.aa1.crc", FT_UINT8, BASE_DEC, NULL, 0x08,
1930 { &hf_atm_aa1_parity,
1931 { "Parity", "atm.aa1.parity", FT_UINT8, BASE_DEC, NULL, 0x07,
1933 { &hf_atm_aa1_payload,
1934 { "Payload", "atm.aa1.payload", FT_BYTES, BASE_NONE, NULL, 0x0,
1936 { &hf_atm_aal3_4_seg_type,
1937 { "Segment Type", "atm.aal3_4.seg_type", FT_UINT16, BASE_DEC, VALS(st_vals), 0xC000,
1939 { &hf_atm_aal3_4_seq_num,
1940 { "Sequence Number", "atm.aal3_4.seq_num", FT_UINT16, BASE_DEC, NULL, 0x3C00,
1942 { &hf_atm_aal3_4_multiplex_id,
1943 { "Multiplex ID", "atm.aal3_4.multiplex_id", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1945 { &hf_atm_aal3_4_information,
1946 { "Information", "atm.aal3_4.information", FT_BYTES, BASE_NONE, NULL, 0x0,
1948 { &hf_atm_aal3_4_length_indicator,
1949 { "Length Indicator", "atm.aal3_4.length_indicator", FT_UINT16, BASE_DEC, VALS(st_vals), 0xFC00,
1951 { &hf_atm_aal3_4_crc,
1952 { "CRC", "atm.aal3_4.crc", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1954 { &hf_atm_aal_oamcell_type,
1955 { "OAM Type", "atm.aal_oamcell.type", FT_UINT8, BASE_DEC, VALS(oam_type_vals), 0xF0,
1957 { &hf_atm_aal_oamcell_type_fm,
1958 { "Function Type", "atm.aal_oamcell.type.fm", FT_UINT8, BASE_DEC, VALS(ft_fm_vals), 0x0F,
1960 { &hf_atm_aal_oamcell_type_pm,
1961 { "Function Type", "atm.aal_oamcell.type.pm", FT_UINT8, BASE_DEC, VALS(ft_pm_vals), 0x0F,
1963 { &hf_atm_aal_oamcell_type_ad,
1964 { "Function Type", "atm.aal_oamcell.type.ad", FT_UINT8, BASE_DEC, VALS(ft_ad_vals), 0x0F,
1966 { &hf_atm_aal_oamcell_type_ft,
1967 { "Function Type", "atm.aal_oamcell.type.ft", FT_UINT8, BASE_DEC, NULL, 0x0F,
1969 { &hf_atm_aal_oamcell_func_spec,
1970 { "Function-specific information", "atm.aal_oamcell.func_spec", FT_BYTES, BASE_NONE, NULL, 0x0,
1972 { &hf_atm_aal_oamcell_crc,
1973 { "CRC-10", "atm.aal_oamcell.crc", FT_UINT16, BASE_HEX, NULL, 0x3FF,
1976 { "Padding", "atm.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
1981 static gint *ett[] = {
1988 &ett_atm_lane_lc_lan_dest,
1989 &ett_atm_lane_lc_lan_dest_rd,
1990 &ett_atm_lane_lc_flags,
1991 &ett_atm_lane_lc_tlv,
1994 static ei_register_info ei[] = {
1995 { &ei_atm_reassembly_failed, { "atm.reassembly_failed", PI_REASSEMBLE, PI_ERROR, "PDU reassembly failed", EXPFILL }},
1998 expert_module_t* expert_atm;
1999 module_t *atm_module;
2001 /* Decode As handling */
2002 static build_valid_func atm_da_build_value[1] = {atm_value};
2003 static decode_as_value_t atm_da_values = {atm_prompt, 1, atm_da_build_value};
2004 static decode_as_t atm_da = {"atm", "atm.aal2.type", 1, 0, &atm_da_values, NULL, NULL,
2005 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
2007 proto_atm = proto_register_protocol("Asynchronous Transfer Mode", "ATM", "atm");
2008 proto_aal1 = proto_register_protocol("ATM AAL1", "AAL1", "aal1");
2009 proto_aal3_4 = proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
2010 proto_oamaal = proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
2011 proto_register_field_array(proto_atm, hf, array_length(hf));
2012 proto_register_subtree_array(ett, array_length(ett));
2013 expert_atm = expert_register_protocol(proto_atm);
2014 expert_register_field_array(expert_atm, ei, array_length(ei));
2016 proto_ilmi = proto_register_protocol("ILMI", "ILMI", "ilmi");
2018 proto_atm_lane = proto_register_protocol("ATM LAN Emulation", "ATM LANE", "lane");
2020 atm_type_aal2_table = register_dissector_table("atm.aal2.type", "ATM AAL_2 type", proto_atm, FT_UINT32, BASE_DEC);
2021 atm_type_aal5_table = register_dissector_table("atm.aal5.type", "ATM AAL_5 type", proto_atm, FT_UINT32, BASE_DEC);
2022 atm_cell_payload_vpi_vci_table = register_dissector_table("atm.cell_payload.vpi_vci", "ATM Cell Payload VPI VCI",
2023 proto_atm, FT_UINT32, BASE_DEC);
2024 atm_reassembled_vpi_vci_table = register_dissector_table("atm.reassembled.vpi_vci", "ATM Reassembled VPI VCI",
2025 proto_atm, FT_UINT32, BASE_DEC);
2027 register_capture_dissector_table("atm.aal5.type", "ATM AAL_5");
2028 register_capture_dissector_table("atm_lane", "ATM LAN Emulation");
2030 atm_handle = register_dissector("atm_truncated", dissect_atm_truncated, proto_atm);
2031 register_dissector("atm_pw_truncated", dissect_atm_pw_truncated, proto_atm);
2032 atm_untruncated_handle = register_dissector("atm_untruncated", dissect_atm_untruncated, proto_atm);
2033 register_dissector("atm_pw_untruncated", dissect_atm_pw_untruncated, proto_atm);
2034 register_dissector("atm_oam_cell", dissect_atm_oam_cell, proto_oamaal);
2035 register_dissector("atm_pw_oam_cell", dissect_atm_pw_oam_cell, proto_oamaal);
2037 atm_module = prefs_register_protocol ( proto_atm, NULL );
2038 prefs_register_bool_preference(atm_module, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
2039 "Autodection between LANE and SSCOP is hard. As default LANE is preferred",
2040 &dissect_lanesscop);
2041 prefs_register_obsolete_preference(atm_module, "unknown_aal2_type");
2043 register_decode_as(&atm_da);
2047 proto_reg_handoff_atm(void)
2049 capture_dissector_handle_t atm_cap_handle;
2052 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
2053 * SSCOP, LANE, and ILMI dissectors.
2055 eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_atm_lane);
2056 tr_handle = find_dissector_add_dependency("tr", proto_atm_lane);
2057 fr_handle = find_dissector_add_dependency("fr", proto_atm);
2058 llc_handle = find_dissector_add_dependency("llc", proto_atm);
2059 sscop_handle = find_dissector_add_dependency("sscop", proto_atm);
2060 ppp_handle = find_dissector_add_dependency("ppp", proto_atm);
2061 eth_maybefcs_handle = find_dissector_add_dependency("eth_maybefcs", proto_atm);
2062 ip_handle = find_dissector_add_dependency("ip", proto_atm);
2064 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_handle);
2065 dissector_add_uint("atm.aal5.type", TRAF_LANE, create_dissector_handle(dissect_lane, proto_atm_lane));
2066 dissector_add_uint("atm.aal5.type", TRAF_ILMI, create_dissector_handle(dissect_ilmi, proto_ilmi));
2068 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,
2069 atm_untruncated_handle);
2071 atm_cap_handle = create_capture_dissector_handle(capture_atm, proto_atm);
2072 capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_cap_handle);
2073 atm_cap_handle = create_capture_dissector_handle(capture_lane, proto_atm_lane);
2074 capture_dissector_add_uint("atm.aal5.type", TRAF_LANE, atm_cap_handle);
2078 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2083 * indent-tabs-mode: nil
2086 * ex: set shiftwidth=2 tabstop=8 expandtab:
2087 * :indentSize=2:tabSize=8:noTabs=true: