2 * Routines for ATM packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <epan/packet.h>
26 #include <wsutil/pint.h>
28 #include <epan/addr_resolv.h>
29 #include <epan/ppptypes.h>
30 #include <epan/expert.h>
31 #include <epan/crc10-tvb.h>
32 #include <epan/crc32-tvb.h>
33 #include <epan/decode_as.h>
35 #include "packet-atm.h"
36 #include "packet-snmp.h"
37 #include "packet-eth.h"
38 #include "packet-tr.h"
39 #include "packet-llc.h"
40 #include <epan/prefs.h>
41 #include "packet-pw-atm.h"
43 void proto_register_atm(void);
44 void proto_reg_handoff_atm(void);
46 static int proto_atm = -1;
47 static int hf_atm_aal = -1;
48 static int hf_atm_gfc = -1;
49 static int hf_atm_vpi = -1;
50 static int hf_atm_vci = -1;
51 static int hf_atm_cid = -1;
52 static int hf_atm_reserved = -1;
53 static int proto_atm_lane = -1;
54 static int proto_ilmi = -1;
55 static int proto_aal1 = -1;
56 static int proto_aal3_4 = -1;
57 static int proto_oamaal = -1;
59 static int hf_atm_le_client_client = -1;
60 static int hf_atm_lan_destination_tag = -1;
61 static int hf_atm_lan_destination_mac = -1;
62 static int hf_atm_le_control_tlv_type = -1;
63 static int hf_atm_le_control_tlv_length = -1;
64 static int hf_atm_lan_destination_route_desc = -1;
65 static int hf_atm_lan_destination_lan_id = -1;
66 static int hf_atm_lan_destination_bridge_num = -1;
67 static int hf_atm_source_atm = -1;
68 static int hf_atm_target_atm = -1;
69 static int hf_atm_le_configure_join_frame_lan_type = -1;
70 static int hf_atm_le_configure_join_frame_max_frame_size = -1;
71 static int hf_atm_le_configure_join_frame_num_tlvs = -1;
72 static int hf_atm_le_configure_join_frame_elan_name_size = -1;
73 static int hf_atm_le_configure_join_frame_elan_name = -1;
74 static int hf_atm_le_registration_frame_num_tlvs = -1;
75 static int hf_atm_le_arp_frame_num_tlvs = -1;
76 static int hf_atm_le_verify_frame_num_tlvs = -1;
77 static int hf_atm_le_control_marker = -1;
78 static int hf_atm_le_control_protocol = -1;
79 static int hf_atm_le_control_version = -1;
80 static int hf_atm_le_control_opcode = -1;
81 static int hf_atm_le_control_status = -1;
82 static int hf_atm_le_control_transaction_id = -1;
83 static int hf_atm_le_control_requester_lecid = -1;
84 static int hf_atm_le_control_flags = -1;
85 static int hf_atm_le_control_flag_v2_capable = -1;
86 static int hf_atm_le_control_flag_selective_multicast = -1;
87 static int hf_atm_le_control_flag_v2_required = -1;
88 static int hf_atm_le_control_flag_proxy = -1;
89 static int hf_atm_le_control_flag_exclude_explorer_frames = -1;
90 static int hf_atm_le_control_flag_address = -1;
91 static int hf_atm_le_control_topology_change = -1;
92 static int hf_atm_traffic_type = -1;
93 static int hf_atm_traffic_vcmx = -1;
94 static int hf_atm_traffic_lane = -1;
95 static int hf_atm_traffic_ipsilon = -1;
96 static int hf_atm_cells = -1;
97 static int hf_atm_aal5_uu = -1;
98 static int hf_atm_aal5_cpi = -1;
99 static int hf_atm_aal5_len = -1;
100 static int hf_atm_aal5_crc = -1;
101 static int hf_atm_payload_type = -1;
102 static int hf_atm_cell_loss_priority = -1;
103 static int hf_atm_header_error_check = -1;
104 static int hf_atm_channel = -1;
105 static int hf_atm_aa1_csi = -1;
106 static int hf_atm_aa1_seq_count = -1;
107 static int hf_atm_aa1_crc = -1;
108 static int hf_atm_aa1_parity = -1;
109 static int hf_atm_aa1_payload = -1;
110 static int hf_atm_aal3_4_seg_type = -1;
111 static int hf_atm_aal3_4_seq_num = -1;
112 static int hf_atm_aal3_4_multiplex_id = -1;
113 static int hf_atm_aal3_4_information = -1;
114 static int hf_atm_aal3_4_length_indicator = -1;
115 static int hf_atm_aal3_4_crc = -1;
116 static int hf_atm_aal_oamcell_type = -1;
117 static int hf_atm_aal_oamcell_type_fm = -1;
118 static int hf_atm_aal_oamcell_type_pm = -1;
119 static int hf_atm_aal_oamcell_type_ad = -1;
120 static int hf_atm_aal_oamcell_type_ft = -1;
121 static int hf_atm_aal_oamcell_func_spec = -1;
122 static int hf_atm_aal_oamcell_crc = -1;
123 static int hf_atm_padding = -1;
125 static gint ett_atm = -1;
126 static gint ett_atm_lane = -1;
127 static gint ett_atm_lane_lc_lan_dest = -1;
128 static gint ett_atm_lane_lc_lan_dest_rd = -1;
129 static gint ett_atm_lane_lc_flags = -1;
130 static gint ett_atm_lane_lc_tlv = -1;
131 static gint ett_ilmi = -1;
132 static gint ett_aal1 = -1;
133 static gint ett_aal3_4 = -1;
134 static gint ett_oamaal = -1;
136 static expert_field ei_atm_reassembly_failed = EI_INIT;
138 static dissector_handle_t atm_handle;
139 static dissector_handle_t atm_untruncated_handle;
141 static dissector_handle_t eth_withoutfcs_handle;
142 static dissector_handle_t tr_handle;
143 static dissector_handle_t fr_handle;
144 static dissector_handle_t llc_handle;
145 static dissector_handle_t sscop_handle;
146 static dissector_handle_t fp_handle;
147 static dissector_handle_t ppp_handle;
148 static dissector_handle_t eth_handle;
149 static dissector_handle_t ip_handle;
150 static dissector_handle_t data_handle;
151 static dissector_handle_t gprs_ns_handle;
153 static gboolean dissect_lanesscop = FALSE;
155 static dissector_table_t atm_type_aal2_table;
156 static dissector_table_t atm_type_aal5_table;
161 * http://www.atmforum.org/atmforum/specs/approved.html
163 * for a number of ATM Forum specifications, e.g. the LAN Emulation
164 * over ATM 1.0 spec, whence I got most of this.
167 /* LE Control opcodes */
168 #define LE_CONFIGURE_REQUEST 0x0001
169 #define LE_CONFIGURE_RESPONSE 0x0101
170 #define LE_JOIN_REQUEST 0x0002
171 #define LE_JOIN_RESPONSE 0x0102
172 #define READY_QUERY 0x0003
173 #define READY_IND 0x0103
174 #define LE_REGISTER_REQUEST 0x0004
175 #define LE_REGISTER_RESPONSE 0x0104
176 #define LE_UNREGISTER_REQUEST 0x0005
177 #define LE_UNREGISTER_RESPONSE 0x0105
178 #define LE_ARP_REQUEST 0x0006
179 #define LE_ARP_RESPONSE 0x0106
180 #define LE_FLUSH_REQUEST 0x0007
181 #define LE_FLUSH_RESPONSE 0x0107
182 #define LE_NARP_REQUEST 0x0008
183 #define LE_TOPOLOGY_REQUEST 0x0009
184 #define LE_VERIFY_REQUEST 0x000A
185 #define LE_VERIFY_RESPONSE 0x010A
187 static const value_string le_control_opcode_vals[] = {
188 { LE_CONFIGURE_REQUEST, "LE_CONFIGURE_REQUEST" },
189 { LE_CONFIGURE_RESPONSE, "LE_CONFIGURE_RESPONSE" },
190 { LE_JOIN_REQUEST, "LE_JOIN_REQUEST" },
191 { LE_JOIN_RESPONSE, "LE_JOIN_RESPONSE" },
192 { READY_QUERY, "READY_QUERY" },
193 { READY_IND, "READY_IND" },
194 { LE_REGISTER_REQUEST, "LE_REGISTER_REQUEST" },
195 { LE_REGISTER_RESPONSE, "LE_REGISTER_RESPONSE" },
196 { LE_UNREGISTER_REQUEST, "LE_UNREGISTER_REQUEST" },
197 { LE_UNREGISTER_RESPONSE, "LE_UNREGISTER_RESPONSE" },
198 { LE_ARP_REQUEST, "LE_ARP_REQUEST" },
199 { LE_ARP_RESPONSE, "LE_ARP_RESPONSE" },
200 { LE_FLUSH_REQUEST, "LE_FLUSH_REQUEST" },
201 { LE_FLUSH_RESPONSE, "LE_FLUSH_RESPONSE" },
202 { LE_NARP_REQUEST, "LE_NARP_REQUEST" },
203 { LE_TOPOLOGY_REQUEST, "LE_TOPOLOGY_REQUEST" },
204 { LE_VERIFY_REQUEST, "LE_VERIFY_REQUEST" },
205 { LE_VERIFY_RESPONSE, "LE_VERIFY_RESPONSE" },
209 /* LE Control statuses */
210 static const value_string le_control_status_vals[] = {
212 { 1, "Version not supported" },
213 { 2, "Invalid request parameters" },
214 { 4, "Duplicate LAN destination registration" },
215 { 5, "Duplicate ATM address" },
216 { 6, "Insufficient resources to grant request" },
217 { 7, "Access denied" },
218 { 8, "Invalid REQUESTOR-ID" },
219 { 9, "Invalid LAN destination" },
220 { 10, "Invalid ATM address" },
221 { 20, "No configuration" },
222 { 21, "LE_CONFIGURE error" },
223 { 22, "Insufficient information" },
224 { 24, "TLV not found" },
228 /* LE Control LAN destination tags */
229 #define TAG_NOT_PRESENT 0x0000
230 #define TAG_MAC_ADDRESS 0x0001
231 #define TAG_ROUTE_DESCRIPTOR 0x0002
233 static const value_string le_control_landest_tag_vals[] = {
234 { TAG_NOT_PRESENT, "Not present" },
235 { TAG_MAC_ADDRESS, "MAC address" },
236 { TAG_ROUTE_DESCRIPTOR, "Route descriptor" },
240 /* LE Control LAN types */
241 #define LANT_UNSPEC 0x00
242 #define LANT_802_3 0x01
243 #define LANT_802_5 0x02
245 static const value_string le_control_lan_type_vals[] = {
246 { LANT_UNSPEC, "Unspecified" },
247 { LANT_802_3, "Ethernet/802.3" },
248 { LANT_802_5, "802.5" },
252 static const value_string le_control_frame_size_vals[] = {
253 { 0x00, "Unspecified" },
254 { 0x01, "1516/1528/1580/1592" },
255 { 0x02, "4544/4556/1580/1592" },
256 { 0x03, "9234/9246" },
257 { 0x04, "18190/18202" },
261 static const value_string atm_channel_vals[] = {
267 static const true_false_string tfs_remote_local = { "Remote", "Local" };
268 static const true_false_string tfs_low_high_priority = { "Low priority", "High priority" };
272 dissect_le_client(tvbuff_t *tvb, proto_tree *tree)
275 proto_tree *lane_tree;
278 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, 0, 2, "ATM LANE");
279 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
281 proto_tree_add_item(lane_tree, hf_atm_le_client_client, tvb, 0, 2, ENC_BIG_ENDIAN );
286 dissect_lan_destination(tvbuff_t *tvb, int offset, const char *type, proto_tree *tree)
289 proto_tree *dest_tree;
293 dest_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
294 ett_atm_lane_lc_lan_dest, NULL, "%s LAN destination", type);
295 tag = tvb_get_ntohs(tvb, offset);
296 proto_tree_add_item(dest_tree, hf_atm_lan_destination_tag, tvb, offset, 2, ENC_BIG_ENDIAN );
301 case TAG_MAC_ADDRESS:
302 proto_tree_add_item(dest_tree, hf_atm_lan_destination_mac, tvb, offset, 6, ENC_NA);
305 case TAG_ROUTE_DESCRIPTOR:
307 td = proto_tree_add_item(dest_tree, hf_atm_lan_destination_route_desc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
308 rd_tree = proto_item_add_subtree(td, ett_atm_lane_lc_lan_dest_rd);
309 proto_tree_add_item(rd_tree, hf_atm_lan_destination_lan_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
310 proto_tree_add_item(rd_tree, hf_atm_lan_destination_bridge_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
316 * TLV values in LE Control frames.
318 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
320 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
321 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
322 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
323 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
324 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
325 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
326 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
327 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
328 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
329 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
330 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
331 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
332 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
333 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
334 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
335 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
336 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
337 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
338 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
339 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
340 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
341 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
343 static const value_string le_tlv_type_vals[] = {
344 { LE_CONTROL_TIMEOUT, "Control Time-out" },
345 { LE_MAX_UNK_FRAME_COUNT, "Maximum Unknown Frame Count" },
346 { LE_MAX_UNK_FRAME_TIME, "Maximum Unknown Frame Time" },
347 { LE_VCC_TIMEOUT_PERIOD, "VCC Time-out" },
348 { LE_MAX_RETRY_COUNT, "Maximum Retry Count" },
349 { LE_AGING_TIME, "Aging Time" },
350 { LE_FORWARD_DELAY_TIME, "Forwarding Delay Time" },
351 { LE_EXPECTED_ARP_RESPONSE_TIME, "Expected LE_ARP Response Time" },
352 { LE_FLUSH_TIMEOUT, "Flush Time-out" },
353 { LE_PATH_SWITCHING_DELAY, "Path Switching Delay" },
354 { LE_LOCAL_SEGMENT_ID, "Local Segment ID" },
355 { LE_MCAST_SEND_VCC_TYPE, "Mcast Send VCC Type" },
356 { LE_MCAST_SEND_VCC_AVGRATE, "Mcast Send VCC AvgRate" },
357 { LE_MCAST_SEND_VCC_PEAKRATE, "Mcast Send VCC PeakRate" },
358 { LE_CONN_COMPLETION_TIMER, "Connection Completion Timer" },
359 { LE_CONFIG_FRAG_INFO, "Config Frag Info" },
360 { LE_LAYER_3_ADDRESS, "Layer 3 Address" },
361 { LE_ELAN_ID, "ELAN ID" },
362 { LE_SERVICE_CATEGORY, "Service Category" },
363 { LE_LLC_MUXED_ATM_ADDRESS, "LLC-muxed ATM Address" },
364 { LE_X5_ADJUSTMENT, "X5 Adjustment" },
365 { LE_PREFERRED_LES, "Preferred LES" },
370 dissect_le_control_tlvs(tvbuff_t *tvb, int offset, guint num_tlvs,
375 proto_tree *tlv_tree;
377 while (num_tlvs != 0) {
378 tlv_type = tvb_get_ntohl(tvb, offset);
379 tlv_length = tvb_get_guint8(tvb, offset+4);
380 tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, 5+tlv_length, ett_atm_lane_lc_tlv, NULL,
381 "TLV type: %s", val_to_str(tlv_type, le_tlv_type_vals, "Unknown (0x%08x)"));
382 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_type, tvb, offset, 4, ENC_BIG_ENDIAN);
383 proto_tree_add_item(tlv_tree, hf_atm_le_control_tlv_length, tvb, offset+4, 1, ENC_BIG_ENDIAN);
384 offset += 5+tlv_length;
390 dissect_le_configure_join_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
395 dissect_lan_destination(tvb, offset, "Source", tree);
398 dissect_lan_destination(tvb, offset, "Target", tree);
401 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
404 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_lan_type, tvb, offset, 1, ENC_NA);
407 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_max_frame_size, tvb, offset, 1, ENC_NA);
410 num_tlvs = tvb_get_guint8(tvb, offset);
411 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_num_tlvs, tvb, offset, 1, ENC_NA);
414 name_size = tvb_get_guint8(tvb, offset);
415 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name_size, tvb, offset, 1, ENC_NA);
418 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
423 if (name_size != 0) {
424 proto_tree_add_item(tree, hf_atm_le_configure_join_frame_elan_name, tvb, offset, name_size, ENC_NA);
428 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
432 dissect_le_registration_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
436 dissect_lan_destination(tvb, offset, "Source", tree);
439 dissect_lan_destination(tvb, offset, "Target", tree);
442 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
445 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
448 num_tlvs = tvb_get_guint8(tvb, offset);
449 proto_tree_add_item(tree, hf_atm_le_registration_frame_num_tlvs, tvb, offset, 1, ENC_NA);
452 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 53, ENC_NA);
455 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
459 dissect_le_arp_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
463 dissect_lan_destination(tvb, offset, "Source", tree);
466 dissect_lan_destination(tvb, offset, "Target", tree);
469 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
472 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 2, ENC_NA);
475 num_tlvs = tvb_get_guint8(tvb, offset);
476 proto_tree_add_item(tree, hf_atm_le_arp_frame_num_tlvs, tvb, offset, 1, ENC_NA);
479 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
482 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
485 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
488 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
492 dissect_le_verify_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
496 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 38, ENC_NA);
499 num_tlvs = tvb_get_guint8(tvb, offset);
500 proto_tree_add_item(tree, hf_atm_le_verify_frame_num_tlvs, tvb, offset, 1, ENC_NA);
503 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 1, ENC_NA);
506 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
509 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
512 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
516 dissect_le_flush_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
518 dissect_lan_destination(tvb, offset, "Source", tree);
521 dissect_lan_destination(tvb, offset, "Target", tree);
524 proto_tree_add_item(tree, hf_atm_source_atm, tvb, offset, 20, ENC_NA);
527 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 4, ENC_NA);
530 proto_tree_add_item(tree, hf_atm_target_atm, tvb, offset, 20, ENC_NA);
533 proto_tree_add_item(tree, hf_atm_reserved, tvb, offset, 32, ENC_NA);
540 dissect_le_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
543 proto_tree *lane_tree = NULL;
546 proto_tree *flags_tree;
549 col_set_str(pinfo->cinfo, COL_INFO, "LE Control");
552 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, offset, 108, "ATM LANE");
553 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
555 proto_tree_add_item(lane_tree, hf_atm_le_control_marker, tvb, offset, 2, ENC_BIG_ENDIAN );
560 proto_tree_add_item(lane_tree, hf_atm_le_control_protocol, tvb, offset, 1, ENC_BIG_ENDIAN );
566 proto_tree_add_item(lane_tree, hf_atm_le_control_version, tvb, offset, 1, ENC_BIG_ENDIAN );
570 opcode = tvb_get_ntohs(tvb, offset);
571 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
572 val_to_str(opcode, le_control_opcode_vals,
573 "Unknown opcode (0x%04X)"));
576 proto_tree_add_item(lane_tree, hf_atm_le_control_opcode, tvb, offset, 2, ENC_BIG_ENDIAN );
580 if (opcode == READY_QUERY || opcode == READY_IND) {
581 /* There's nothing more in this packet. */
586 if (opcode & 0x0100) {
587 /* Response; decode status. */
588 proto_tree_add_item(lane_tree, hf_atm_le_control_status, tvb, offset, 2, ENC_BIG_ENDIAN );
592 proto_tree_add_item(lane_tree, hf_atm_le_control_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN );
595 proto_tree_add_item(lane_tree, hf_atm_le_control_requester_lecid, tvb, offset, 2, ENC_BIG_ENDIAN );
598 tf = proto_tree_add_item(lane_tree, hf_atm_le_control_flags, tvb, offset, 2, ENC_BIG_ENDIAN );
599 flags_tree = proto_item_add_subtree(tf, ett_atm_lane_lc_flags);
603 case LE_CONFIGURE_REQUEST:
604 case LE_CONFIGURE_RESPONSE:
605 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
607 dissect_le_configure_join_frame(tvb, offset, lane_tree);
610 case LE_JOIN_REQUEST:
611 case LE_JOIN_RESPONSE:
612 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_capable, tvb, offset, 2, ENC_BIG_ENDIAN);
613 if (opcode == LE_JOIN_REQUEST) {
614 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_selective_multicast, tvb, offset, 2, ENC_BIG_ENDIAN);
616 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_v2_required, tvb, offset, 2, ENC_BIG_ENDIAN);
619 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_proxy, tvb, offset, 2, ENC_BIG_ENDIAN);
620 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_exclude_explorer_frames, tvb, offset, 2, ENC_BIG_ENDIAN);
623 dissect_le_configure_join_frame(tvb, offset, lane_tree);
626 case LE_REGISTER_REQUEST:
627 case LE_REGISTER_RESPONSE:
628 case LE_UNREGISTER_REQUEST:
629 case LE_UNREGISTER_RESPONSE:
631 dissect_le_registration_frame(tvb, offset, lane_tree);
635 case LE_ARP_RESPONSE:
636 case LE_NARP_REQUEST:
637 if (opcode != LE_NARP_REQUEST) {
638 proto_tree_add_item(flags_tree, hf_atm_le_control_flag_address, tvb, offset, 2, ENC_BIG_ENDIAN);
641 dissect_le_arp_frame(tvb, offset, lane_tree);
644 case LE_TOPOLOGY_REQUEST:
645 proto_tree_add_item(flags_tree, hf_atm_le_control_topology_change, tvb, offset, 2, ENC_BIG_ENDIAN);
647 proto_tree_add_item(flags_tree, hf_atm_reserved, tvb, offset, 92, ENC_NA);
650 case LE_VERIFY_REQUEST:
651 case LE_VERIFY_RESPONSE:
653 dissect_le_verify_frame(tvb, offset, lane_tree);
656 case LE_FLUSH_REQUEST:
657 case LE_FLUSH_RESPONSE:
659 dissect_le_flush_frame(tvb, offset, lane_tree);
666 capture_lane(const union wtap_pseudo_header *pseudo_header, const guchar *pd,
667 int len, packet_counts *ld)
669 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
670 switch (pseudo_header->atm.subtype) {
672 case TRAF_ST_LANE_802_3:
673 case TRAF_ST_LANE_802_3_MC:
674 /* Dissect as Ethernet */
675 capture_eth(pd, 2, len, ld);
678 case TRAF_ST_LANE_802_5:
679 case TRAF_ST_LANE_802_5_MC:
680 /* Dissect as Token-Ring */
681 capture_tr(pd, 2, len, ld);
691 dissect_lane(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
694 tvbuff_t *next_tvb_le_client;
696 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM LANE");
698 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
699 switch (pinfo->pseudo_header->atm.subtype) {
701 case TRAF_ST_LANE_LE_CTRL:
702 dissect_le_control(tvb, pinfo, tree);
705 case TRAF_ST_LANE_802_3:
706 case TRAF_ST_LANE_802_3_MC:
707 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - Ethernet/802.3");
708 dissect_le_client(tvb, tree);
710 /* Dissect as Ethernet */
711 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
712 call_dissector(eth_withoutfcs_handle, next_tvb_le_client, pinfo, tree);
715 case TRAF_ST_LANE_802_5:
716 case TRAF_ST_LANE_802_5_MC:
717 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - 802.5");
718 dissect_le_client(tvb, tree);
720 /* Dissect as Token-Ring */
721 next_tvb_le_client = tvb_new_subset_remaining(tvb, 2);
722 call_dissector(tr_handle, next_tvb_le_client, pinfo, tree);
726 /* Dump it as raw data. */
727 col_set_str(pinfo->cinfo, COL_INFO, "Unknown LANE traffic type");
728 next_tvb = tvb_new_subset_remaining(tvb, 0);
729 call_dissector(data_handle,next_tvb, pinfo, tree);
735 dissect_ilmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
737 dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_ilmi, ett_ilmi, FALSE);
741 static const value_string aal_vals[] = {
742 { AAL_UNKNOWN, "Unknown AAL" },
745 { AAL_3_4, "AAL3/4" },
747 { AAL_USER, "User AAL" },
748 { AAL_SIGNALLING, "Signalling AAL" },
749 { AAL_OAMCELL, "OAM cell" },
753 /* AAL5 higher-level traffic types */
754 static const value_string aal5_hltype_vals[] = {
755 { TRAF_UNKNOWN, "Unknown traffic type" },
756 { TRAF_LLCMX, "LLC multiplexed" },
757 { TRAF_VCMX, "VC multiplexed" },
758 { TRAF_LANE, "LANE" },
759 { TRAF_ILMI, "ILMI" },
760 { TRAF_FR, "Frame Relay" },
761 { TRAF_SPANS, "FORE SPANS" },
762 { TRAF_IPSILON, "Ipsilon" },
763 { TRAF_GPRS_NS, "GPRS NS" },
764 { TRAF_SSCOP, "SSCOP" },
768 /* Traffic subtypes for VC multiplexed traffic */
769 static const value_string vcmx_type_vals[] = {
770 { TRAF_ST_UNKNOWN, "Unknown VC multiplexed traffic type" },
771 { TRAF_ST_VCMX_802_3_FCS, "802.3 FCS" },
772 { TRAF_ST_VCMX_802_4_FCS, "802.4 FCS" },
773 { TRAF_ST_VCMX_802_5_FCS, "802.5 FCS" },
774 { TRAF_ST_VCMX_FDDI_FCS, "FDDI FCS" },
775 { TRAF_ST_VCMX_802_6_FCS, "802.6 FCS" },
776 { TRAF_ST_VCMX_802_3, "802.3" },
777 { TRAF_ST_VCMX_802_4, "802.4" },
778 { TRAF_ST_VCMX_802_5, "802.5" },
779 { TRAF_ST_VCMX_FDDI, "FDDI" },
780 { TRAF_ST_VCMX_802_6, "802.6" },
781 { TRAF_ST_VCMX_FRAGMENTS, "Fragments" },
782 { TRAF_ST_VCMX_BPDU, "BPDU" },
786 /* Traffic subtypes for LANE traffic */
787 static const value_string lane_type_vals[] = {
788 { TRAF_ST_UNKNOWN, "Unknown LANE traffic type" },
789 { TRAF_ST_LANE_LE_CTRL, "LE Control" },
790 { TRAF_ST_LANE_802_3, "802.3" },
791 { TRAF_ST_LANE_802_5, "802.5" },
792 { TRAF_ST_LANE_802_3_MC, "802.3 multicast" },
793 { TRAF_ST_LANE_802_5_MC, "802.5 multicast" },
797 /* Traffic subtypes for Ipsilon traffic */
798 static const value_string ipsilon_type_vals[] = {
799 { TRAF_ST_UNKNOWN, "Unknown Ipsilon traffic type" },
800 { TRAF_ST_IPSILON_FT0, "Flow type 0" },
801 { TRAF_ST_IPSILON_FT1, "Flow type 1" },
802 { TRAF_ST_IPSILON_FT2, "Flow type 2" },
807 capture_atm(const union wtap_pseudo_header *pseudo_header, const guchar *pd,
808 int len, packet_counts *ld)
810 if (pseudo_header->atm.aal == AAL_5) {
811 switch (pseudo_header->atm.type) {
814 /* Dissect as WTAP_ENCAP_ATM_RFC1483 */
815 /* The ATM iptrace capture that we have shows LLC at this point,
816 * so that's what I'm calling */
817 capture_llc(pd, 0, len, ld);
821 capture_lane(pseudo_header, pd, len, ld);
833 dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
835 proto_tree *atm_tree, gboolean truncated, gboolean pseudowire_mode)
837 guint length, reported_length;
846 * This is reassembled traffic, so the cell headers are missing;
847 * show the traffic type for AAL5 traffic, and the VPI and VCI,
848 * from the pseudo-header.
850 if (pinfo->pseudo_header->atm.aal == AAL_5) {
851 proto_tree_add_uint(atm_tree, hf_atm_traffic_type, tvb, 0, 0, pinfo->pseudo_header->atm.type);
853 switch (pinfo->pseudo_header->atm.type) {
856 proto_tree_add_uint(atm_tree, hf_atm_traffic_vcmx, tvb, 0, 0, pinfo->pseudo_header->atm.subtype);
860 proto_tree_add_uint(atm_tree, hf_atm_traffic_lane, tvb, 0, 0, pinfo->pseudo_header->atm.subtype);
864 proto_tree_add_uint(atm_tree, hf_atm_traffic_ipsilon, tvb, 0, 0, pinfo->pseudo_header->atm.subtype);
868 if (!pseudowire_mode) {
869 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0,
870 pinfo->pseudo_header->atm.vpi);
871 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0,
872 pinfo->pseudo_header->atm.vci);
874 /* Also show vpi/vci in info column */
875 col_append_fstr(pinfo->cinfo, COL_INFO, " VPI=%u, VCI=%u",
876 pinfo->pseudo_header->atm.vpi,
877 pinfo->pseudo_header->atm.vci);
881 if (truncated || pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR) {
883 * The packet data does not include stuff such as the AAL5
884 * trailer, either because it was explicitly left out or because
887 if (pinfo->pseudo_header->atm.cells != 0) {
889 * If the cell count is 0, assume it means we don't know how
892 * XXX - also assume it means we don't know what was in the AAL5
893 * trailer. We may, however, find some capture program that can
894 * give us the AAL5 trailer information but not the cell count,
895 * in which case we need some other way of indicating whether we
896 * have the AAL5 trailer information.
899 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, pinfo->pseudo_header->atm.cells);
900 proto_tree_add_uint(atm_tree, hf_atm_aal5_uu, tvb, 0, 0, pinfo->pseudo_header->atm.aal5t_u2u >> 8);
901 proto_tree_add_uint(atm_tree, hf_atm_aal5_cpi, tvb, 0, 0, pinfo->pseudo_header->atm.aal5t_u2u & 0xFF);
902 proto_tree_add_uint(atm_tree, hf_atm_aal5_len, tvb, 0, 0, pinfo->pseudo_header->atm.aal5t_len);
903 proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, 0, 0, pinfo->pseudo_header->atm.aal5t_chksum);
908 * The packet data includes stuff such as the AAL5 trailer, if
909 * it wasn't cut off by the snapshot length, and ATM reassembly
911 * Decode the trailer, if present, and then chop it off.
913 length = tvb_captured_length(tvb);
914 reported_length = tvb_reported_length(tvb);
915 if ((reported_length % 48) == 0) {
917 * Reported length is a multiple of 48, so we can presumably
918 * divide it by 48 to get the number of cells.
920 proto_tree_add_uint(atm_tree, hf_atm_cells, tvb, 0, 0, reported_length/48);
922 if ((pinfo->pseudo_header->atm.aal == AAL_5 ||
923 pinfo->pseudo_header->atm.aal == AAL_SIGNALLING) &&
924 length >= reported_length) {
926 * XXX - what if the packet is truncated? Can that happen?
927 * What if you capture with Windows Sniffer on an ATM link
928 * and tell it not to save the entire packet? What happens
931 aal5_length = tvb_get_ntohs(tvb, length - 6);
934 * Check for sanity in the AAL5 length. It must be > 0
935 * and must be less than the amount of space left after
936 * we remove the trailer.
938 * If it's not sane, assume we don't have a trailer.
940 if (aal5_length > 0 && aal5_length <= length - 8) {
942 * How much padding is there?
944 pad_length = length - aal5_length - 8;
947 * There is no reason for more than 47 bytes of padding.
948 * The most padding you can have would be 7 bytes at the
949 * end of the next-to-last cell (8 bytes after the end of
950 * the data means you can fit the trailer in that cell),
951 * plus 40 bytes in the last cell (with the last 8 bytes
954 * If there's more than 47 bytes of padding, assume we don't
957 if (pad_length <= 47) {
961 if (pad_length > 0) {
962 proto_tree_add_item(atm_tree, hf_atm_padding, tvb, aal5_length, pad_length, ENC_NA);
965 proto_tree_add_item(atm_tree, hf_atm_aal5_uu, tvb, length - 8, 1, ENC_BIG_ENDIAN);
966 proto_tree_add_item(atm_tree, hf_atm_aal5_cpi, tvb, length - 7, 1, ENC_BIG_ENDIAN);
967 proto_tree_add_item(atm_tree, hf_atm_aal5_len, tvb, length - 6, 2, ENC_BIG_ENDIAN);
969 crc = tvb_get_ntohl(tvb, length - 4);
970 calc_crc = crc32_mpeg2_tvb(tvb, length);
971 ti = proto_tree_add_uint(atm_tree, hf_atm_aal5_crc, tvb, length - 4, 4, crc);
972 proto_item_append_text(ti, (calc_crc == 0xC704DD7B) ? " (correct)" : " (incorrect)");
974 next_tvb = tvb_new_subset_length(tvb, 0, aal5_length);
982 * Don't try to dissect the payload of PDUs with a reassembly
985 switch (pinfo->pseudo_header->atm.aal) {
988 if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) {
989 call_dissector(sscop_handle, next_tvb, pinfo, tree);
995 if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) {
996 if (dissector_try_uint(atm_type_aal5_table, pinfo->pseudo_header->atm.type, next_tvb, pinfo, tree))
1002 if (tvb_reported_length(next_tvb) > 7) /* sizeof(octet) */
1005 tvb_memcpy(next_tvb, octet, 0, sizeof(octet));
1007 if (octet[0] == 0xaa
1009 && octet[2] == 0x03) /* LLC SNAP as per RFC2684 */
1011 call_dissector(llc_handle, next_tvb, pinfo, tree);
1014 else if ((pntoh16(octet) & 0xff) == PPP_IP)
1016 call_dissector(ppp_handle, next_tvb, pinfo, tree);
1019 else if (pntoh16(octet) == 0x00)
1021 /* assume vc muxed bridged ethernet */
1022 proto_tree_add_item(tree, hf_atm_padding, tvb, 0, 2, ENC_NA);
1023 next_tvb = tvb_new_subset_remaining(tvb, 2);
1024 call_dissector(eth_handle, next_tvb, pinfo, tree);
1027 else if (octet[2] == 0x03 && /* NLPID */
1028 ((octet[3] == 0xcc || /* IPv4 */
1029 octet[3] == 0x8e) || /* IPv6 */
1030 (octet[3] == 0x00 && /* Eth */
1031 octet[4] == 0x80))) /* Eth */
1033 /* assume network interworking with FR 2 byte header */
1034 call_dissector(fr_handle, next_tvb, pinfo, tree);
1037 else if (octet[4] == 0x03 && /* NLPID */
1038 ((octet[5] == 0xcc || /* IPv4 */
1039 octet[5] == 0x8e) || /* IPv6 */
1040 (octet[5] == 0x00 && /* Eth */
1041 octet[6] == 0x80))) /* Eth */
1043 /* assume network interworking with FR 4 byte header */
1044 call_dissector(fr_handle, next_tvb, pinfo, tree);
1047 else if (((octet[0] & 0xf0)== 0x40) ||
1048 ((octet[0] & 0xf0) == 0x60))
1050 call_dissector(ip_handle, next_tvb, pinfo, tree);
1060 proto_tree_add_uint(atm_tree, hf_atm_cid, tvb, 0, 0,
1061 pinfo->pseudo_header->atm.aal2_cid);
1062 proto_item_append_text(atm_ti, " (vpi=%u vci=%u cid=%u)",
1063 pinfo->pseudo_header->atm.vpi,
1064 pinfo->pseudo_header->atm.vci,
1065 pinfo->pseudo_header->atm.aal2_cid);
1067 if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) {
1068 if (pinfo->pseudo_header->atm.flags & ATM_AAL2_NOPHDR) {
1071 /* Skip first 4 bytes of message
1075 Ignoring for now... */
1076 next_tvb = tvb_new_subset_remaining(tvb, 4);
1079 if (dissector_try_uint(atm_type_aal2_table, pinfo->pseudo_header->atm.type, next_tvb, pinfo, tree))
1087 /* Dump it as raw data. */
1092 /* Dump it as raw data. */
1093 call_dissector(data_handle, next_tvb, pinfo, tree);
1098 * Charles Michael Heard's HEC code, from
1100 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1102 * with the syndrome and error position tables initialized with values
1103 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1104 * rather than by calling those routines at run time, and with various data
1105 * type cleanups and changes not to correct the header if a correctible
1106 * error was detected.
1108 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1110 static const guint8 syndrome_table[256] = {
1111 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1112 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1113 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1114 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1115 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1116 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1117 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1118 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1119 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1120 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1121 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1122 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1123 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1124 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1125 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1126 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1127 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1128 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1129 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1130 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1131 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1132 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1133 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1134 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1135 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1136 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1137 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1138 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1139 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1140 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1141 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1142 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1145 #define NO_ERROR_DETECTED -128
1146 #define UNCORRECTIBLE_ERROR 128
1148 static const int err_posn_table[256] = {
1149 NO_ERROR_DETECTED, 39,
1150 38, UNCORRECTIBLE_ERROR,
1151 37, UNCORRECTIBLE_ERROR,
1152 UNCORRECTIBLE_ERROR, 31,
1153 36, UNCORRECTIBLE_ERROR,
1154 UNCORRECTIBLE_ERROR, 8,
1155 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1156 30, UNCORRECTIBLE_ERROR,
1157 35, UNCORRECTIBLE_ERROR,
1158 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1159 UNCORRECTIBLE_ERROR, 23,
1160 7, UNCORRECTIBLE_ERROR,
1161 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1162 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1163 29, UNCORRECTIBLE_ERROR,
1164 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1165 34, UNCORRECTIBLE_ERROR,
1166 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1167 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1168 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1169 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1170 22, UNCORRECTIBLE_ERROR,
1171 6, UNCORRECTIBLE_ERROR,
1172 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1173 UNCORRECTIBLE_ERROR, 0,
1174 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1175 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1176 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1177 28, UNCORRECTIBLE_ERROR,
1178 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1179 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1180 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1181 33, UNCORRECTIBLE_ERROR,
1182 UNCORRECTIBLE_ERROR, 10,
1183 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1184 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1185 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1186 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1187 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1188 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1189 UNCORRECTIBLE_ERROR, 12,
1190 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1191 21, UNCORRECTIBLE_ERROR,
1192 UNCORRECTIBLE_ERROR, 19,
1193 5, UNCORRECTIBLE_ERROR,
1194 UNCORRECTIBLE_ERROR, 17,
1195 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1196 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1197 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1198 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1199 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1200 UNCORRECTIBLE_ERROR, 3,
1201 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1202 UNCORRECTIBLE_ERROR, 15,
1203 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1204 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1205 27, UNCORRECTIBLE_ERROR,
1206 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1207 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1208 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1209 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1210 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1211 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1212 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1213 32, UNCORRECTIBLE_ERROR,
1214 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1215 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1216 9, UNCORRECTIBLE_ERROR,
1217 UNCORRECTIBLE_ERROR, 24,
1218 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1219 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1220 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1221 UNCORRECTIBLE_ERROR, 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, 1,
1227 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1228 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1229 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1230 11, UNCORRECTIBLE_ERROR,
1231 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1232 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1233 20, UNCORRECTIBLE_ERROR,
1234 UNCORRECTIBLE_ERROR, 13,
1235 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1236 18, UNCORRECTIBLE_ERROR,
1237 4, UNCORRECTIBLE_ERROR,
1238 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1239 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1240 16, 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, 25,
1249 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1250 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1251 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1252 2, UNCORRECTIBLE_ERROR,
1253 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1254 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1255 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1256 14, UNCORRECTIBLE_ERROR,
1257 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1258 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1259 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1260 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1261 26, UNCORRECTIBLE_ERROR,
1262 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1263 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1264 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1265 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1266 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1267 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1268 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1269 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1270 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1271 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1272 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1273 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1274 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1275 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1276 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1280 * Return an indication of whether there was an error in the cell header
1281 * and, if so, where the error was, if it was correctable.
1284 get_header_err(const guint8 *cell_header)
1286 register guint8 syndrome;
1287 register int i, err_posn;
1290 for (i = 0; i < 4; i++)
1291 syndrome = syndrome_table[syndrome ^ cell_header[i]];
1292 syndrome ^= cell_header[4] ^ COSET_LEADER;
1294 err_posn = err_posn_table [syndrome];
1297 return NO_ERROR_DETECTED;
1298 else if (err_posn < 40)
1301 return UNCORRECTIBLE_ERROR;
1304 const value_string atm_pt_vals[] = {
1305 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1306 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1307 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1308 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1309 { 4, "Segment OAM F5 flow related cell" },
1310 { 5, "End-to-end OAM F5 flow related cell" },
1311 { 6, "VC resource management cell" },
1315 static const value_string st_vals[] = {
1323 #define OAM_TYPE_FM 1 /* Fault Management */
1324 #define OAM_TYPE_PM 2 /* Performance Management */
1325 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1327 static const value_string oam_type_vals[] = {
1328 { OAM_TYPE_FM, "Fault Management" },
1329 { OAM_TYPE_PM, "Performance Management" },
1330 { OAM_TYPE_AD, "Activation/Deactivation" },
1334 static const value_string ft_fm_vals[] = {
1335 { 0, "Alarm Indication Signal" },
1336 { 1, "Far End Receive Failure" },
1337 { 8, "OAM Cell Loopback" },
1338 { 4, "Continuity Check" },
1342 static const value_string ft_pm_vals[] = {
1343 { 0, "Forward Monitoring" },
1344 { 1, "Backward Reporting" },
1345 { 2, "Monitoring and Reporting" },
1349 static const value_string ft_ad_vals[] = {
1350 { 0, "Performance Monitoring" },
1351 { 1, "Continuity Check" },
1357 dissect_atm_cell_payload(tvbuff_t *tvb, int offset, packet_info *pinfo,
1358 proto_tree *tree, guint aal,
1359 const pwatm_private_data_t *pwpd)
1361 proto_tree *aal_tree;
1365 guint16 aal3_4_hdr, crc10;
1371 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL1");
1372 col_clear(pinfo->cinfo, COL_INFO);
1373 ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, ENC_NA);
1374 aal_tree = proto_item_add_subtree(ti, ett_aal1);
1375 octet = tvb_get_guint8(tvb, offset);
1377 proto_tree_add_item(aal_tree, hf_atm_aa1_csi, tvb, offset, 1, ENC_BIG_ENDIAN);
1378 proto_tree_add_item(aal_tree, hf_atm_aa1_seq_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1379 col_add_fstr(pinfo->cinfo, COL_INFO, "Sequence count = %u",
1380 (octet >> 4) & 0x7);
1381 proto_tree_add_item(aal_tree, hf_atm_aa1_crc, tvb, offset, 1, ENC_BIG_ENDIAN);
1382 proto_tree_add_item(aal_tree, hf_atm_aa1_parity, tvb, offset, 1, ENC_BIG_ENDIAN);
1385 proto_tree_add_item(aal_tree, hf_atm_aa1_payload, tvb, offset, 47, ENC_NA);
1390 * XXX - or should this be the CS PDU?
1392 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL3/4");
1393 col_clear(pinfo->cinfo, COL_INFO);
1394 ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, ENC_NA);
1395 aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
1396 aal3_4_hdr = tvb_get_ntohs(tvb, offset);
1397 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, sequence number = %u",
1398 val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"),
1399 (aal3_4_hdr >> 10) & 0xF);
1400 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1401 proto_tree_add_item(aal_tree, hf_atm_aal3_4_seq_num, tvb, offset, 2, ENC_BIG_ENDIAN);
1402 proto_tree_add_item(aal_tree, hf_atm_aal3_4_multiplex_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1404 length = tvb_reported_length_remaining(tvb, offset);
1405 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1408 proto_tree_add_item(aal_tree, hf_atm_aal3_4_information, tvb, offset, 44, ENC_NA);
1411 proto_tree_add_item(aal_tree, hf_atm_aal3_4_length_indicator, tvb, offset, 2, ENC_BIG_ENDIAN);
1412 ti = proto_tree_add_item(aal_tree, hf_atm_aal3_4_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1413 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1417 if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
1419 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
1420 col_clear(pinfo->cinfo, COL_INFO);
1422 ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, ENC_NA);
1423 aal_tree = proto_item_add_subtree(ti, ett_oamaal);
1424 octet = tvb_get_guint8(tvb, offset);
1425 if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
1427 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
1428 val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
1431 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1432 switch (octet >> 4) {
1435 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_fm, tvb, offset, 1, ENC_BIG_ENDIAN);
1439 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_pm, tvb, offset, 1, ENC_BIG_ENDIAN);
1443 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ad, tvb, offset, 1, ENC_BIG_ENDIAN);
1447 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_type_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
1450 length = tvb_reported_length_remaining(tvb, offset);
1451 crc10 = update_crc10_by_bytes_tvb(0, tvb, offset, length);
1454 proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_func_spec, tvb, offset, 45, ENC_NA);
1457 ti = proto_tree_add_item(aal_tree, hf_atm_aal_oamcell_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1458 proto_item_append_text(ti, " (%s)", (crc10 == 0) ? " (correct)" : " (incorrect)");
1462 next_tvb = tvb_new_subset_remaining(tvb, offset);
1463 call_dissector(data_handle, next_tvb, pinfo, tree);
1469 * Check for OAM cells.
1470 * OAM F4 is VCI 3 or 4 and PT 0X0.
1474 atm_is_oam_cell(const guint16 vci, const guint8 pt)
1476 return (((vci == 3 || vci == 4) && ((pt & 0x5) == 0))
1477 || ((pt & 0x6) == 0x4));
1482 dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1483 proto_tree *atm_tree, guint aal, gboolean nni,
1484 gboolean crc_stripped)
1494 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1495 * and encoding at UNI reference point as:
1510 octet = tvb_get_guint8(tvb, 0);
1511 proto_tree_add_item(atm_tree, hf_atm_gfc, tvb, 0, 1, ENC_NA);
1512 vpi = (octet & 0xF) << 4;
1513 octet = tvb_get_guint8(tvb, 1);
1515 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1518 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1519 * and encoding at NNI reference point as:
1534 octet = tvb_get_guint8(tvb, 0);
1536 octet = tvb_get_guint8(tvb, 1);
1537 vpi |= (octet & 0xF0) >> 4;
1538 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1541 vci = (octet & 0x0F) << 12;
1542 octet = tvb_get_guint8(tvb, 2);
1544 octet = tvb_get_guint8(tvb, 3);
1546 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 1, 3, vci);
1547 pt = (octet >> 1) & 0x7;
1548 proto_tree_add_item(atm_tree, hf_atm_payload_type, tvb, 3, 1, ENC_BIG_ENDIAN);
1549 proto_tree_add_item(atm_tree, hf_atm_cell_loss_priority, tvb, 3, 1, ENC_BIG_ENDIAN);
1551 if (!crc_stripped) {
1553 * FF: parse the Header Error Check (HEC).
1555 ti = proto_tree_add_item(atm_tree, hf_atm_header_error_check, tvb, 4, 1, ENC_BIG_ENDIAN);
1556 err = get_header_err(tvb_get_ptr(tvb, 0, 5));
1557 if (err == NO_ERROR_DETECTED)
1558 proto_item_append_text(ti, " (correct)");
1559 else if (err == UNCORRECTIBLE_ERROR)
1560 proto_item_append_text(ti, " (uncorrectable error)");
1562 proto_item_append_text(ti, " (error in bit %d)", err);
1566 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1567 * Cell Mode) the Header Error Check (HEC) field is stripped.
1568 * So we do nothing here.
1574 * Check for OAM cells.
1575 * XXX - do this for all AAL values, overriding whatever information
1576 * Wiretap got from the file?
1578 if (aal == AAL_USER || aal == AAL_UNKNOWN) {
1579 if (atm_is_oam_cell(vci,pt)) {
1584 dissect_atm_cell_payload(tvb, offset, pinfo, tree, aal, NULL);
1588 dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1589 gboolean truncated, const pwatm_private_data_t *pwpd)
1591 proto_tree *atm_tree = NULL;
1592 proto_item *atm_ti = NULL;
1593 gboolean pseudowire_mode = (NULL != pwpd);
1595 if ( pinfo->pseudo_header->atm.aal == AAL_5 &&
1596 pinfo->pseudo_header->atm.type == TRAF_LANE &&
1597 dissect_lanesscop ) {
1598 pinfo->pseudo_header->atm.aal = AAL_SIGNALLING;
1601 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1603 if (!pseudowire_mode) {
1604 switch (pinfo->pseudo_header->atm.channel) {
1607 /* Traffic from DTE to DCE. */
1608 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
1609 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
1613 /* Traffic from DCE to DTE. */
1614 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
1615 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
1620 if (pinfo->pseudo_header->atm.aal == AAL_5) {
1621 col_add_fstr(pinfo->cinfo, COL_INFO, "AAL5 %s",
1622 val_to_str(pinfo->pseudo_header->atm.type, aal5_hltype_vals,
1623 "Unknown traffic type (%u)"));
1625 col_add_str(pinfo->cinfo, COL_INFO,
1626 val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
1627 "Unknown AAL (%u)"));
1631 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, -1, ENC_NA);
1632 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1634 if (!pseudowire_mode) {
1635 proto_tree_add_uint(atm_tree, hf_atm_channel, tvb, 0, 0, pinfo->pseudo_header->atm.channel);
1636 if (pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)
1637 expert_add_info(pinfo, atm_ti, &ei_atm_reassembly_failed);
1640 proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0,
1641 pinfo->pseudo_header->atm.aal,
1643 val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
1644 "Unknown AAL (%u)"));
1646 if (pinfo->pseudo_header->atm.flags & ATM_RAW_CELL) {
1647 /* This is a single cell, with the cell header at the beginning. */
1648 if (pinfo->pseudo_header->atm.flags & ATM_NO_HEC) {
1649 proto_item_set_len(atm_ti, 4);
1651 proto_item_set_len(atm_ti, 5);
1653 dissect_atm_cell(tvb, pinfo, tree, atm_tree,
1654 pinfo->pseudo_header->atm.aal, FALSE,
1655 pinfo->pseudo_header->atm.flags & ATM_NO_HEC);
1657 /* This is a reassembled PDU. */
1660 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
1661 * In such cases, the dissector data parameter is used to pass info from/to
1662 * PW dissector to ATM dissector. For decoding normal ATM traffic
1663 * data parameter should be NULL.
1665 dissect_reassembled_pdu(tvb, pinfo, tree, atm_tree, atm_ti, truncated, pwpd != NULL);
1668 return tvb_reported_length(tvb);
1672 dissect_atm_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1674 return dissect_atm_common(tvb, pinfo, tree, TRUE, NULL);
1678 dissect_atm_pw_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1680 const pwatm_private_data_t *pwpd = (const pwatm_private_data_t *)data;
1682 return dissect_atm_common(tvb, pinfo, tree, TRUE, pwpd);
1686 dissect_atm_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1688 return dissect_atm_common(tvb, pinfo, tree, FALSE, NULL);
1692 dissect_atm_pw_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1694 const pwatm_private_data_t *pwpd = (const pwatm_private_data_t *)data;
1696 return dissect_atm_common(tvb, pinfo, tree, FALSE, pwpd);
1700 dissect_atm_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1702 proto_tree *atm_tree;
1705 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1707 atm_ti = proto_tree_add_item(tree, proto_atm, tvb, 0, 0, ENC_NA);
1708 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1710 dissect_atm_cell(tvb, pinfo, tree, atm_tree, AAL_OAMCELL, FALSE, FALSE);
1711 return tvb_reported_length(tvb);
1715 dissect_atm_pw_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1717 const pwatm_private_data_t *pwpd = (const pwatm_private_data_t *)data;
1719 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1721 dissect_atm_cell_payload(tvb, 0, pinfo, tree, AAL_OAMCELL, pwpd);
1723 return tvb_reported_length(tvb);
1726 static void atm_prompt(packet_info *pinfo _U_, gchar* result)
1728 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode AAL2 traffic as");
1731 static gpointer atm_value(packet_info *pinfo)
1733 return GUINT_TO_POINTER((guint)pinfo->pseudo_header->atm.type);
1737 proto_register_atm(void)
1739 static hf_register_info hf[] = {
1741 { "AAL", "atm.aal", FT_UINT8, BASE_DEC, VALS(aal_vals), 0x0,
1744 { "GFC", "atm.GFC", FT_UINT8, BASE_DEC, NULL, 0xF0,
1747 { "VPI", "atm.vpi", FT_UINT8, BASE_DEC, NULL, 0x0,
1751 { "VCI", "atm.vci", FT_UINT16, BASE_DEC, NULL, 0x0,
1755 { "CID", "atm.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
1759 { "Reserved", "atm.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
1762 { &hf_atm_le_client_client,
1763 { "LE Client", "atm.le_client.client", FT_UINT16, BASE_HEX, NULL, 0x0,
1765 { &hf_atm_lan_destination_tag,
1766 { "Tag", "atm.lan_destination.tag", FT_UINT16, BASE_HEX, VALS(le_control_landest_tag_vals), 0x0,
1768 { &hf_atm_lan_destination_mac,
1769 { "MAC address", "atm.lan_destination.mac", FT_ETHER, BASE_NONE, NULL, 0x0,
1771 { &hf_atm_le_control_tlv_type,
1772 { "TLV Type", "atm.le_control.tlv_type", FT_UINT32, BASE_HEX, VALS(le_tlv_type_vals), 0x0,
1774 { &hf_atm_le_control_tlv_length,
1775 { "TLV Length", "atm.le_control.tlv_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1777 { &hf_atm_lan_destination_route_desc,
1778 { "Route descriptor", "atm.lan_destination.route_desc", FT_UINT16, BASE_HEX, NULL, 0x0,
1780 { &hf_atm_lan_destination_lan_id,
1781 { "LAN ID", "atm.lan_destination.lan_id", FT_UINT16, BASE_DEC, NULL, 0xFFF0,
1783 { &hf_atm_lan_destination_bridge_num,
1784 { "Bridge number", "atm.lan_destination.bridge_num", FT_UINT16, BASE_DEC, NULL, 0x000F,
1786 { &hf_atm_source_atm,
1787 { "Source ATM address", "atm.source_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1789 { &hf_atm_target_atm,
1790 { "Target ATM address", "atm.target_atm", FT_BYTES, BASE_NONE, NULL, 0x0,
1792 { &hf_atm_le_configure_join_frame_lan_type,
1793 { "LAN type", "atm.le_configure_join_frame.lan_type", FT_UINT8, BASE_HEX, VALS(le_control_lan_type_vals), 0x0,
1795 { &hf_atm_le_configure_join_frame_max_frame_size,
1796 { "Maximum frame size", "atm.le_configure_join_frame.max_frame_size", FT_UINT8, BASE_HEX, VALS(le_control_frame_size_vals), 0x0,
1798 { &hf_atm_le_configure_join_frame_num_tlvs,
1799 { "Number of TLVs", "atm.le_configure_join_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1801 { &hf_atm_le_configure_join_frame_elan_name_size,
1802 { "ELAN name size", "atm.le_configure_join_frame.elan_name_size", FT_UINT8, BASE_DEC, NULL, 0x0,
1804 { &hf_atm_le_registration_frame_num_tlvs,
1805 { "Number of TLVs", "atm.le_registration_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1807 { &hf_atm_le_arp_frame_num_tlvs,
1808 { "Number of TLVs", "atm.le_arp_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1810 { &hf_atm_le_verify_frame_num_tlvs,
1811 { "Number of TLVs", "atm.le_verify_frame.num_tlvs", FT_UINT8, BASE_DEC, NULL, 0x0,
1813 { &hf_atm_le_configure_join_frame_elan_name,
1814 { "ELAN name", "atm.le_configure_join_frame.elan_name", FT_BYTES, BASE_NONE, NULL, 0x0,
1816 { &hf_atm_le_control_marker,
1817 { "Marker", "atm.le_control.marker", FT_UINT16, BASE_HEX, NULL, 0x0,
1819 { &hf_atm_le_control_protocol,
1820 { "Protocol", "atm.le_control.protocol", FT_UINT8, BASE_HEX, NULL, 0x0,
1822 { &hf_atm_le_control_version,
1823 { "Version", "atm.le_control.version", FT_UINT8, BASE_HEX, NULL, 0x0,
1825 { &hf_atm_le_control_opcode,
1826 { "Opcode", "atm.le_control.opcode", FT_UINT16, BASE_HEX, VALS(le_control_opcode_vals), 0x0,
1828 { &hf_atm_le_control_status,
1829 { "Status", "atm.le_control.status", FT_UINT16, BASE_HEX, VALS(le_control_status_vals), 0x0,
1831 { &hf_atm_le_control_transaction_id,
1832 { "Transaction ID", "atm.le_control.transaction_id", FT_UINT32, BASE_HEX, NULL, 0x0,
1834 { &hf_atm_le_control_requester_lecid,
1835 { "Requester LECID", "atm.le_control.requester_lecid", FT_UINT16, BASE_HEX, NULL, 0x0,
1837 { &hf_atm_le_control_flags,
1838 { "Flags", "atm.le_control.flag", FT_UINT16, BASE_HEX, NULL, 0x0,
1840 { &hf_atm_le_control_flag_v2_capable,
1841 { "V2 capable", "atm.le_control.flag.v2_capable", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002,
1843 { &hf_atm_le_control_flag_selective_multicast,
1844 { "Selective multicast", "atm.le_control.flag.selective_multicast", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004,
1846 { &hf_atm_le_control_flag_v2_required,
1847 { "V2 required", "atm.le_control.flag.v2_required", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008,
1849 { &hf_atm_le_control_flag_proxy,
1850 { "Proxy", "atm.le_control.flag.flag_proxy", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0080,
1852 { &hf_atm_le_control_flag_exclude_explorer_frames,
1853 { "Exclude explorer frames", "atm.le_control.flag.exclude_explorer_frames", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0200,
1855 { &hf_atm_le_control_flag_address,
1856 { "Address", "atm.le_control.flag.address", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001,
1858 { &hf_atm_le_control_topology_change,
1859 { "Topology change", "atm.le_control.flag.topology_change", FT_BOOLEAN, 16, TFS(&tfs_remote_local), 0x0100,
1861 { &hf_atm_traffic_type,
1862 { "Traffic type", "atm.traffic_type", FT_UINT8, BASE_DEC, VALS(aal5_hltype_vals), 0x0,
1864 { &hf_atm_traffic_vcmx,
1865 { "VC multiplexed traffic type", "atm.traffic.vcmx", FT_UINT8, BASE_DEC, VALS(vcmx_type_vals), 0x0,
1867 { &hf_atm_traffic_lane,
1868 { "LANE traffic type", "atm.traffic.lane", FT_UINT8, BASE_DEC, VALS(lane_type_vals), 0x0,
1870 { &hf_atm_traffic_ipsilon,
1871 { "Ipsilon traffic type", "atm.traffic.ipsilon", FT_UINT8, BASE_DEC, VALS(ipsilon_type_vals), 0x0,
1874 { "Cells", "atm.cells", FT_UINT16, BASE_DEC, NULL, 0x0,
1877 { "AAL5 UU", "atm.hf_atm.aal5t_uu", FT_UINT8, BASE_HEX, NULL, 0x0,
1880 { "AAL5 CPI", "atm.hf_atm.aal5t_cpi", FT_UINT8, BASE_HEX, NULL, 0x0,
1883 { "AAL5 len", "atm.aal5t_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1886 { "AAL5 CRC", "atm.aal5t_crc", FT_UINT32, BASE_HEX, NULL, 0x0,
1888 { &hf_atm_payload_type,
1889 { "Payload Type", "atm.payload_type", FT_UINT8, BASE_DEC, NULL, 0x0E,
1891 { &hf_atm_cell_loss_priority,
1892 { "Cell Loss Priority", "atm.cell_loss_priority", FT_BOOLEAN, 8, TFS(&tfs_low_high_priority), 0x01,
1894 { &hf_atm_header_error_check,
1895 { "Header Error Check", "atm.header_error_check", FT_UINT8, BASE_HEX, NULL, 0,
1898 { "Channel", "atm.channel", FT_UINT16, BASE_DEC, VALS(atm_channel_vals), 0,
1901 { "CSI", "atm.aa1.csi", FT_UINT8, BASE_DEC, NULL, 0x80,
1903 { &hf_atm_aa1_seq_count,
1904 { "Sequence Count", "atm.aa1.seq_count", FT_UINT8, BASE_DEC, NULL, 0x70,
1907 { "CRC", "atm.aa1.crc", FT_UINT8, BASE_DEC, NULL, 0x08,
1909 { &hf_atm_aa1_parity,
1910 { "Parity", "atm.aa1.parity", FT_UINT8, BASE_DEC, NULL, 0x07,
1912 { &hf_atm_aa1_payload,
1913 { "Payload", "atm.aa1.payload", FT_BYTES, BASE_NONE, NULL, 0x0,
1915 { &hf_atm_aal3_4_seg_type,
1916 { "Segment Type", "atm.aal3_4.seg_type", FT_UINT16, BASE_DEC, VALS(st_vals), 0xC000,
1918 { &hf_atm_aal3_4_seq_num,
1919 { "Sequence Number", "atm.aal3_4.seq_num", FT_UINT16, BASE_DEC, NULL, 0x3C00,
1921 { &hf_atm_aal3_4_multiplex_id,
1922 { "Multiplex ID", "atm.aal3_4.multiplex_id", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1924 { &hf_atm_aal3_4_information,
1925 { "Information", "atm.aal3_4.information", FT_BYTES, BASE_NONE, NULL, 0x0,
1927 { &hf_atm_aal3_4_length_indicator,
1928 { "Length Indicator", "atm.aal3_4.length_indicator", FT_UINT16, BASE_DEC, VALS(st_vals), 0xFC00,
1930 { &hf_atm_aal3_4_crc,
1931 { "CRC", "atm.aal3_4.crc", FT_UINT16, BASE_DEC, NULL, 0x03FF,
1933 { &hf_atm_aal_oamcell_type,
1934 { "OAM Type", "atm.aal_oamcell.type", FT_UINT8, BASE_DEC, VALS(oam_type_vals), 0xF0,
1936 { &hf_atm_aal_oamcell_type_fm,
1937 { "Function Type", "atm.aal_oamcell.type.fm", FT_UINT8, BASE_DEC, VALS(ft_fm_vals), 0x0F,
1939 { &hf_atm_aal_oamcell_type_pm,
1940 { "Function Type", "atm.aal_oamcell.type.pm", FT_UINT8, BASE_DEC, VALS(ft_pm_vals), 0x0F,
1942 { &hf_atm_aal_oamcell_type_ad,
1943 { "Function Type", "atm.aal_oamcell.type.ad", FT_UINT8, BASE_DEC, VALS(ft_ad_vals), 0x0F,
1945 { &hf_atm_aal_oamcell_type_ft,
1946 { "Function Type", "atm.aal_oamcell.type.ft", FT_UINT8, BASE_DEC, NULL, 0x0F,
1948 { &hf_atm_aal_oamcell_func_spec,
1949 { "Function-specific information", "atm.aal_oamcell.func_spec", FT_BYTES, BASE_NONE, NULL, 0x0,
1951 { &hf_atm_aal_oamcell_crc,
1952 { "CRC-10", "atm.aal_oamcell.crc", FT_UINT16, BASE_HEX, NULL, 0x3FF,
1955 { "Padding", "atm.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
1960 static gint *ett[] = {
1967 &ett_atm_lane_lc_lan_dest,
1968 &ett_atm_lane_lc_lan_dest_rd,
1969 &ett_atm_lane_lc_flags,
1970 &ett_atm_lane_lc_tlv,
1973 static ei_register_info ei[] = {
1974 { &ei_atm_reassembly_failed, { "atm.reassembly_failed", PI_REASSEMBLE, PI_ERROR, "PDU reassembly failed", EXPFILL }},
1977 expert_module_t* expert_atm;
1978 module_t *atm_module;
1980 /* Decode As handling */
1981 static build_valid_func atm_da_build_value[1] = {atm_value};
1982 static decode_as_value_t atm_da_values = {atm_prompt, 1, atm_da_build_value};
1983 static decode_as_t atm_da = {"atm", "Network", "atm.aal2.type", 1, 0, &atm_da_values, NULL, NULL,
1984 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
1986 proto_atm = proto_register_protocol("Asynchronous Transfer Mode", "ATM", "atm");
1987 proto_aal1 = proto_register_protocol("ATM AAL1", "AAL1", "aal1");
1988 proto_aal3_4 = proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
1989 proto_oamaal = proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
1990 proto_register_field_array(proto_atm, hf, array_length(hf));
1991 proto_register_subtree_array(ett, array_length(ett));
1992 expert_atm = expert_register_protocol(proto_atm);
1993 expert_register_field_array(expert_atm, ei, array_length(ei));
1995 proto_ilmi = proto_register_protocol("ILMI", "ILMI", "ilmi");
1997 proto_atm_lane = proto_register_protocol("ATM LAN Emulation", "ATM LANE", "lane");
1999 atm_type_aal2_table = register_dissector_table("atm.aal2.type", "ATM AAL_2 type subdissector", FT_UINT32, BASE_DEC);
2000 atm_type_aal5_table = register_dissector_table("atm.aal5.type", "ATM AAL_5 type subdissector", FT_UINT32, BASE_DEC);
2002 atm_handle = new_register_dissector("atm_truncated", dissect_atm_truncated, proto_atm);
2003 new_register_dissector("atm_pw_truncated", dissect_atm_pw_truncated, proto_atm);
2004 atm_untruncated_handle = new_register_dissector("atm_untruncated", dissect_atm_untruncated, proto_atm);
2005 new_register_dissector("atm_pw_untruncated", dissect_atm_pw_untruncated, proto_atm);
2006 new_register_dissector("atm_oam_cell", dissect_atm_oam_cell, proto_oamaal);
2007 new_register_dissector("atm_pw_oam_cell", dissect_atm_pw_oam_cell, proto_oamaal);
2009 atm_module = prefs_register_protocol ( proto_atm, NULL );
2010 prefs_register_bool_preference(atm_module, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
2011 "Autodection between LANE and SSCOP is hard. As default LANE is preferred",
2012 &dissect_lanesscop);
2013 prefs_register_obsolete_preference(atm_module, "unknown_aal2_type");
2015 register_decode_as(&atm_da);
2019 proto_reg_handoff_atm(void)
2022 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
2023 * SSCOP, LANE, and ILMI dissectors.
2025 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
2026 tr_handle = find_dissector("tr");
2027 fr_handle = find_dissector("fr");
2028 llc_handle = find_dissector("llc");
2029 sscop_handle = find_dissector("sscop");
2030 ppp_handle = find_dissector("ppp");
2031 eth_handle = find_dissector("eth");
2032 ip_handle = find_dissector("ip");
2033 data_handle = find_dissector("data");
2034 fp_handle = find_dissector("fp");
2035 gprs_ns_handle = find_dissector("gprs_ns");
2037 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_handle);
2038 dissector_add_uint("atm.aal5.type", TRAF_LANE, create_dissector_handle(dissect_lane, proto_atm_lane));
2039 dissector_add_uint("atm.aal5.type", TRAF_ILMI, create_dissector_handle(dissect_ilmi, proto_ilmi));
2041 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,
2042 atm_untruncated_handle);
2046 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2051 * indent-tabs-mode: nil
2054 * ex: set shiftwidth=2 tabstop=8 expandtab:
2055 * :indentSize=2:tabSize=8:noTabs=true: