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