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