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