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;
147 * http://www.atmforum.org/atmforum/specs/approved.html
149 * for a number of ATM Forum specifications, e.g. the LAN Emulation
150 * over ATM 1.0 spec, whence I got most of this.
153 /* LE Control opcodes */
154 #define LE_CONFIGURE_REQUEST 0x0001
155 #define LE_CONFIGURE_RESPONSE 0x0101
156 #define LE_JOIN_REQUEST 0x0002
157 #define LE_JOIN_RESPONSE 0x0102
158 #define READY_QUERY 0x0003
159 #define READY_IND 0x0103
160 #define LE_REGISTER_REQUEST 0x0004
161 #define LE_REGISTER_RESPONSE 0x0104
162 #define LE_UNREGISTER_REQUEST 0x0005
163 #define LE_UNREGISTER_RESPONSE 0x0105
164 #define LE_ARP_REQUEST 0x0006
165 #define LE_ARP_RESPONSE 0x0106
166 #define LE_FLUSH_REQUEST 0x0007
167 #define LE_FLUSH_RESPONSE 0x0107
168 #define LE_NARP_REQUEST 0x0008
169 #define LE_TOPOLOGY_REQUEST 0x0009
170 #define LE_VERIFY_REQUEST 0x000A
171 #define LE_VERIFY_RESPONSE 0x010A
173 static const value_string le_control_opcode_vals[] = {
174 { LE_CONFIGURE_REQUEST, "LE_CONFIGURE_REQUEST" },
175 { LE_CONFIGURE_RESPONSE, "LE_CONFIGURE_RESPONSE" },
176 { LE_JOIN_REQUEST, "LE_JOIN_REQUEST" },
177 { LE_JOIN_RESPONSE, "LE_JOIN_RESPONSE" },
178 { READY_QUERY, "READY_QUERY" },
179 { READY_IND, "READY_IND" },
180 { LE_REGISTER_REQUEST, "LE_REGISTER_REQUEST" },
181 { LE_REGISTER_RESPONSE, "LE_REGISTER_RESPONSE" },
182 { LE_UNREGISTER_REQUEST, "LE_UNREGISTER_REQUEST" },
183 { LE_UNREGISTER_RESPONSE, "LE_UNREGISTER_RESPONSE" },
184 { LE_ARP_REQUEST, "LE_ARP_REQUEST" },
185 { LE_ARP_RESPONSE, "LE_ARP_RESPONSE" },
186 { LE_FLUSH_REQUEST, "LE_FLUSH_REQUEST" },
187 { LE_FLUSH_RESPONSE, "LE_FLUSH_RESPONSE" },
188 { LE_NARP_REQUEST, "LE_NARP_REQUEST" },
189 { LE_TOPOLOGY_REQUEST, "LE_TOPOLOGY_REQUEST" },
190 { LE_VERIFY_REQUEST, "LE_VERIFY_REQUEST" },
191 { LE_VERIFY_RESPONSE, "LE_VERIFY_RESPONSE" },
195 /* LE Control statuses */
196 static const value_string le_control_status_vals[] = {
198 { 1, "Version not supported" },
199 { 2, "Invalid request parameters" },
200 { 4, "Duplicate LAN destination registration" },
201 { 5, "Duplicate ATM address" },
202 { 6, "Insufficient resources to grant request" },
203 { 7, "Access denied" },
204 { 8, "Invalid REQUESTOR-ID" },
205 { 9, "Invalid LAN destination" },
206 { 10, "Invalid ATM address" },
207 { 20, "No configuration" },
208 { 21, "LE_CONFIGURE error" },
209 { 22, "Insufficient information" },
210 { 24, "TLV not found" },
214 /* LE Control LAN destination tags */
215 #define TAG_NOT_PRESENT 0x0000
216 #define TAG_MAC_ADDRESS 0x0001
217 #define TAG_ROUTE_DESCRIPTOR 0x0002
219 static const value_string le_control_landest_tag_vals[] = {
220 { TAG_NOT_PRESENT, "Not present" },
221 { TAG_MAC_ADDRESS, "MAC address" },
222 { TAG_ROUTE_DESCRIPTOR, "Route descriptor" },
226 /* LE Control LAN types */
227 #define LANT_UNSPEC 0x00
228 #define LANT_802_3 0x01
229 #define LANT_802_5 0x02
231 static const value_string le_control_lan_type_vals[] = {
232 { LANT_UNSPEC, "Unspecified" },
233 { LANT_802_3, "Ethernet/802.3" },
234 { LANT_802_5, "802.5" },
238 static const value_string le_control_frame_size_vals[] = {
239 { 0x00, "Unspecified" },
240 { 0x01, "1516/1528/1580/1592" },
241 { 0x02, "4544/4556/1580/1592" },
242 { 0x03, "9234/9246" },
243 { 0x04, "18190/18202" },
247 static const value_string atm_channel_vals[] = {
253 static const true_false_string tfs_remote_local = { "Remote", "Local" };
254 static const true_false_string tfs_low_high_priority = { "Low priority", "High priority" };
258 dissect_le_client(tvbuff_t *tvb, proto_tree *tree)
261 proto_tree *lane_tree;
264 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, 0, 2, "ATM LANE");
265 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
267 proto_tree_add_item(lane_tree, hf_atm_le_client_client, tvb, 0, 2, ENC_BIG_ENDIAN );
272 dissect_lan_destination(tvbuff_t *tvb, int offset, const char *type, proto_tree *tree)
275 proto_tree *dest_tree;
279 dest_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
280 ett_atm_lane_lc_lan_dest, NULL, "%s LAN destination", type);
281 tag = tvb_get_ntohs(tvb, offset);
282 proto_tree_add_item(dest_tree, hf_atm_lan_destination_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
287 case TAG_MAC_ADDRESS:
288 proto_tree_add_item(dest_tree, hf_atm_lan_destination_mac, tvb, offset, 6, ENC_NA);
291 case TAG_ROUTE_DESCRIPTOR:
293 td = proto_tree_add_item(dest_tree, hf_atm_lan_destination_route_desc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
294 rd_tree = proto_item_add_subtree(td, ett_atm_lane_lc_lan_dest_rd);
295 proto_tree_add_item(rd_tree, hf_atm_lan_destination_lan_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
296 proto_tree_add_item(rd_tree, hf_atm_lan_destination_bridge_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
302 * TLV values in LE Control frames.
304 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
306 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
307 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
308 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
309 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
310 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
311 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
312 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
313 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
314 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
315 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
316 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
317 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
318 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
319 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
320 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
321 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
322 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
323 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
324 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
325 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
326 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
327 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
329 static const value_string le_tlv_type_vals[] = {
330 { LE_CONTROL_TIMEOUT, "Control Time-out" },
331 { LE_MAX_UNK_FRAME_COUNT, "Maximum Unknown Frame Count" },
332 { LE_MAX_UNK_FRAME_TIME, "Maximum Unknown Frame Time" },
333 { LE_VCC_TIMEOUT_PERIOD, "VCC Time-out" },
334 { LE_MAX_RETRY_COUNT, "Maximum Retry Count" },
335 { LE_AGING_TIME, "Aging Time" },
336 { LE_FORWARD_DELAY_TIME, "Forwarding Delay Time" },
337 { LE_EXPECTED_ARP_RESPONSE_TIME, "Expected LE_ARP Response Time" },
338 { LE_FLUSH_TIMEOUT, "Flush Time-out" },
339 { LE_PATH_SWITCHING_DELAY, "Path Switching Delay" },
340 { LE_LOCAL_SEGMENT_ID, "Local Segment ID" },
341 { LE_MCAST_SEND_VCC_TYPE, "Mcast Send VCC Type" },
342 { LE_MCAST_SEND_VCC_AVGRATE, "Mcast Send VCC AvgRate" },
343 { LE_MCAST_SEND_VCC_PEAKRATE, "Mcast Send VCC PeakRate" },
344 { LE_CONN_COMPLETION_TIMER, "Connection Completion Timer" },
345 { LE_CONFIG_FRAG_INFO, "Config Frag Info" },
346 { LE_LAYER_3_ADDRESS, "Layer 3 Address" },
347 { LE_ELAN_ID, "ELAN ID" },
348 { LE_SERVICE_CATEGORY, "Service Category" },
349 { LE_LLC_MUXED_ATM_ADDRESS, "LLC-muxed ATM Address" },
350 { LE_X5_ADJUSTMENT, "X5 Adjustment" },
351 { LE_PREFERRED_LES, "Preferred LES" },
356 dissect_le_control_tlvs(tvbuff_t *tvb, int offset, guint num_tlvs,
361 proto_tree *tlv_tree;
363 while (num_tlvs != 0) {
364 tlv_type = tvb_get_ntohl(tvb, offset);
365 tlv_length = tvb_get_guint8(tvb, offset+4);
366 tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, 5+tlv_length, ett_atm_lane_lc_tlv, NULL,
367 "TLV type: %s", val_to_str(tlv_type, le_tlv_type_vals, "Unknown (0x%08x)"));
368 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_type, tvb, offset, 4, ENC_BIG_ENDIAN);
369 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_length, tvb, offset+4, 1, ENC_BIG_ENDIAN);
370 offset += 5+tlv_length;
376 dissect_le_configure_join_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
381 dissect_lan_destination(tvb, offset, "Source", tree);
384 dissect_lan_destination(tvb, offset, "Target", tree);
387 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
390 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_lan_type, tvb, offset, 1, ENC_NA);
393 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_max_frame_size, tvb, offset, 1, ENC_NA);
396 num_tlvs = tvb_get_guint8(tvb, offset);
397 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_num_tlvs, tvb, offset, 1, ENC_NA);
400 name_size = tvb_get_guint8(tvb, offset);
401 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name_size, tvb, offset, 1, ENC_NA);
404 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
409 if (name_size != 0) {
410 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name, tvb, offset, name_size, ENC_NA);
414 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
418 dissect_le_registration_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
422 dissect_lan_destination(tvb, offset, "Source", tree);
425 dissect_lan_destination(tvb, offset, "Target", tree);
428 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
431 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
434 num_tlvs = tvb_get_guint8(tvb, offset);
435 proto_tree_add_item(tree, hf_atm_le_registration_frame_num_tlvs, tvb, offset, 1, ENC_NA);
438 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 53, ENC_NA);
441 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
445 dissect_le_arp_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
449 dissect_lan_destination(tvb, offset, "Source", tree);
452 dissect_lan_destination(tvb, offset, "Target", tree);
455 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
458 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
461 num_tlvs = tvb_get_guint8(tvb, offset);
462 proto_tree_add_item(tree, hf_atm_le_arp_frame_num_tlvs, tvb, offset, 1, ENC_NA);
465 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
468 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
471 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
474 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
478 dissect_le_verify_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
482 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 38, ENC_NA);
485 num_tlvs = tvb_get_guint8(tvb, offset);
486 proto_tree_add_item(tree, hf_atm_le_verify_frame_num_tlvs, tvb, offset, 1, ENC_NA);
489 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
492 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
495 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
498 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
502 dissect_le_flush_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
504 dissect_lan_destination(tvb, offset, "Source", tree);
507 dissect_lan_destination(tvb, offset, "Target", tree);
510 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
513 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 4, ENC_NA);
516 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
519 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
526 dissect_le_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
529 proto_tree *lane_tree = NULL;
532 proto_tree *flags_tree;
535 col_set_str(pinfo->cinfo, COL_INFO, "LE Control");
538 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, offset, 108, "ATM LANE");
539 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
541 proto_tree_add_item(lane_tree, hf_atm_le_control_marker, tvb, offset, 2, ENC_BIG_ENDIAN );
546 proto_tree_add_item(lane_tree, hf_atm_le_control_protocol, tvb, offset, 1, ENC_BIG_ENDIAN );
552 proto_tree_add_item(lane_tree, hf_atm_le_control_version, tvb, offset, 1, ENC_BIG_ENDIAN );
556 opcode = tvb_get_ntohs(tvb, offset);
557 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
558 val_to_str(opcode, le_control_opcode_vals,
559 "Unknown opcode (0x%04X)"));
562 proto_tree_add_item(lane_tree, hf_atm_le_control_opcode, tvb, offset, 2, ENC_BIG_ENDIAN );
566 if (opcode == READY_QUERY || opcode == READY_IND) {
567 /* There's nothing more in this packet. */
572 if (opcode & 0x0100) {
573 /* Response; decode status. */
574 proto_tree_add_item(lane_tree, hf_atm_le_control_status, tvb, offset, 2, ENC_BIG_ENDIAN );
578 proto_tree_add_item(lane_tree, hf_atm_le_control_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN );
581 proto_tree_add_item(lane_tree, hf_atm_le_control_requester_lecid, tvb, offset, 2, ENC_BIG_ENDIAN );
584 tf = proto_tree_add_item(lane_tree, hf_atm_le_control_flags, tvb, offset, 2, ENC_BIG_ENDIAN );
585 flags_tree = proto_item_add_subtree(tf, ett_atm_lane_lc_flags);
589 case LE_CONFIGURE_REQUEST:
590 case LE_CONFIGURE_RESPONSE:
591 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
593 dissect_le_configure_join_frame(tvb, offset, lane_tree);
596 case LE_JOIN_REQUEST:
597 case LE_JOIN_RESPONSE:
598 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
599 if (opcode == LE_JOIN_REQUEST) {
600 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_selective_multicast, tvb, offset, 2, ENC_BIG_ENDIAN);
602 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_required, tvb, offset, 2, ENC_BIG_ENDIAN);
605 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_proxy, tvb, offset, 2, ENC_BIG_ENDIAN);
606 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_exclude_explorer_frames, tvb, offset, 2, ENC_BIG_ENDIAN);
609 dissect_le_configure_join_frame(tvb, offset, lane_tree);
612 case LE_REGISTER_REQUEST:
613 case LE_REGISTER_RESPONSE:
614 case LE_UNREGISTER_REQUEST:
615 case LE_UNREGISTER_RESPONSE:
617 dissect_le_registration_frame(tvb, offset, lane_tree);
621 case LE_ARP_RESPONSE:
622 case LE_NARP_REQUEST:
623 if (opcode != LE_NARP_REQUEST) {
624 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_address, tvb, offset, 2, ENC_BIG_ENDIAN);
627 dissect_le_arp_frame(tvb, offset, lane_tree);
630 case LE_TOPOLOGY_REQUEST:
631 proto_tree_add_item(flags_tree, hf_atm_le_control_topology_change, tvb, offset, 2, ENC_BIG_ENDIAN);
633 proto_tree_add_item(flags_tree, hf_atm_reserved, tvb, offset, 92, ENC_NA);
636 case LE_VERIFY_REQUEST:
637 case LE_VERIFY_RESPONSE:
639 dissect_le_verify_frame(tvb, offset, lane_tree);
642 case LE_FLUSH_REQUEST:
643 case LE_FLUSH_RESPONSE:
645 dissect_le_flush_frame(tvb, offset, lane_tree);
652 capture_lane(const guchar *pd, int offset _U_,
653 int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
655 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
656 return try_capture_dissector("atm_lane", pseudo_header->atm.subtype, pd, 2, len, cpinfo, pseudo_header);
660 dissect_lane(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
662 struct atm_phdr *atm_info = (struct atm_phdr *)data;
664 tvbuff_t *next_tvb_le_client;
666 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM LANE");
668 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
669 switch (atm_info->subtype) {
671 case TRAF_ST_LANE_LE_CTRL:
672 dissect_le_control(tvb, pinfo, tree);
675 case TRAF_ST_LANE_802_3:
676 case TRAF_ST_LANE_802_3_MC:
677 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - Ethernet/802.3");
678 dissect_le_client(tvb, tree);
680 /* Dissect as Ethernet */
681 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
682 call_dissector(eth_withoutfcs_handle, next_tvb_le_client, pinfo, tree);
685 case TRAF_ST_LANE_802_5:
686 case TRAF_ST_LANE_802_5_MC:
687 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - 802.5");
688 dissect_le_client(tvb, tree);
690 /* Dissect as Token-Ring */
691 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
692 call_dissector(tr_handle, next_tvb_le_client, pinfo, tree);
696 /* Dump it as raw data. */
697 col_set_str(pinfo->cinfo, COL_INFO, "Unknown LANE traffic type");
698 next_tvb = tvb_new_subset_remaining(tvb, 0);
699 call_data_dissector(next_tvb, pinfo, tree);
702 return tvb_captured_length(tvb);
706 dissect_ilmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
708 return dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_ilmi, ett_ilmi, FALSE);
712 static const value_string aal_vals[] = {
713 { AAL_UNKNOWN, "Unknown AAL" },
716 { AAL_3_4, "AAL3/4" },
718 { AAL_USER, "User AAL" },
719 { AAL_SIGNALLING, "Signalling AAL" },
720 { AAL_OAMCELL, "OAM cell" },
724 /* AAL5 higher-level traffic types */
725 static const value_string aal5_hltype_vals[] = {
726 { TRAF_UNKNOWN, "Unknown traffic type" },
727 { TRAF_LLCMX, "LLC multiplexed" },
728 { TRAF_VCMX, "VC multiplexed" },
729 { TRAF_LANE, "LANE" },
730 { TRAF_ILMI, "ILMI" },
731 { TRAF_FR, "Frame Relay" },
732 { TRAF_SPANS, "FORE SPANS" },
733 { TRAF_IPSILON, "Ipsilon" },
734 { TRAF_GPRS_NS, "GPRS NS" },
735 { TRAF_SSCOP, "SSCOP" },
739 /* Traffic subtypes for VC multiplexed traffic */
740 static const value_string vcmx_type_vals[] = {
741 { TRAF_ST_UNKNOWN, "Unknown VC multiplexed traffic type" },
742 { TRAF_ST_VCMX_802_3_FCS, "802.3 FCS" },
743 { TRAF_ST_VCMX_802_4_FCS, "802.4 FCS" },
744 { TRAF_ST_VCMX_802_5_FCS, "802.5 FCS" },
745 { TRAF_ST_VCMX_FDDI_FCS, "FDDI FCS" },
746 { TRAF_ST_VCMX_802_6_FCS, "802.6 FCS" },
747 { TRAF_ST_VCMX_802_3, "802.3" },
748 { TRAF_ST_VCMX_802_4, "802.4" },
749 { TRAF_ST_VCMX_802_5, "802.5" },
750 { TRAF_ST_VCMX_FDDI, "FDDI" },
751 { TRAF_ST_VCMX_802_6, "802.6" },
752 { TRAF_ST_VCMX_FRAGMENTS, "Fragments" },
753 { TRAF_ST_VCMX_BPDU, "BPDU" },
757 /* Traffic subtypes for LANE traffic */
758 static const value_string lane_type_vals[] = {
759 { TRAF_ST_UNKNOWN, "Unknown LANE traffic type" },
760 { TRAF_ST_LANE_LE_CTRL, "LE Control" },
761 { TRAF_ST_LANE_802_3, "802.3" },
762 { TRAF_ST_LANE_802_5, "802.5" },
763 { TRAF_ST_LANE_802_3_MC, "802.3 multicast" },
764 { TRAF_ST_LANE_802_5_MC, "802.5 multicast" },
768 /* Traffic subtypes for Ipsilon traffic */
769 static const value_string ipsilon_type_vals[] = {
770 { TRAF_ST_UNKNOWN, "Unknown Ipsilon traffic type" },
771 { TRAF_ST_IPSILON_FT0, "Flow type 0" },
772 { TRAF_ST_IPSILON_FT1, "Flow type 1" },
773 { TRAF_ST_IPSILON_FT2, "Flow type 2" },
778 capture_atm(const guchar *pd, int offset,
779 int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
781 if (pseudo_header->atm.aal == AAL_5) {
782 return try_capture_dissector("atm.aal5.type", pseudo_header->atm.type, pd, offset, len, cpinfo, pseudo_header);
788 dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
789 proto_item *atm_ti, proto_tree *atm_tree, gboolean truncated,
790 struct atm_phdr *atm_info, gboolean pseudowire_mode)
792 guint length, reported_length;
801 * This is reassembled traffic, so the cell headers are missing;
802 * show the traffic type for AAL5 traffic, and the VPI and VCI,
803 * from the pseudo-header.
805 if (atm_info->aal == AAL_5) {
806 proto_tree_add_uint(atm_tree, hf_atm_traffic_type, tvb, 0, 0, atm_info->type);
808 switch (atm_info->type) {
811 proto_tree_add_uint(atm_tree, hf_atm_traffic_vcmx, tvb, 0, 0, atm_info->subtype);
815 proto_tree_add_uint(atm_tree, hf_atm_traffic_lane, tvb, 0, 0, atm_info->subtype);
819 proto_tree_add_uint(atm_tree, hf_atm_traffic_ipsilon, tvb, 0, 0, atm_info->subtype);
823 if (!pseudowire_mode) {
824 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0, atm_info->vpi);
825 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0, atm_info->vci);
827 /* Also show vpi/vci in info column */
828 col_append_fstr(pinfo->cinfo, COL_INFO, " VPI=%u, VCI=%u",
829 atm_info->vpi, atm_info->vci);
833 if (truncated || atm_info->flags & ATM_REASSEMBLY_ERROR) {
835 * The packet data does not include stuff such as the AAL5
836 * trailer, either because it was explicitly left out or because
839 if (atm_info->cells != 0) {
841 * If the cell count is 0, assume it means we don't know how
844 * XXX - also assume it means we don't know what was in the AAL5
845 * trailer. We may, however, find some capture program that can
846 * give us the AAL5 trailer information but not the cell count,
847 * in which case we need some other way of indicating whether we
848 * have the AAL5 trailer information.
851 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, atm_info->cells);
852 proto_tree_add_uint(atm_tree, hf_atm_aal5_uu, tvb, 0, 0, atm_info->aal5t_u2u >> 8);
853 proto_tree_add_uint(atm_tree, hf_atm_aal5_cpi, tvb, 0, 0, atm_info->aal5t_u2u & 0xFF);
854 proto_tree_add_uint(atm_tree, hf_atm_aal5_len, tvb, 0, 0, atm_info->aal5t_len);
855 proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, 0, 0, atm_info->aal5t_chksum);
860 * The packet data includes stuff such as the AAL5 trailer, if
861 * it wasn't cut off by the snapshot length, and ATM reassembly
863 * Decode the trailer, if present, and then chop it off.
865 length = tvb_captured_length(tvb);
866 reported_length = tvb_reported_length(tvb);
867 if ((reported_length % 48) == 0) {
869 * Reported length is a multiple of 48, so we can presumably
870 * divide it by 48 to get the number of cells.
872 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, reported_length/48);
874 if ((atm_info->aal == AAL_5 || atm_info->aal == AAL_SIGNALLING) &&
875 length >= reported_length) {
877 * XXX - what if the packet is truncated? Can that happen?
878 * What if you capture with Windows Sniffer on an ATM link
879 * and tell it not to save the entire packet? What happens
882 aal5_length = tvb_get_ntohs(tvb, length - 6);
885 * Check for sanity in the AAL5 length. It must be > 0
886 * and must be less than the amount of space left after
887 * we remove the trailer.
889 * If it's not sane, assume we don't have a trailer.
891 if (aal5_length > 0 && aal5_length <= length - 8) {
893 * How much padding is there?
895 pad_length = length - aal5_length - 8;
898 * There is no reason for more than 47 bytes of padding.
899 * The most padding you can have would be 7 bytes at the
900 * end of the next-to-last cell (8 bytes after the end of
901 * the data means you can fit the trailer in that cell),
902 * plus 40 bytes in the last cell (with the last 8 bytes
905 * If there's more than 47 bytes of padding, assume we don't
908 if (pad_length <= 47) {
912 if (pad_length > 0) {
913 proto_tree_add_item(atm_tree, hf_atm_padding, tvb, aal5_length, pad_length, ENC_NA);
916 proto_tree_add_item(atm_tree, hf_atm_aal5_uu, tvb, length - 8, 1, ENC_BIG_ENDIAN);
917 proto_tree_add_item(atm_tree, hf_atm_aal5_cpi, tvb, length - 7, 1, ENC_BIG_ENDIAN);
918 proto_tree_add_item(atm_tree, hf_atm_aal5_len, tvb, length - 6, 2, ENC_BIG_ENDIAN);
920 crc = tvb_get_ntohl(tvb, length - 4);
921 calc_crc = crc32_mpeg2_tvb(tvb, length);
922 ti = proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, length - 4, 4, crc);
923 proto_item_append_text(ti, (calc_crc == 0xC704DD7B) ? " (correct)" : " (incorrect)");
925 next_tvb = tvb_new_subset_length(tvb, 0, aal5_length);
933 * Don't try to dissect the payload of PDUs with a reassembly
936 switch (atm_info->aal) {
939 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
940 call_dissector(sscop_handle, next_tvb, pinfo, tree);
946 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
947 if (dissector_try_uint_new(atm_type_aal5_table, atm_info->type, next_tvb, pinfo, tree, TRUE, atm_info))
953 if (tvb_reported_length(next_tvb) > 7) /* sizeof(octet) */
956 tvb_memcpy(next_tvb, octet, 0, sizeof(octet));
960 && octet[2] == 0x03) /* LLC SNAP as per RFC2684 */
962 call_dissector(llc_handle, next_tvb, pinfo, tree);
965 else if ((pntoh16(octet) & 0xff) == PPP_IP)
967 call_dissector(ppp_handle, next_tvb, pinfo, tree);
970 else if (pntoh16(octet) == 0x00)
973 * Assume VC multiplexed bridged Ethernet.
974 * Whether there's an FCS is an option negotiated
975 * over the VC, so we call the "do heuristic checks
976 * to see if there's an FCS" version of the Ethernet
979 * See RFC 2684 section 6.2 "VC Multiplexing of Bridged
982 proto_tree_add_item(tree, hf_atm_padding, tvb, 0, 2, ENC_NA);
983 next_tvb = tvb_new_subset_remaining(tvb, 2);
984 call_dissector(eth_maybefcs_handle, next_tvb, pinfo, tree);
987 else if (octet[2] == 0x03 && /* NLPID */
988 ((octet[3] == 0xcc || /* IPv4 */
989 octet[3] == 0x8e) || /* IPv6 */
990 (octet[3] == 0x00 && /* Eth */
991 octet[4] == 0x80))) /* Eth */
993 /* assume network interworking with FR 2 byte header */
994 call_dissector(fr_handle, next_tvb, pinfo, tree);
997 else if (octet[4] == 0x03 && /* NLPID */
998 ((octet[5] == 0xcc || /* IPv4 */
999 octet[5] == 0x8e) || /* IPv6 */
1000 (octet[5] == 0x00 && /* Eth */
1001 octet[6] == 0x80))) /* Eth */
1003 /* assume network interworking with FR 4 byte header */
1004 call_dissector(fr_handle, next_tvb, pinfo, tree);
1007 else if (((octet[0] & 0xf0)== 0x40) ||
1008 ((octet[0] & 0xf0) == 0x60))
1010 call_dissector(ip_handle, next_tvb, pinfo, tree);
1020 proto_tree_add_uint(atm_tree, hf_atm_cid, tvb, 0, 0,
1021 atm_info->aal2_cid);
1022 proto_item_append_text(atm_ti, " (vpi=%u vci=%u cid=%u)",
1025 atm_info->aal2_cid);
1027 if (!(atm_info->flags & ATM_REASSEMBLY_ERROR)) {
1028 if (atm_info->flags & ATM_AAL2_NOPHDR) {
1031 /* Skip first 4 bytes of message
1035 Ignoring for now... */
1036 next_tvb = tvb_new_subset_remaining(tvb, 4);
1039 if (dissector_try_uint(atm_type_aal2_table, atm_info->type, next_tvb, pinfo, tree))
1047 /* Dump it as raw data. */
1052 /* Dump it as raw data. */
1053 call_data_dissector(next_tvb, pinfo, tree);
1058 * Charles Michael Heard's HEC code, from
1060 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1062 * with the syndrome and error position tables initialized with values
1063 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1064 * rather than by calling those routines at run time, and with various data
1065 * type cleanups and changes not to correct the header if a correctible
1066 * error was detected.
1068 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1070 static const guint8 syndrome_table[256] = {
1071 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1072 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1073 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1074 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1075 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1076 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1077 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1078 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1079 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1080 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1081 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1082 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1083 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1084 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1085 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1086 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1087 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1088 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1089 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1090 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1091 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1092 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1093 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1094 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1095 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1096 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1097 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1098 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1099 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1100 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1101 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1102 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1105 #define NO_ERROR_DETECTED -128
1106 #define UNCORRECTIBLE_ERROR 128
1108 static const int err_posn_table[256] = {
1109 NO_ERROR_DETECTED, 39,
1110 38, UNCORRECTIBLE_ERROR,
1111 37, UNCORRECTIBLE_ERROR,
1112 UNCORRECTIBLE_ERROR, 31,
1113 36, UNCORRECTIBLE_ERROR,
1114 UNCORRECTIBLE_ERROR, 8,
1115 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1116 30, UNCORRECTIBLE_ERROR,
1117 35, UNCORRECTIBLE_ERROR,
1118 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1119 UNCORRECTIBLE_ERROR, 23,
1120 7, UNCORRECTIBLE_ERROR,
1121 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1122 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1123 29, UNCORRECTIBLE_ERROR,
1124 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1125 34, UNCORRECTIBLE_ERROR,
1126 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1127 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1128 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1129 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1130 22, UNCORRECTIBLE_ERROR,
1131 6, UNCORRECTIBLE_ERROR,
1132 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1133 UNCORRECTIBLE_ERROR, 0,
1134 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1135 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1136 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1137 28, UNCORRECTIBLE_ERROR,
1138 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1139 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1140 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1141 33, UNCORRECTIBLE_ERROR,
1142 UNCORRECTIBLE_ERROR, 10,
1143 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1144 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1145 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1146 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1147 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1148 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1149 UNCORRECTIBLE_ERROR, 12,
1150 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1151 21, UNCORRECTIBLE_ERROR,
1152 UNCORRECTIBLE_ERROR, 19,
1153 5, UNCORRECTIBLE_ERROR,
1154 UNCORRECTIBLE_ERROR, 17,
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, 3,
1161 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1162 UNCORRECTIBLE_ERROR, 15,
1163 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1164 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1165 27, UNCORRECTIBLE_ERROR,
1166 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
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, UNCORRECTIBLE_ERROR,
1173 32, UNCORRECTIBLE_ERROR,
1174 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1175 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1176 9, UNCORRECTIBLE_ERROR,
1177 UNCORRECTIBLE_ERROR, 24,
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 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1186 UNCORRECTIBLE_ERROR, 1,
1187 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1188 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1189 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1190 11, UNCORRECTIBLE_ERROR,
1191 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1192 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1193 20, UNCORRECTIBLE_ERROR,
1194 UNCORRECTIBLE_ERROR, 13,
1195 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1196 18, UNCORRECTIBLE_ERROR,
1197 4, UNCORRECTIBLE_ERROR,
1198 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1199 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1200 16, UNCORRECTIBLE_ERROR,
1201 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1202 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1203 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1204 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1205 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1206 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1207 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1208 UNCORRECTIBLE_ERROR, 25,
1209 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1210 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1211 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1212 2, UNCORRECTIBLE_ERROR,
1213 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1214 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1215 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1216 14, UNCORRECTIBLE_ERROR,
1217 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1218 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1219 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1220 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1221 26, UNCORRECTIBLE_ERROR,
1222 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1223 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1224 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1225 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1226 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1227 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1228 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1229 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1230 UNCORRECTIBLE_ERROR, 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,
1240 * Return an indication of whether there was an error in the cell header
1241 * and, if so, where the error was, if it was correctable.
1244 get_header_err(const guint8 *cell_header)
1246 register guint8 syndrome;
1247 register int i, err_posn;
1250 for (i = 0; i < 4; i++)
1251 syndrome = syndrome_table[syndrome ^ cell_header[i]];
1252 syndrome ^= cell_header[4] ^ COSET_LEADER;
1254 err_posn = err_posn_table [syndrome];
1257 return NO_ERROR_DETECTED;
1258 else if (err_posn < 40)
1261 return UNCORRECTIBLE_ERROR;
1264 const value_string atm_pt_vals[] = {
1265 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1266 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1267 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1268 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1269 { 4, "Segment OAM F5 flow related cell" },
1270 { 5, "End-to-end OAM F5 flow related cell" },
1271 { 6, "VC resource management cell" },
1275 static const value_string st_vals[] = {
1283 #define OAM_TYPE_FM 1 /* Fault Management */
1284 #define OAM_TYPE_PM 2 /* Performance Management */
1285 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1287 static const value_string oam_type_vals[] = {
1288 { OAM_TYPE_FM, "Fault Management" },
1289 { OAM_TYPE_PM, "Performance Management" },
1290 { OAM_TYPE_AD, "Activation/Deactivation" },
1294 static const value_string ft_fm_vals[] = {
1295 { 0, "Alarm Indication Signal" },
1296 { 1, "Far End Receive Failure" },
1297 { 8, "OAM Cell Loopback" },
1298 { 4, "Continuity Check" },
1302 static const value_string ft_pm_vals[] = {
1303 { 0, "Forward Monitoring" },
1304 { 1, "Backward Reporting" },
1305 { 2, "Monitoring and Reporting" },
1309 static const value_string ft_ad_vals[] = {
1310 { 0, "Performance Monitoring" },
1311 { 1, "Continuity Check" },
1317 dissect_atm_cell_payload(tvbuff_t *tvb, int offset, packet_info *pinfo,
1318 proto_tree *tree, guint aal, gboolean fill_columns)
1320 proto_tree *aal_tree;
1324 guint16 aal3_4_hdr, crc10;
1330 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL1");
1331 col_clear(pinfo->cinfo, COL_INFO);
1332 ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, ENC_NA);
1333 aal_tree = proto_item_add_subtree(ti, ett_aal1);
1334 octet = tvb_get_guint8(tvb, offset);
1336 proto_tree_add_item(aal_tree, hf_atm_aa1_csi, tvb, offset, 1, ENC_BIG_ENDIAN);
1337 proto_tree_add_item(aal_tree, hf_atm_aa1_seq_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1338 col_add_fstr(pinfo->cinfo, COL_INFO, "Sequence count = %u",
1339 (octet >> 4) & 0x7);
1340 proto_tree_add_item(aal_tree, hf_atm_aa1_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1341 proto_tree_add_item(aal_tree, hf_atm_aa1_parity, tvb, offset, 1, ENC_BIG_ENDIAN);
1344 proto_tree_add_item(aal_tree, hf_atm_aa1_payload, tvb, offset, 47, ENC_NA);
1349 * XXX - or should this be the CS PDU?
1351 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL3/4");
1352 col_clear(pinfo->cinfo, COL_INFO);
1353 ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, ENC_NA);
1354 aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
1355 aal3_4_hdr = tvb_get_ntohs(tvb, offset);
1356 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, sequence number = %u",
1357 val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"),
1358 (aal3_4_hdr >> 10) & 0xF);
1359 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1360 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seq_num, tvb, offset, 2, ENC_BIG_ENDIAN);
1361 proto_tree_add_item(aal_tree, hf_atm_aal3_4_multiplex_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1363 length = tvb_reported_length_remaining(tvb, offset);
1364 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1367 proto_tree_add_item(aal_tree, hf_atm_aal3_4_information, tvb, offset, 44, ENC_NA);
1370 proto_tree_add_item(aal_tree, hf_atm_aal3_4_length_indicator, tvb, offset, 2, ENC_BIG_ENDIAN);
1371 ti = proto_tree_add_item(aal_tree, hf_atm_aal3_4_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1372 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1378 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
1379 col_clear(pinfo->cinfo, COL_INFO);
1381 ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, ENC_NA);
1382 aal_tree = proto_item_add_subtree(ti, ett_oamaal);
1383 octet = tvb_get_guint8(tvb, offset);
1386 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
1387 val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
1390 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1391 switch (octet >> 4) {
1394 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_fm, tvb, offset, 1, ENC_BIG_ENDIAN);
1398 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_pm, tvb, offset, 1, ENC_BIG_ENDIAN);
1402 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ad, tvb, offset, 1, ENC_BIG_ENDIAN);
1406 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1409 length = tvb_reported_length_remaining(tvb, offset);
1410 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1413 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_func_spec, tvb, offset, 45, ENC_NA);
1416 ti = proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1417 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1421 next_tvb = tvb_new_subset_remaining(tvb, offset);
1422 call_data_dissector(next_tvb, pinfo, tree);
1428 * Check for OAM cells.
1429 * OAM F4 is VCI 3 or 4 and PT 0X0.
1433 atm_is_oam_cell(const guint16 vci, const guint8 pt)
1435 return (((vci == 3 || vci == 4) && ((pt & 0x5) == 0))
1436 || ((pt & 0x6) == 0x4));
1441 dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1442 proto_tree *atm_tree, guint aal, gboolean nni,
1443 gboolean crc_stripped)
1453 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1454 * and encoding at UNI reference point as:
1469 octet = tvb_get_guint8(tvb, 0);
1470 proto_tree_add_item(atm_tree, hf_atm_gfc, tvb, 0, 1, ENC_NA);
1471 vpi = (octet & 0xF) << 4;
1472 octet = tvb_get_guint8(tvb, 1);
1474 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1477 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1478 * and encoding at NNI reference point as:
1493 octet = tvb_get_guint8(tvb, 0);
1495 octet = tvb_get_guint8(tvb, 1);
1496 vpi |= (octet & 0xF0) >> 4;
1497 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1500 vci = (octet & 0x0F) << 12;
1501 octet = tvb_get_guint8(tvb, 2);
1503 octet = tvb_get_guint8(tvb, 3);
1505 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 1, 3, vci);
1506 pt = (octet >> 1) & 0x7;
1507 proto_tree_add_item(atm_tree, hf_atm_payload_type, tvb, 3, 1, ENC_BIG_ENDIAN);
1508 proto_tree_add_item(atm_tree, hf_atm_cell_loss_priority, tvb, 3, 1, ENC_BIG_ENDIAN);
1510 if (!crc_stripped) {
1512 * FF: parse the Header Error Check (HEC).
1514 ti = proto_tree_add_item(atm_tree, hf_atm_header_error_check, tvb, 4, 1, ENC_BIG_ENDIAN);
1515 err = get_header_err((const guint8*)tvb_memdup(wmem_packet_scope(), tvb, 0, 5));
1516 if (err == NO_ERROR_DETECTED)
1517 proto_item_append_text(ti, " (correct)");
1518 else if (err == UNCORRECTIBLE_ERROR)
1519 proto_item_append_text(ti, " (uncorrectable error)");
1521 proto_item_append_text(ti, " (error in bit %d)", err);
1525 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1526 * Cell Mode) the Header Error Check (HEC) field is stripped.
1527 * So we do nothing here.
1533 * Check for OAM cells.
1534 * XXX - do this for all AAL values, overriding whatever information
1535 * Wiretap got from the file?
1537 if (aal == AAL_USER || aal == AAL_UNKNOWN) {
1538 if (atm_is_oam_cell(vci,pt)) {
1543 dissect_atm_cell_payload(tvb, offset, pinfo, tree, aal, TRUE);
1547 dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1548 gboolean truncated, struct atm_phdr *atm_info, gboolean pseudowire_mode)
1550 proto_tree *atm_tree = NULL;
1551 proto_item *atm_ti = NULL;
1553 if ( atm_info->aal == AAL_5 && atm_info->type == TRAF_LANE &&
1554 dissect_lanesscop ) {
1555 atm_info->aal = AAL_SIGNALLING;
1558 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1560 if (!pseudowire_mode) {
1561 switch (atm_info->channel) {
1564 /* Traffic from DTE to DCE. */
1565 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
1566 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
1570 /* Traffic from DCE to DTE. */
1571 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
1572 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
1577 if (atm_info->aal == AAL_5) {
1578 col_add_fstr(pinfo->cinfo, COL_INFO, "AAL5 %s",
1579 val_to_str(atm_info->type, aal5_hltype_vals,
1580 "Unknown traffic type (%u)"));
1582 col_add_str(pinfo->cinfo, COL_INFO,
1583 val_to_str(atm_info->aal, aal_vals,
1584 "Unknown AAL (%u)"));
1588 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, -1, ENC_NA);
1589 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1591 if (!pseudowire_mode) {
1592 proto_tree_add_uint(atm_tree, hf_atm_channel, tvb, 0, 0, atm_info->channel);
1593 if (atm_info->flags & ATM_REASSEMBLY_ERROR)
1594 expert_add_info(pinfo, atm_ti, &ei_atm_reassembly_failed);
1597 proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0,
1600 val_to_str(atm_info->aal, aal_vals,
1601 "Unknown AAL (%u)"));
1603 if (atm_info->flags & ATM_RAW_CELL) {
1604 /* This is a single cell, with the cell header at the beginning. */
1605 if (atm_info->flags & ATM_NO_HEC) {
1606 proto_item_set_len(atm_ti, 4);
1608 proto_item_set_len(atm_ti, 5);
1610 dissect_atm_cell(tvb, pinfo, tree, atm_tree,
1611 atm_info->aal, FALSE,
1612 atm_info->flags & ATM_NO_HEC);
1614 /* This is a reassembled PDU. */
1617 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
1618 * In such cases, the dissector data parameter is used to pass info from/to
1619 * PW dissector to ATM dissector. For decoding normal ATM traffic
1620 * data parameter should be NULL.
1622 dissect_reassembled_pdu(tvb, pinfo, tree, atm_tree, atm_ti, truncated,
1623 atm_info, pseudowire_mode);
1626 return tvb_reported_length(tvb);
1630 dissect_atm_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1632 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1634 DISSECTOR_ASSERT(atm_info != NULL);
1636 return dissect_atm_common(tvb, pinfo, tree, TRUE, atm_info, FALSE);
1640 dissect_atm_pw_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1642 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1644 DISSECTOR_ASSERT(atm_info != NULL);
1646 return dissect_atm_common(tvb, pinfo, tree, TRUE, atm_info, TRUE);
1650 dissect_atm_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1652 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1654 DISSECTOR_ASSERT(atm_info != NULL);
1656 return dissect_atm_common(tvb, pinfo, tree, FALSE, atm_info, FALSE);
1660 dissect_atm_pw_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1662 struct atm_phdr *atm_info = (struct atm_phdr *)data;
1664 DISSECTOR_ASSERT(atm_info != NULL);
1666 return dissect_atm_common(tvb, pinfo, tree, FALSE, atm_info, TRUE);
1670 dissect_atm_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1672 proto_tree *atm_tree;
1675 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1677 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, 0, ENC_NA);
1678 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1680 dissect_atm_cell(tvb, pinfo, tree, atm_tree, AAL_OAMCELL, FALSE, FALSE);
1681 return tvb_reported_length(tvb);
1685 dissect_atm_pw_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1687 const pwatm_private_data_t *pwpd = (const pwatm_private_data_t *)data;
1689 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1691 dissect_atm_cell_payload(tvb, 0, pinfo, tree, AAL_OAMCELL,
1692 pwpd->enable_fill_columns_by_atm_dissector);
1694 return tvb_reported_length(tvb);
1697 static void atm_prompt(packet_info *pinfo _U_, gchar* result)
1699 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode AAL2 traffic as");
1702 static gpointer atm_value(packet_info *pinfo)
1704 return GUINT_TO_POINTER((guint)pinfo->pseudo_header->atm.type);
1708 proto_register_atm(void)
1710 static hf_register_info hf[] = {
1712 { "AAL", "atm.aal", FT_UINT8, BASE_DEC, VALS(aal_vals), 0x0,
1715 { "GFC", "atm.GFC", FT_UINT8, BASE_DEC, NULL, 0xF0,
1718 { "VPI", "atm.vpi", FT_UINT8, BASE_DEC, NULL, 0x0,
1722 { "VCI", "atm.vci", FT_UINT16, BASE_DEC, NULL, 0x0,
1726 { "CID", "atm.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
1730 { "Reserved", "atm.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
1733 { &hf_atm_le_client_client,
1734 { "LE Client", "atm.le_client.client", FT_UINT16, BASE_HEX, NULL, 0x0,
1736 { &hf_atm_lan_destination_tag,
1737 { "Tag", "atm.lan_destination.tag", FT_UINT16, BASE_HEX, VALS(le_control_landest_tag_vals), 0x0,
1739 { &hf_atm_lan_destination_mac,
1740 { "MAC address", "atm.lan_destination.mac", FT_ETHER, BASE_NONE, NULL, 0x0,
1742 { &hf_atm_le_control_tlv_type,
1743 { "TLV Type", "atm.le_control.tlv_type", FT_UINT32, BASE_HEX, VALS(le_tlv_type_vals), 0x0,
1745 { &hf_atm_le_control_tlv_length,
1746 { "TLV Length", "atm.le_control.tlv_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1748 { &hf_atm_lan_destination_route_desc,
1749 { "Route descriptor", "atm.lan_destination.route_desc", FT_UINT16, BASE_HEX, NULL, 0x0,
1751 { &hf_atm_lan_destination_lan_id,
1752 { "LAN ID", "atm.lan_destination.lan_id", FT_UINT16, BASE_DEC, NULL, 0xFFF0,
1754 { &hf_atm_lan_destination_bridge_num,
1755 { "Bridge number", "atm.lan_destination.bridge_num", FT_UINT16, BASE_DEC, NULL, 0x000F,
1757 { &hf_atm_source_atm,
1758 { "Source ATM address", "atm.source_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1760 { &hf_atm_target_atm,
1761 { "Target ATM address", "atm.target_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1763 { &hf_atm_le_configure_join_frame_lan_type,
1764 { "LAN type", "atm.le_configure_join_frame.lan_type", FT_UINT8, BASE_HEX, VALS(le_control_lan_type_vals), 0x0,
1766 { &hf_atm_le_configure_join_frame_max_frame_size,
1767 { "Maximum frame size", "atm.le_configure_join_frame.max_frame_size", FT_UINT8, BASE_HEX, VALS(le_control_frame_size_vals), 0x0,
1769 { &hf_atm_le_configure_join_frame_num_tlvs,
1770 { "Number of TLVs", "atm.le_configure_join_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1772 { &hf_atm_le_configure_join_frame_elan_name_size,
1773 { "ELAN name size", "atm.le_configure_join_frame.elan_name_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1775 { &hf_atm_le_registration_frame_num_tlvs,
1776 { "Number of TLVs", "atm.le_registration_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1778 { &hf_atm_le_arp_frame_num_tlvs,
1779 { "Number of TLVs", "atm.le_arp_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1781 { &hf_atm_le_verify_frame_num_tlvs,
1782 { "Number of TLVs", "atm.le_verify_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1784 { &hf_atm_le_configure_join_frame_elan_name,
1785 { "ELAN name", "atm.le_configure_join_frame.elan_name", FT_BYTES, BASE_NONE, NULL, 0x0,
1787 { &hf_atm_le_control_marker,
1788 { "Marker", "atm.le_control.marker", FT_UINT16, BASE_HEX, NULL, 0x0,
1790 { &hf_atm_le_control_protocol,
1791 { "Protocol", "atm.le_control.protocol", FT_UINT8, BASE_HEX, NULL, 0x0,
1793 { &hf_atm_le_control_version,
1794 { "Version", "atm.le_control.version", FT_UINT8, BASE_HEX, NULL, 0x0,
1796 { &hf_atm_le_control_opcode,
1797 { "Opcode", "atm.le_control.opcode", FT_UINT16, BASE_HEX, VALS(le_control_opcode_vals), 0x0,
1799 { &hf_atm_le_control_status,
1800 { "Status", "atm.le_control.status", FT_UINT16, BASE_HEX, VALS(le_control_status_vals), 0x0,
1802 { &hf_atm_le_control_transaction_id,
1803 { "Transaction ID", "atm.le_control.transaction_id", FT_UINT32, BASE_HEX, NULL, 0x0,
1805 { &hf_atm_le_control_requester_lecid,
1806 { "Requester LECID", "atm.le_control.requester_lecid", FT_UINT16, BASE_HEX, NULL, 0x0,
1808 { &hf_atm_le_control_flags,
1809 { "Flags", "atm.le_control.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
1811 { &hf_atm_le_control_flag_v2_capable,
1812 { "V2 capable", "atm.le_control.flag.v2_capable", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002,
1814 { &hf_atm_le_control_flag_selective_multicast,
1815 { "Selective multicast", "atm.le_control.flag.selective_multicast", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004,
1817 { &hf_atm_le_control_flag_v2_required,
1818 { "V2 required", "atm.le_control.flag.v2_required", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008,
1820 { &hf_atm_le_control_flag_proxy,
1821 { "Proxy", "atm.le_control.flag.flag_proxy", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0080,
1823 { &hf_atm_le_control_flag_exclude_explorer_frames,
1824 { "Exclude explorer frames", "atm.le_control.flag.exclude_explorer_frames", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0200,
1826 { &hf_atm_le_control_flag_address,
1827 { "Address", "atm.le_control.flag.address", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001,
1829 { &hf_atm_le_control_topology_change,
1830 { "Topology change", "atm.le_control.flag.topology_change", FT_BOOLEAN, 16, TFS(&tfs_remote_local), 0x0100,
1832 { &hf_atm_traffic_type,
1833 { "Traffic type", "atm.traffic_type", FT_UINT8, BASE_DEC, VALS(aal5_hltype_vals), 0x0,
1835 { &hf_atm_traffic_vcmx,
1836 { "VC multiplexed traffic type", "atm.traffic.vcmx", FT_UINT8, BASE_DEC, VALS(vcmx_type_vals), 0x0,
1838 { &hf_atm_traffic_lane,
1839 { "LANE traffic type", "atm.traffic.lane", FT_UINT8, BASE_DEC, VALS(lane_type_vals), 0x0,
1841 { &hf_atm_traffic_ipsilon,
1842 { "Ipsilon traffic type", "atm.traffic.ipsilon", FT_UINT8, BASE_DEC, VALS(ipsilon_type_vals), 0x0,
1845 { "Cells", "atm.cells", FT_UINT16, BASE_DEC, NULL, 0x0,
1848 { "AAL5 UU", "atm.hf_atm.aal5t_uu", FT_UINT8, BASE_HEX, NULL, 0x0,
1851 { "AAL5 CPI", "atm.hf_atm.aal5t_cpi", FT_UINT8, BASE_HEX, NULL, 0x0,
1854 { "AAL5 len", "atm.aal5t_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1857 { "AAL5 CRC", "atm.aal5t_crc", FT_UINT32, BASE_HEX, NULL, 0x0,
1859 { &hf_atm_payload_type,
1860 { "Payload Type", "atm.payload_type", FT_UINT8, BASE_DEC, NULL, 0x0E,
1862 { &hf_atm_cell_loss_priority,
1863 { "Cell Loss Priority", "atm.cell_loss_priority", FT_BOOLEAN, 8, TFS(&tfs_low_high_priority), 0x01,
1865 { &hf_atm_header_error_check,
1866 { "Header Error Check", "atm.header_error_check", FT_UINT8, BASE_HEX, NULL, 0,
1869 { "Channel", "atm.channel", FT_UINT16, BASE_DEC, VALS(atm_channel_vals), 0,
1872 { "CSI", "atm.aa1.csi", FT_UINT8, BASE_DEC, NULL, 0x80,
1874 { &hf_atm_aa1_seq_count,
1875 { "Sequence Count", "atm.aa1.seq_count", FT_UINT8, BASE_DEC, NULL, 0x70,
1878 { "CRC", "atm.aa1.crc", FT_UINT8, BASE_DEC, NULL, 0x08,
1880 { &hf_atm_aa1_parity,
1881 { "Parity", "atm.aa1.parity", FT_UINT8, BASE_DEC, NULL, 0x07,
1883 { &hf_atm_aa1_payload,
1884 { "Payload", "atm.aa1.payload", FT_BYTES, BASE_NONE, NULL, 0x0,
1886 { &hf_atm_aal3_4_seg_type,
1887 { "Segment Type", "atm.aal3_4.seg_type", FT_UINT16, BASE_DEC, VALS(st_vals), 0xC000,
1889 { &hf_atm_aal3_4_seq_num,
1890 { "Sequence Number", "atm.aal3_4.seq_num", FT_UINT16, BASE_DEC, NULL, 0x3C00,
1892 { &hf_atm_aal3_4_multiplex_id,
1893 { "Multiplex ID", "atm.aal3_4.multiplex_id", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1895 { &hf_atm_aal3_4_information,
1896 { "Information", "atm.aal3_4.information", FT_BYTES, BASE_NONE, NULL, 0x0,
1898 { &hf_atm_aal3_4_length_indicator,
1899 { "Length Indicator", "atm.aal3_4.length_indicator", FT_UINT16, BASE_DEC, VALS(st_vals), 0xFC00,
1901 { &hf_atm_aal3_4_crc,
1902 { "CRC", "atm.aal3_4.crc", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1904 { &hf_atm_aal_oamcell_type,
1905 { "OAM Type", "atm.aal_oamcell.type", FT_UINT8, BASE_DEC, VALS(oam_type_vals), 0xF0,
1907 { &hf_atm_aal_oamcell_type_fm,
1908 { "Function Type", "atm.aal_oamcell.type.fm", FT_UINT8, BASE_DEC, VALS(ft_fm_vals), 0x0F,
1910 { &hf_atm_aal_oamcell_type_pm,
1911 { "Function Type", "atm.aal_oamcell.type.pm", FT_UINT8, BASE_DEC, VALS(ft_pm_vals), 0x0F,
1913 { &hf_atm_aal_oamcell_type_ad,
1914 { "Function Type", "atm.aal_oamcell.type.ad", FT_UINT8, BASE_DEC, VALS(ft_ad_vals), 0x0F,
1916 { &hf_atm_aal_oamcell_type_ft,
1917 { "Function Type", "atm.aal_oamcell.type.ft", FT_UINT8, BASE_DEC, NULL, 0x0F,
1919 { &hf_atm_aal_oamcell_func_spec,
1920 { "Function-specific information", "atm.aal_oamcell.func_spec", FT_BYTES, BASE_NONE, NULL, 0x0,
1922 { &hf_atm_aal_oamcell_crc,
1923 { "CRC-10", "atm.aal_oamcell.crc", FT_UINT16, BASE_HEX, NULL, 0x3FF,
1926 { "Padding", "atm.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
1931 static gint *ett[] = {
1938 &ett_atm_lane_lc_lan_dest,
1939 &ett_atm_lane_lc_lan_dest_rd,
1940 &ett_atm_lane_lc_flags,
1941 &ett_atm_lane_lc_tlv,
1944 static ei_register_info ei[] = {
1945 { &ei_atm_reassembly_failed, { "atm.reassembly_failed", PI_REASSEMBLE, PI_ERROR, "PDU reassembly failed", EXPFILL }},
1948 expert_module_t* expert_atm;
1949 module_t *atm_module;
1951 /* Decode As handling */
1952 static build_valid_func atm_da_build_value[1] = {atm_value};
1953 static decode_as_value_t atm_da_values = {atm_prompt, 1, atm_da_build_value};
1954 static decode_as_t atm_da = {"atm", "Network", "atm.aal2.type", 1, 0, &atm_da_values, NULL, NULL,
1955 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
1957 proto_atm = proto_register_protocol("Asynchronous Transfer Mode", "ATM", "atm");
1958 proto_aal1 = proto_register_protocol("ATM AAL1", "AAL1", "aal1");
1959 proto_aal3_4 = proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
1960 proto_oamaal = proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
1961 proto_register_field_array(proto_atm, hf, array_length(hf));
1962 proto_register_subtree_array(ett, array_length(ett));
1963 expert_atm = expert_register_protocol(proto_atm);
1964 expert_register_field_array(expert_atm, ei, array_length(ei));
1966 proto_ilmi = proto_register_protocol("ILMI", "ILMI", "ilmi");
1968 proto_atm_lane = proto_register_protocol("ATM LAN Emulation", "ATM LANE", "lane");
1970 atm_type_aal2_table = register_dissector_table("atm.aal2.type", "ATM AAL_2 type", proto_atm, FT_UINT32, BASE_DEC);
1971 atm_type_aal5_table = register_dissector_table("atm.aal5.type", "ATM AAL_5 type", proto_atm, FT_UINT32, BASE_DEC);
1973 register_capture_dissector_table("atm.aal5.type", "ATM AAL_5");
1974 register_capture_dissector_table("atm_lane", "ATM LAN Emulation");
1976 atm_handle = register_dissector("atm_truncated", dissect_atm_truncated, proto_atm);
1977 register_dissector("atm_pw_truncated", dissect_atm_pw_truncated, proto_atm);
1978 atm_untruncated_handle = register_dissector("atm_untruncated", dissect_atm_untruncated, proto_atm);
1979 register_dissector("atm_pw_untruncated", dissect_atm_pw_untruncated, proto_atm);
1980 register_dissector("atm_oam_cell", dissect_atm_oam_cell, proto_oamaal);
1981 register_dissector("atm_pw_oam_cell", dissect_atm_pw_oam_cell, proto_oamaal);
1983 atm_module = prefs_register_protocol ( proto_atm, NULL );
1984 prefs_register_bool_preference(atm_module, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
1985 "Autodection between LANE and SSCOP is hard. As default LANE is preferred",
1986 &dissect_lanesscop);
1987 prefs_register_obsolete_preference(atm_module, "unknown_aal2_type");
1989 register_decode_as(&atm_da);
1993 proto_reg_handoff_atm(void)
1995 capture_dissector_handle_t atm_cap_handle;
1998 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
1999 * SSCOP, LANE, and ILMI dissectors.
2001 eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_atm_lane);
2002 tr_handle = find_dissector_add_dependency("tr", proto_atm_lane);
2003 fr_handle = find_dissector_add_dependency("fr", proto_atm);
2004 llc_handle = find_dissector_add_dependency("llc", proto_atm);
2005 sscop_handle = find_dissector_add_dependency("sscop", proto_atm);
2006 ppp_handle = find_dissector_add_dependency("ppp", proto_atm);
2007 eth_maybefcs_handle = find_dissector_add_dependency("eth_maybefcs", proto_atm);
2008 ip_handle = find_dissector_add_dependency("ip", proto_atm);
2010 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_handle);
2011 dissector_add_uint("atm.aal5.type", TRAF_LANE, create_dissector_handle(dissect_lane, proto_atm_lane));
2012 dissector_add_uint("atm.aal5.type", TRAF_ILMI, create_dissector_handle(dissect_ilmi, proto_ilmi));
2014 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,
2015 atm_untruncated_handle);
2017 atm_cap_handle = create_capture_dissector_handle(capture_atm, proto_atm);
2018 capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_cap_handle);
2019 atm_cap_handle = create_capture_dissector_handle(capture_lane, proto_atm_lane);
2020 capture_dissector_add_uint("atm.aal5.type", TRAF_LANE, atm_cap_handle);
2024 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2029 * indent-tabs-mode: nil
2032 * ex: set shiftwidth=2 tabstop=8 expandtab:
2033 * :indentSize=2:tabSize=8:noTabs=true: