2 * Routines for ATM packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <wsutil/pint.h>
31 #include <epan/addr_resolv.h>
32 #include <epan/ppptypes.h>
34 #include "packet-atm.h"
35 #include "packet-snmp.h"
36 #include "packet-eth.h"
37 #include "packet-tr.h"
38 #include "packet-llc.h"
39 #include <epan/prefs.h>
40 #include "packet-pw-atm.h"
42 void proto_register_atm(void);
43 void proto_reg_handoff_atm(void);
45 static int proto_atm
= -1;
46 static int hf_atm_aal
= -1;
47 static int hf_atm_vpi
= -1;
48 static int hf_atm_vci
= -1;
49 static int hf_atm_cid
= -1;
50 static int proto_atm_lane
= -1;
51 static int proto_ilmi
= -1;
52 static int proto_aal1
= -1;
53 static int proto_aal3_4
= -1;
54 static int proto_oamaal
= -1;
56 static int hf_atm_le_client_client
= -1;
57 static int hf_atm_lan_destination_tag
= -1;
58 static int hf_atm_lan_destination_mac
= -1;
59 static int hf_atm_le_control_tlv_type
= -1;
60 static int hf_atm_le_control_tlv_length
= -1;
61 static int hf_atm_lan_destination_route_desc
= -1;
62 static int hf_atm_lan_destination_lan_id
= -1;
63 static int hf_atm_lan_destination_bridge_num
= -1;
64 static int hf_atm_source_atm
= -1;
65 static int hf_atm_target_atm
= -1;
66 static int hf_atm_le_configure_join_frame_lan_type
= -1;
67 static int hf_atm_le_configure_join_frame_max_frame_size
= -1;
68 static int hf_atm_le_configure_join_frame_num_tlvs
= -1;
69 static int hf_atm_le_configure_join_frame_elan_name_size
= -1;
70 static int hf_atm_le_configure_join_frame_elan_name
= -1;
71 static int hf_atm_le_registration_frame_num_tlvs
= -1;
72 static int hf_atm_le_arp_frame_num_tlvs
= -1;
73 static int hf_atm_le_verify_frame_num_tlvs
= -1;
74 static int hf_atm_le_control_marker
= -1;
75 static int hf_atm_le_control_protocol
= -1;
76 static int hf_atm_le_control_version
= -1;
77 static int hf_atm_le_control_opcode
= -1;
78 static int hf_atm_le_control_status
= -1;
79 static int hf_atm_le_control_transaction_id
= -1;
80 static int hf_atm_le_control_requester_lecid
= -1;
81 static int hf_atm_le_control_flags
= -1;
82 static int hf_atm_le_control_flag_v2_capable
= -1;
83 static int hf_atm_le_control_flag_selective_multicast
= -1;
84 static int hf_atm_le_control_flag_v2_required
= -1;
85 static int hf_atm_le_control_flag_proxy
= -1;
86 static int hf_atm_le_control_flag_exclude_explorer_frames
= -1;
87 static int hf_atm_le_control_flag_address
= -1;
88 static int hf_atm_le_control_topology_change
= -1;
89 static int hf_atm_traffic_type
= -1;
90 static int hf_atm_traffic_vcmx
= -1;
91 static int hf_atm_traffic_lane
= -1;
92 static int hf_atm_traffic_ipsilon
= -1;
93 static int hf_atm_cells
= -1;
94 static int hf_atm_aal5_uu
= -1;
95 static int hf_atm_aal5_cpi
= -1;
96 static int hf_atm_aal5_len
= -1;
97 static int hf_atm_aal5_crc
= -1;
98 static int hf_atm_payload_type
= -1;
99 static int hf_atm_cell_loss_priority
= -1;
100 static int hf_atm_header_error_check
= -1;
101 static int hf_atm_channel
= -1;
102 static int hf_atm_aa1_csi
= -1;
103 static int hf_atm_aa1_seq_count
= -1;
104 static int hf_atm_aa1_crc
= -1;
105 static int hf_atm_aa1_parity
= -1;
106 static int hf_atm_aa1_payload
= -1;
107 static int hf_atm_aal3_4_seg_type
= -1;
108 static int hf_atm_aal3_4_seq_num
= -1;
109 static int hf_atm_aal3_4_multiplex_id
= -1;
110 static int hf_atm_aal3_4_information
= -1;
111 static int hf_atm_aal3_4_length_indicator
= -1;
112 static int hf_atm_aal3_4_crc
= -1;
113 static int hf_atm_aal_oamcell_type
= -1;
114 static int hf_atm_aal_oamcell_type_fm
= -1;
115 static int hf_atm_aal_oamcell_type_pm
= -1;
116 static int hf_atm_aal_oamcell_type_ad
= -1;
117 static int hf_atm_aal_oamcell_type_ft
= -1;
118 static int hf_atm_aal_oamcell_func_spec
= -1;
119 static int hf_atm_aal_oamcell_crc
= -1;
121 static gint ett_atm
= -1;
122 static gint ett_atm_lane
= -1;
123 static gint ett_atm_lane_lc_lan_dest
= -1;
124 static gint ett_atm_lane_lc_lan_dest_rd
= -1;
125 static gint ett_atm_lane_lc_flags
= -1;
126 static gint ett_atm_lane_lc_tlv
= -1;
127 static gint ett_ilmi
= -1;
128 static gint ett_aal1
= -1;
129 static gint ett_aal3_4
= -1;
130 static gint ett_oamaal
= -1;
132 static dissector_handle_t atm_handle
;
133 static dissector_handle_t atm_untruncated_handle
;
135 static dissector_handle_t eth_withoutfcs_handle
;
136 static dissector_handle_t tr_handle
;
137 static dissector_handle_t fr_handle
;
138 static dissector_handle_t llc_handle
;
139 static dissector_handle_t sscop_handle
;
140 static dissector_handle_t lane_handle
;
141 static dissector_handle_t ilmi_handle
;
142 static dissector_handle_t fp_handle
;
143 static dissector_handle_t ppp_handle
;
144 static dissector_handle_t eth_handle
;
145 static dissector_handle_t ip_handle
;
146 static dissector_handle_t data_handle
;
147 static dissector_handle_t gprs_ns_handle
;
149 static gboolean dissect_lanesscop
= FALSE
;
151 static gint unknown_aal2_type
= TRAF_UNKNOWN
;
156 * http://www.atmforum.org/atmforum/specs/approved.html
158 * for a number of ATM Forum specifications, e.g. the LAN Emulation
159 * over ATM 1.0 spec, whence I got most of this.
162 /* LE Control opcodes */
163 #define LE_CONFIGURE_REQUEST 0x0001
164 #define LE_CONFIGURE_RESPONSE 0x0101
165 #define LE_JOIN_REQUEST 0x0002
166 #define LE_JOIN_RESPONSE 0x0102
167 #define READY_QUERY 0x0003
168 #define READY_IND 0x0103
169 #define LE_REGISTER_REQUEST 0x0004
170 #define LE_REGISTER_RESPONSE 0x0104
171 #define LE_UNREGISTER_REQUEST 0x0005
172 #define LE_UNREGISTER_RESPONSE 0x0105
173 #define LE_ARP_REQUEST 0x0006
174 #define LE_ARP_RESPONSE 0x0106
175 #define LE_FLUSH_REQUEST 0x0007
176 #define LE_FLUSH_RESPONSE 0x0107
177 #define LE_NARP_REQUEST 0x0008
178 #define LE_TOPOLOGY_REQUEST 0x0009
179 #define LE_VERIFY_REQUEST 0x000A
180 #define LE_VERIFY_RESPONSE 0x010A
182 static const value_string le_control_opcode_vals
[] = {
183 { LE_CONFIGURE_REQUEST
, "LE_CONFIGURE_REQUEST" },
184 { LE_CONFIGURE_RESPONSE
, "LE_CONFIGURE_RESPONSE" },
185 { LE_JOIN_REQUEST
, "LE_JOIN_REQUEST" },
186 { LE_JOIN_RESPONSE
, "LE_JOIN_RESPONSE" },
187 { READY_QUERY
, "READY_QUERY" },
188 { READY_IND
, "READY_IND" },
189 { LE_REGISTER_REQUEST
, "LE_REGISTER_REQUEST" },
190 { LE_REGISTER_RESPONSE
, "LE_REGISTER_RESPONSE" },
191 { LE_UNREGISTER_REQUEST
, "LE_UNREGISTER_REQUEST" },
192 { LE_UNREGISTER_RESPONSE
, "LE_UNREGISTER_RESPONSE" },
193 { LE_ARP_REQUEST
, "LE_ARP_REQUEST" },
194 { LE_ARP_RESPONSE
, "LE_ARP_RESPONSE" },
195 { LE_FLUSH_REQUEST
, "LE_FLUSH_REQUEST" },
196 { LE_FLUSH_RESPONSE
, "LE_FLUSH_RESPONSE" },
197 { LE_NARP_REQUEST
, "LE_NARP_REQUEST" },
198 { LE_TOPOLOGY_REQUEST
, "LE_TOPOLOGY_REQUEST" },
199 { LE_VERIFY_REQUEST
, "LE_VERIFY_REQUEST" },
200 { LE_VERIFY_RESPONSE
, "LE_VERIFY_RESPONSE" },
204 /* LE Control statuses */
205 static const value_string le_control_status_vals
[] = {
207 { 1, "Version not supported" },
208 { 2, "Invalid request parameters" },
209 { 4, "Duplicate LAN destination registration" },
210 { 5, "Duplicate ATM address" },
211 { 6, "Insufficient resources to grant request" },
212 { 7, "Access denied" },
213 { 8, "Invalid REQUESTOR-ID" },
214 { 9, "Invalid LAN destination" },
215 { 10, "Invalid ATM address" },
216 { 20, "No configuration" },
217 { 21, "LE_CONFIGURE error" },
218 { 22, "Insufficient information" },
219 { 24, "TLV not found" },
223 /* LE Control LAN destination tags */
224 #define TAG_NOT_PRESENT 0x0000
225 #define TAG_MAC_ADDRESS 0x0001
226 #define TAG_ROUTE_DESCRIPTOR 0x0002
228 static const value_string le_control_landest_tag_vals
[] = {
229 { TAG_NOT_PRESENT
, "Not present" },
230 { TAG_MAC_ADDRESS
, "MAC address" },
231 { TAG_ROUTE_DESCRIPTOR
, "Route descriptor" },
235 /* LE Control LAN types */
236 #define LANT_UNSPEC 0x00
237 #define LANT_802_3 0x01
238 #define LANT_802_5 0x02
240 static const value_string le_control_lan_type_vals
[] = {
241 { LANT_UNSPEC
, "Unspecified" },
242 { LANT_802_3
, "Ethernet/802.3" },
243 { LANT_802_5
, "802.5" },
247 static const value_string le_control_frame_size_vals
[] = {
248 { 0x00, "Unspecified" },
249 { 0x01, "1516/1528/1580/1592" },
250 { 0x02, "4544/4556/1580/1592" },
251 { 0x03, "9234/9246" },
252 { 0x04, "18190/18202" },
256 static const value_string atm_channel_vals
[] = {
262 static const true_false_string tfs_remote_local
= { "Remote", "Local" };
263 static const true_false_string tfs_low_high_priority
= { "Low priority", "High priority" };
267 dissect_le_client(tvbuff_t
*tvb
, proto_tree
*tree
)
270 proto_tree
*lane_tree
;
273 ti
= proto_tree_add_protocol_format(tree
, proto_atm_lane
, tvb
, 0, 2, "ATM LANE");
274 lane_tree
= proto_item_add_subtree(ti
, ett_atm_lane
);
276 proto_tree_add_item(lane_tree
, hf_atm_le_client_client
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
281 dissect_lan_destination(tvbuff_t
*tvb
, int offset
, const char *type
, proto_tree
*tree
)
284 proto_tree
*dest_tree
;
288 td
= proto_tree_add_text(tree
, tvb
, offset
, 8, "%s LAN destination",
290 dest_tree
= proto_item_add_subtree(td
, ett_atm_lane_lc_lan_dest
);
291 tag
= tvb_get_ntohs(tvb
, offset
);
292 proto_tree_add_item(dest_tree
, hf_atm_lan_destination_tag
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
297 case TAG_MAC_ADDRESS
:
298 proto_tree_add_item(dest_tree
, hf_atm_lan_destination_mac
, tvb
, offset
, 6, ENC_NA
);
301 case TAG_ROUTE_DESCRIPTOR
:
303 proto_tree_add_item(dest_tree
, hf_atm_lan_destination_route_desc
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
304 rd_tree
= proto_item_add_subtree(td
, ett_atm_lane_lc_lan_dest_rd
);
305 proto_tree_add_item(rd_tree
, hf_atm_lan_destination_lan_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
306 proto_tree_add_item(rd_tree
, hf_atm_lan_destination_bridge_num
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
312 * TLV values in LE Control frames.
314 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
316 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
317 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
318 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
319 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
320 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
321 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
322 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
323 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
324 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
325 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
326 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
327 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
328 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
329 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
330 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
331 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
332 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
333 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
334 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
335 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
336 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
337 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
339 static const value_string le_tlv_type_vals
[] = {
340 { LE_CONTROL_TIMEOUT
, "Control Time-out" },
341 { LE_MAX_UNK_FRAME_COUNT
, "Maximum Unknown Frame Count" },
342 { LE_MAX_UNK_FRAME_TIME
, "Maximum Unknown Frame Time" },
343 { LE_VCC_TIMEOUT_PERIOD
, "VCC Time-out" },
344 { LE_MAX_RETRY_COUNT
, "Maximum Retry Count" },
345 { LE_AGING_TIME
, "Aging Time" },
346 { LE_FORWARD_DELAY_TIME
, "Forwarding Delay Time" },
347 { LE_EXPECTED_ARP_RESPONSE_TIME
, "Expected LE_ARP Response Time" },
348 { LE_FLUSH_TIMEOUT
, "Flush Time-out" },
349 { LE_PATH_SWITCHING_DELAY
, "Path Switching Delay" },
350 { LE_LOCAL_SEGMENT_ID
, "Local Segment ID" },
351 { LE_MCAST_SEND_VCC_TYPE
, "Mcast Send VCC Type" },
352 { LE_MCAST_SEND_VCC_AVGRATE
, "Mcast Send VCC AvgRate" },
353 { LE_MCAST_SEND_VCC_PEAKRATE
, "Mcast Send VCC PeakRate" },
354 { LE_CONN_COMPLETION_TIMER
, "Connection Completion Timer" },
355 { LE_CONFIG_FRAG_INFO
, "Config Frag Info" },
356 { LE_LAYER_3_ADDRESS
, "Layer 3 Address" },
357 { LE_ELAN_ID
, "ELAN ID" },
358 { LE_SERVICE_CATEGORY
, "Service Category" },
359 { LE_LLC_MUXED_ATM_ADDRESS
, "LLC-muxed ATM Address" },
360 { LE_X5_ADJUSTMENT
, "X5 Adjustment" },
361 { LE_PREFERRED_LES
, "Preferred LES" },
366 dissect_le_control_tlvs(tvbuff_t
*tvb
, int offset
, guint num_tlvs
,
372 proto_tree
*tlv_tree
;
374 while (num_tlvs
!= 0) {
375 tlv_type
= tvb_get_ntohl(tvb
, offset
);
376 tlv_length
= tvb_get_guint8(tvb
, offset
+4);
377 ttlv
= proto_tree_add_text(tree
, tvb
, offset
, 5+tlv_length
, "TLV type: %s",
378 val_to_str(tlv_type
, le_tlv_type_vals
, "Unknown (0x%08x)"));
379 tlv_tree
= proto_item_add_subtree(ttlv
, ett_atm_lane_lc_tlv
);
380 proto_tree_add_item(tlv_tree
, hf_atm_le_control_tlv_type
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
381 proto_tree_add_item(tlv_tree
, hf_atm_le_control_tlv_length
, tvb
, offset
+4, 1, ENC_BIG_ENDIAN
);
382 offset
+= 5+tlv_length
;
388 dissect_le_configure_join_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
393 dissect_lan_destination(tvb
, offset
, "Source", tree
);
396 dissect_lan_destination(tvb
, offset
, "Target", tree
);
399 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
402 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_lan_type
, tvb
, offset
, 1, ENC_NA
);
405 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_max_frame_size
, tvb
, offset
, 1, ENC_NA
);
408 num_tlvs
= tvb_get_guint8(tvb
, offset
);
409 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
412 name_size
= tvb_get_guint8(tvb
, offset
);
413 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_elan_name_size
, tvb
, offset
, 1, ENC_NA
);
416 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
421 if (name_size
!= 0) {
422 proto_tree_add_item(tree
, hf_atm_le_configure_join_frame_elan_name
, tvb
, offset
, name_size
, ENC_NA
);
426 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
430 dissect_le_registration_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
434 dissect_lan_destination(tvb
, offset
, "Source", tree
);
437 dissect_lan_destination(tvb
, offset
, "Target", tree
);
440 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
446 num_tlvs
= tvb_get_guint8(tvb
, offset
);
447 proto_tree_add_item(tree
, hf_atm_le_registration_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
453 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
457 dissect_le_arp_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
461 dissect_lan_destination(tvb
, offset
, "Source", tree
);
464 dissect_lan_destination(tvb
, offset
, "Target", tree
);
467 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
473 num_tlvs
= tvb_get_guint8(tvb
, offset
);
474 proto_tree_add_item(tree
, hf_atm_le_arp_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
480 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
486 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
490 dissect_le_verify_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
497 num_tlvs
= tvb_get_guint8(tvb
, offset
);
498 proto_tree_add_item(tree
, hf_atm_le_verify_frame_num_tlvs
, tvb
, offset
, 1, ENC_NA
);
504 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
510 dissect_le_control_tlvs(tvb
, offset
, num_tlvs
, tree
);
514 dissect_le_flush_frame(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
516 dissect_lan_destination(tvb
, offset
, "Source", tree
);
519 dissect_lan_destination(tvb
, offset
, "Target", tree
);
522 proto_tree_add_item(tree
, hf_atm_source_atm
, tvb
, offset
, 20, ENC_NA
);
528 proto_tree_add_item(tree
, hf_atm_target_atm
, tvb
, offset
, 20, ENC_NA
);
538 dissect_le_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
541 proto_tree
*lane_tree
= NULL
;
544 proto_tree
*flags_tree
;
547 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Control");
550 ti
= proto_tree_add_protocol_format(tree
, proto_atm_lane
, tvb
, offset
, 108, "ATM LANE");
551 lane_tree
= proto_item_add_subtree(ti
, ett_atm_lane
);
553 proto_tree_add_item(lane_tree
, hf_atm_le_control_marker
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
558 proto_tree_add_item(lane_tree
, hf_atm_le_control_protocol
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
564 proto_tree_add_item(lane_tree
, hf_atm_le_control_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
568 opcode
= tvb_get_ntohs(tvb
, offset
);
569 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ": %s",
570 val_to_str(opcode
, le_control_opcode_vals
,
571 "Unknown opcode (0x%04X)"));
574 proto_tree_add_item(lane_tree
, hf_atm_le_control_opcode
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
578 if (opcode
== READY_QUERY
|| opcode
== READY_IND
) {
579 /* There's nothing more in this packet. */
584 if (opcode
& 0x0100) {
585 /* Response; decode status. */
586 proto_tree_add_item(lane_tree
, hf_atm_le_control_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
590 proto_tree_add_item(lane_tree
, hf_atm_le_control_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
593 proto_tree_add_item(lane_tree
, hf_atm_le_control_requester_lecid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
596 tf
= proto_tree_add_item(lane_tree
, hf_atm_le_control_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
597 flags_tree
= proto_item_add_subtree(tf
, ett_atm_lane_lc_flags
);
601 case LE_CONFIGURE_REQUEST
:
602 case LE_CONFIGURE_RESPONSE
:
603 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_capable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
605 dissect_le_configure_join_frame(tvb
, offset
, lane_tree
);
608 case LE_JOIN_REQUEST
:
609 case LE_JOIN_RESPONSE
:
610 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_capable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
611 if (opcode
== LE_JOIN_REQUEST
) {
612 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_selective_multicast
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
614 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_v2_required
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
617 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_proxy
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
618 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_exclude_explorer_frames
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
621 dissect_le_configure_join_frame(tvb
, offset
, lane_tree
);
624 case LE_REGISTER_REQUEST
:
625 case LE_REGISTER_RESPONSE
:
626 case LE_UNREGISTER_REQUEST
:
627 case LE_UNREGISTER_RESPONSE
:
629 dissect_le_registration_frame(tvb
, offset
, lane_tree
);
633 case LE_ARP_RESPONSE
:
634 case LE_NARP_REQUEST
:
635 if (opcode
!= LE_NARP_REQUEST
) {
636 proto_tree_add_item(flags_tree
, hf_atm_le_control_flag_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
639 dissect_le_arp_frame(tvb
, offset
, lane_tree
);
642 case LE_TOPOLOGY_REQUEST
:
643 proto_tree_add_item(flags_tree
, hf_atm_le_control_topology_change
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
644 /* 92 reserved bytes */
647 case LE_VERIFY_REQUEST
:
648 case LE_VERIFY_RESPONSE
:
650 dissect_le_verify_frame(tvb
, offset
, lane_tree
);
653 case LE_FLUSH_REQUEST
:
654 case LE_FLUSH_RESPONSE
:
656 dissect_le_flush_frame(tvb
, offset
, lane_tree
);
663 capture_lane(const union wtap_pseudo_header
*pseudo_header
, const guchar
*pd
,
664 int len
, packet_counts
*ld
)
666 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
667 switch (pseudo_header
->atm
.subtype
) {
669 case TRAF_ST_LANE_802_3
:
670 case TRAF_ST_LANE_802_3_MC
:
671 /* Dissect as Ethernet */
672 capture_eth(pd
, 2, len
, ld
);
675 case TRAF_ST_LANE_802_5
:
676 case TRAF_ST_LANE_802_5_MC
:
677 /* Dissect as Token-Ring */
678 capture_tr(pd
, 2, len
, ld
);
688 dissect_lane(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
691 tvbuff_t
*next_tvb_le_client
;
693 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM LANE");
695 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
696 switch (pinfo
->pseudo_header
->atm
.subtype
) {
698 case TRAF_ST_LANE_LE_CTRL
:
699 dissect_le_control(tvb
, pinfo
, tree
);
702 case TRAF_ST_LANE_802_3
:
703 case TRAF_ST_LANE_802_3_MC
:
704 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Client - Ethernet/802.3");
705 dissect_le_client(tvb
, tree
);
707 /* Dissect as Ethernet */
708 next_tvb_le_client
= tvb_new_subset_remaining(tvb
, 2);
709 call_dissector(eth_withoutfcs_handle
, next_tvb_le_client
, pinfo
, tree
);
712 case TRAF_ST_LANE_802_5
:
713 case TRAF_ST_LANE_802_5_MC
:
714 col_set_str(pinfo
->cinfo
, COL_INFO
, "LE Client - 802.5");
715 dissect_le_client(tvb
, tree
);
717 /* Dissect as Token-Ring */
718 next_tvb_le_client
= tvb_new_subset_remaining(tvb
, 2);
719 call_dissector(tr_handle
, next_tvb_le_client
, pinfo
, tree
);
723 /* Dump it as raw data. */
724 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unknown LANE traffic type");
725 next_tvb
= tvb_new_subset_remaining(tvb
, 0);
726 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
732 dissect_ilmi(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
734 dissect_snmp_pdu(tvb
, 0, pinfo
, tree
, proto_ilmi
, ett_ilmi
, FALSE
);
738 static const value_string aal_vals
[] = {
739 { AAL_UNKNOWN
, "Unknown AAL" },
742 { AAL_3_4
, "AAL3/4" },
744 { AAL_USER
, "User AAL" },
745 { AAL_SIGNALLING
, "Signalling AAL" },
746 { AAL_OAMCELL
, "OAM cell" },
750 /* AAL5 higher-level traffic types */
751 static const value_string aal5_hltype_vals
[] = {
752 { TRAF_UNKNOWN
, "Unknown traffic type" },
753 { TRAF_LLCMX
, "LLC multiplexed" },
754 { TRAF_VCMX
, "VC multiplexed" },
755 { TRAF_LANE
, "LANE" },
756 { TRAF_ILMI
, "ILMI" },
757 { TRAF_FR
, "Frame Relay" },
758 { TRAF_SPANS
, "FORE SPANS" },
759 { TRAF_IPSILON
, "Ipsilon" },
760 { TRAF_GPRS_NS
, "GPRS NS" },
761 { TRAF_SSCOP
, "SSCOP" },
765 /* Traffic subtypes for VC multiplexed traffic */
766 static const value_string vcmx_type_vals
[] = {
767 { TRAF_ST_UNKNOWN
, "Unknown VC multiplexed traffic type" },
768 { TRAF_ST_VCMX_802_3_FCS
, "802.3 FCS" },
769 { TRAF_ST_VCMX_802_4_FCS
, "802.4 FCS" },
770 { TRAF_ST_VCMX_802_5_FCS
, "802.5 FCS" },
771 { TRAF_ST_VCMX_FDDI_FCS
, "FDDI FCS" },
772 { TRAF_ST_VCMX_802_6_FCS
, "802.6 FCS" },
773 { TRAF_ST_VCMX_802_3
, "802.3" },
774 { TRAF_ST_VCMX_802_4
, "802.4" },
775 { TRAF_ST_VCMX_802_5
, "802.5" },
776 { TRAF_ST_VCMX_FDDI
, "FDDI" },
777 { TRAF_ST_VCMX_802_6
, "802.6" },
778 { TRAF_ST_VCMX_FRAGMENTS
, "Fragments" },
779 { TRAF_ST_VCMX_BPDU
, "BPDU" },
783 /* Traffic subtypes for LANE traffic */
784 static const value_string lane_type_vals
[] = {
785 { TRAF_ST_UNKNOWN
, "Unknown LANE traffic type" },
786 { TRAF_ST_LANE_LE_CTRL
, "LE Control" },
787 { TRAF_ST_LANE_802_3
, "802.3" },
788 { TRAF_ST_LANE_802_5
, "802.5" },
789 { TRAF_ST_LANE_802_3_MC
, "802.3 multicast" },
790 { TRAF_ST_LANE_802_5_MC
, "802.5 multicast" },
794 /* Traffic subtypes for Ipsilon traffic */
795 static const value_string ipsilon_type_vals
[] = {
796 { TRAF_ST_UNKNOWN
, "Unknown Ipsilon traffic type" },
797 { TRAF_ST_IPSILON_FT0
, "Flow type 0" },
798 { TRAF_ST_IPSILON_FT1
, "Flow type 1" },
799 { TRAF_ST_IPSILON_FT2
, "Flow type 2" },
804 capture_atm(const union wtap_pseudo_header
*pseudo_header
, const guchar
*pd
,
805 int len
, packet_counts
*ld
)
807 if (pseudo_header
->atm
.aal
== AAL_5
) {
808 switch (pseudo_header
->atm
.type
) {
811 /* Dissect as WTAP_ENCAP_ATM_RFC1483 */
812 /* The ATM iptrace capture that we have shows LLC at this point,
813 * so that's what I'm calling */
814 capture_llc(pd
, 0, len
, ld
);
818 capture_lane(pseudo_header
, pd
, len
, ld
);
830 * Charles Michael Heard's CRC-32 code, from
832 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.c.html
834 * with the CRC table initialized with values computed by
835 * his "gen_crc_table()" routine, rather than by calling that routine
836 * at run time, and with various data type cleanups.
839 /* crc32h.c -- package to compute 32-bit CRC one byte at a time using */
840 /* the high-bit first (Big-Endian) bit ordering convention */
843 /* gen_crc_table() -- generates a 256-word table containing all CRC */
844 /* remainders for every possible 8-bit byte. It */
845 /* must be executed (once) before any CRC updates. */
847 /* unsigned update_crc(crc_accum, data_blk_ptr, data_blk_size) */
848 /* unsigned crc_accum; char *data_blk_ptr; int data_blk_size; */
849 /* Returns the updated value of the CRC accumulator after */
850 /* processing each byte in the addressed block of data. */
852 /* It is assumed that an unsigned long is at least 32 bits wide and */
853 /* that the predefined type char occupies one 8-bit byte of storage. */
855 /* The generator polynomial used for this version of the package is */
856 /* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 */
857 /* as specified in the Autodin/Ethernet/ADCCP protocol standards. */
858 /* Other degree 32 polynomials may be substituted by re-defining the */
859 /* symbol POLYNOMIAL below. Lower degree polynomials must first be */
860 /* multiplied by an appropriate power of x. The representation used */
861 /* is that the coefficient of x^0 is stored in the LSB of the 32-bit */
862 /* word and the coefficient of x^31 is stored in the most significant */
863 /* bit. The CRC is to be appended to the data most significant byte */
864 /* first. For those protocols in which bytes are transmitted MSB */
865 /* first and in the same order as they are encountered in the block */
866 /* this convention results in the CRC remainder being transmitted with */
867 /* the coefficient of x^31 first and with that of x^0 last (just as */
868 /* would be done by a hardware shift register mechanization). */
870 /* The table lookup technique was adapted from the algorithm described */
871 /* by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).*/
873 static const guint32 crc_table
[256] = {
874 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
875 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
876 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
877 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
878 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
879 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
880 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
881 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
882 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
883 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
884 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
885 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
886 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
887 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
888 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
889 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
890 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
891 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
892 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
893 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
894 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
895 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
896 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
897 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
898 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
899 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
900 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
901 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
902 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
903 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
904 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
905 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
906 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
907 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
908 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
909 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
910 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
911 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
912 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
913 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
914 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
915 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
916 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
917 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
918 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
919 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
920 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
921 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
922 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
923 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
924 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
925 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
926 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
927 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
928 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
929 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
930 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
931 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
932 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
933 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
934 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
935 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
936 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
937 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
941 update_crc(guint32 crc_accum
, const guint8
*data_blk_ptr
, int data_blk_size
)
945 /* update the CRC on the data block one byte at a time */
946 for (j
= 0; j
< data_blk_size
; j
++) {
947 i
= ( (int) ( crc_accum
>> 24) ^ *data_blk_ptr
++ ) & 0xff;
948 crc_accum
= ( crc_accum
<< 8 ) ^ crc_table
[i
];
954 dissect_reassembled_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
956 proto_tree
*atm_tree
, gboolean truncated
, gboolean pseudowire_mode
)
958 guint length
, reported_length
;
967 * This is reassembled traffic, so the cell headers are missing;
968 * show the traffic type for AAL5 traffic, and the VPI and VCI,
969 * from the pseudo-header.
971 if (pinfo
->pseudo_header
->atm
.aal
== AAL_5
) {
972 proto_tree_add_uint(atm_tree
, hf_atm_traffic_type
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.type
);
974 switch (pinfo
->pseudo_header
->atm
.type
) {
977 proto_tree_add_uint(atm_tree
, hf_atm_traffic_vcmx
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.subtype
);
981 proto_tree_add_uint(atm_tree
, hf_atm_traffic_lane
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.subtype
);
985 proto_tree_add_uint(atm_tree
, hf_atm_traffic_ipsilon
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.subtype
);
989 if (!pseudowire_mode
) {
990 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 0,
991 pinfo
->pseudo_header
->atm
.vpi
);
992 proto_tree_add_uint(atm_tree
, hf_atm_vci
, tvb
, 0, 0,
993 pinfo
->pseudo_header
->atm
.vci
);
995 /* Also show vpi/vci in info column */
996 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " VPI=%u, VCI=%u",
997 pinfo
->pseudo_header
->atm
.vpi
,
998 pinfo
->pseudo_header
->atm
.vci
);
1004 * The packet data does not include stuff such as the AAL5
1007 if (pinfo
->pseudo_header
->atm
.cells
!= 0) {
1009 * If the cell count is 0, assume it means we don't know how
1010 * many cells it was.
1012 * XXX - also assume it means we don't know what was in the AAL5
1013 * trailer. We may, however, find some capture program that can
1014 * give us the AAL5 trailer information but not the cell count,
1015 * in which case we need some other way of indicating whether we
1016 * have the AAL5 trailer information.
1019 proto_tree_add_uint(atm_tree
, hf_atm_cells
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.cells
);
1020 proto_tree_add_uint(atm_tree
, hf_atm_aal5_uu
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.aal5t_u2u
>> 8);
1021 proto_tree_add_uint(atm_tree
, hf_atm_aal5_cpi
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.aal5t_u2u
& 0xFF);
1022 proto_tree_add_uint(atm_tree
, hf_atm_aal5_len
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.aal5t_len
);
1023 proto_tree_add_uint(atm_tree
, hf_atm_aal5_crc
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.aal5t_chksum
);
1028 * The packet data includes stuff such as the AAL5 trailer, if
1029 * it wasn't cut off by the snapshot length.
1030 * Decode the trailer, if present, and then chop it off.
1032 length
= tvb_length(tvb
);
1033 reported_length
= tvb_reported_length(tvb
);
1034 if ((reported_length
% 48) == 0) {
1036 * Reported length is a multiple of 48, so we can presumably
1037 * divide it by 48 to get the number of cells.
1039 proto_tree_add_uint(atm_tree
, hf_atm_cells
, tvb
, 0, 0, reported_length
/48);
1041 if ((pinfo
->pseudo_header
->atm
.aal
== AAL_5
||
1042 pinfo
->pseudo_header
->atm
.aal
== AAL_SIGNALLING
) &&
1043 length
>= reported_length
) {
1045 * XXX - what if the packet is truncated? Can that happen?
1046 * What if you capture with Windows Sniffer on an ATM link
1047 * and tell it not to save the entire packet? What happens
1050 aal5_length
= tvb_get_ntohs(tvb
, length
- 6);
1053 * Check for sanity in the AAL5 length. It must be > 0
1054 * and must be less than the amount of space left after
1055 * we remove the trailer.
1057 * If it's not sane, assume we don't have a trailer.
1059 if (aal5_length
> 0 && aal5_length
<= length
- 8) {
1061 * How much padding is there?
1063 pad_length
= length
- aal5_length
- 8;
1066 * There is no reason for more than 47 bytes of padding.
1067 * The most padding you can have would be 7 bytes at the
1068 * end of the next-to-last cell (8 bytes after the end of
1069 * the data means you can fit the trailer in that cell),
1070 * plus 40 bytes in the last cell (with the last 8 bytes
1073 * If there's more than 47 bytes of padding, assume we don't
1076 if (pad_length
<= 47) {
1080 if (pad_length
> 0) {
1081 proto_tree_add_text(atm_tree
, tvb
, aal5_length
, pad_length
,
1085 proto_tree_add_item(atm_tree
, hf_atm_aal5_uu
, tvb
, length
- 8, 1, ENC_BIG_ENDIAN
);
1086 proto_tree_add_item(atm_tree
, hf_atm_aal5_cpi
, tvb
, length
- 7, 1, ENC_BIG_ENDIAN
);
1087 proto_tree_add_item(atm_tree
, hf_atm_aal5_len
, tvb
, length
- 6, 2, ENC_BIG_ENDIAN
);
1089 crc
= tvb_get_ntohl(tvb
, length
- 4);
1090 calc_crc
= update_crc(0xFFFFFFFF, tvb_get_ptr(tvb
, 0, length
),
1092 ti
= proto_tree_add_uint(atm_tree
, hf_atm_aal5_crc
, tvb
, length
- 4, 4, crc
);
1093 proto_item_append_text(ti
, (calc_crc
== 0xC704DD7B) ? " (correct)" : " (incorrect)");
1095 next_tvb
= tvb_new_subset(tvb
, 0, aal5_length
, aal5_length
);
1101 switch (pinfo
->pseudo_header
->atm
.aal
) {
1103 case AAL_SIGNALLING
:
1104 call_dissector(sscop_handle
, next_tvb
, pinfo
, tree
);
1108 switch (pinfo
->pseudo_header
->atm
.type
) {
1111 call_dissector(sscop_handle
, next_tvb
, pinfo
, tree
);
1115 call_dissector(fr_handle
, next_tvb
, pinfo
, tree
);
1119 call_dissector(llc_handle
, next_tvb
, pinfo
, tree
);
1123 call_dissector(lane_handle
, next_tvb
, pinfo
, tree
);
1127 call_dissector(ilmi_handle
, next_tvb
, pinfo
, tree
);
1131 call_dissector(gprs_ns_handle
, next_tvb
, pinfo
, tree
);
1136 gboolean decoded
= FALSE
;
1138 if (tvb_length(next_tvb
) > 7) /* sizeof(octet) */
1141 tvb_memcpy(next_tvb
, octet
, 0, sizeof(octet
));
1144 if (octet
[0] == 0xaa
1146 && octet
[2] == 0x03) /* LLC SNAP as per RFC2684 */
1148 call_dissector(llc_handle
, next_tvb
, pinfo
, tree
);
1150 else if ((pntohs(octet
) & 0xff) == PPP_IP
)
1152 call_dissector(ppp_handle
, next_tvb
, pinfo
, tree
);
1154 else if (pntohs(octet
) == 0x00)
1156 /* assume vc muxed bridged ethernet */
1157 proto_tree_add_text(tree
, tvb
, 0, 2, "Pad: 0x0000");
1158 next_tvb
= tvb_new_subset_remaining(tvb
, 2);
1159 call_dissector(eth_handle
, next_tvb
, pinfo
, tree
);
1161 else if (octet
[2] == 0x03 && /* NLPID */
1162 ((octet
[3] == 0xcc || /* IPv4 */
1163 octet
[3] == 0x8e) || /* IPv6 */
1164 (octet
[3] == 0x00 && /* Eth */
1165 octet
[4] == 0x80))) /* Eth */
1167 /* assume network interworking with FR 2 byte header */
1168 call_dissector(fr_handle
, next_tvb
, pinfo
, tree
);
1170 else if (octet
[4] == 0x03 && /* NLPID */
1171 ((octet
[5] == 0xcc || /* IPv4 */
1172 octet
[5] == 0x8e) || /* IPv6 */
1173 (octet
[5] == 0x00 && /* Eth */
1174 octet
[6] == 0x80))) /* Eth */
1176 /* assume network interworking with FR 4 byte header */
1177 call_dissector(fr_handle
, next_tvb
, pinfo
, tree
);
1179 else if (((octet
[0] & 0xf0)== 0x40) ||
1180 ((octet
[0] & 0xf0) == 0x60))
1182 call_dissector(ip_handle
, next_tvb
, pinfo
, tree
);
1190 if (tree
&& !decoded
) {
1191 /* Dump it as raw data. */
1192 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1200 proto_tree_add_uint(atm_tree
, hf_atm_cid
, tvb
, 0, 0,
1201 pinfo
->pseudo_header
->atm
.aal2_cid
);
1202 proto_item_append_text(atm_ti
, " (vpi=%u vci=%u cid=%u)",
1203 pinfo
->pseudo_header
->atm
.vpi
,
1204 pinfo
->pseudo_header
->atm
.vci
,
1205 pinfo
->pseudo_header
->atm
.aal2_cid
);
1207 if (pinfo
->pseudo_header
->atm
.flags
& ATM_AAL2_NOPHDR
) {
1210 /* Skip first 4 bytes of message
1214 Ignoring for now... */
1215 next_tvb
= tvb_new_subset_remaining(tvb
, 4);
1218 type
= pinfo
->pseudo_header
->atm
.type
;
1219 if (type
== TRAF_UNKNOWN
) {
1220 type
= unknown_aal2_type
;
1224 call_dissector(fp_handle
, next_tvb
, pinfo
, tree
);
1228 /* Dump it as raw data. */
1229 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1235 /* Dump it as raw data. */
1236 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1242 * Charles Michael Heard's HEC code, from
1244 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1246 * with the syndrome and error position tables initialized with values
1247 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1248 * rather than by calling those routines at run time, and with various data
1249 * type cleanups and changes not to correct the header if a correctible
1250 * error was detected.
1252 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1254 static const guint8 syndrome_table
[256] = {
1255 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1256 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1257 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1258 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1259 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1260 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1261 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1262 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1263 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1264 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1265 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1266 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1267 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1268 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1269 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1270 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1271 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1272 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1273 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1274 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1275 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1276 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1277 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1278 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1279 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1280 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1281 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1282 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1283 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1284 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1285 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1286 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1289 #define NO_ERROR_DETECTED -128
1290 #define UNCORRECTIBLE_ERROR 128
1292 static const int err_posn_table
[256] = {
1293 NO_ERROR_DETECTED
, 39,
1294 38, UNCORRECTIBLE_ERROR
,
1295 37, UNCORRECTIBLE_ERROR
,
1296 UNCORRECTIBLE_ERROR
, 31,
1297 36, UNCORRECTIBLE_ERROR
,
1298 UNCORRECTIBLE_ERROR
, 8,
1299 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1300 30, UNCORRECTIBLE_ERROR
,
1301 35, UNCORRECTIBLE_ERROR
,
1302 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1303 UNCORRECTIBLE_ERROR
, 23,
1304 7, UNCORRECTIBLE_ERROR
,
1305 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1306 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1307 29, UNCORRECTIBLE_ERROR
,
1308 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1309 34, UNCORRECTIBLE_ERROR
,
1310 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1311 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1312 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1313 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1314 22, UNCORRECTIBLE_ERROR
,
1315 6, UNCORRECTIBLE_ERROR
,
1316 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1317 UNCORRECTIBLE_ERROR
, 0,
1318 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1319 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1320 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1321 28, UNCORRECTIBLE_ERROR
,
1322 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1323 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1324 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1325 33, UNCORRECTIBLE_ERROR
,
1326 UNCORRECTIBLE_ERROR
, 10,
1327 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1328 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1329 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1330 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1331 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1332 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1333 UNCORRECTIBLE_ERROR
, 12,
1334 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1335 21, UNCORRECTIBLE_ERROR
,
1336 UNCORRECTIBLE_ERROR
, 19,
1337 5, UNCORRECTIBLE_ERROR
,
1338 UNCORRECTIBLE_ERROR
, 17,
1339 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1340 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1341 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1342 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1343 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1344 UNCORRECTIBLE_ERROR
, 3,
1345 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1346 UNCORRECTIBLE_ERROR
, 15,
1347 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1348 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1349 27, UNCORRECTIBLE_ERROR
,
1350 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1351 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1352 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1353 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1354 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1355 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1356 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1357 32, UNCORRECTIBLE_ERROR
,
1358 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1359 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1360 9, UNCORRECTIBLE_ERROR
,
1361 UNCORRECTIBLE_ERROR
, 24,
1362 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1363 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1364 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1365 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1366 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1367 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1368 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1369 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1370 UNCORRECTIBLE_ERROR
, 1,
1371 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1372 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1373 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1374 11, UNCORRECTIBLE_ERROR
,
1375 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1376 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1377 20, UNCORRECTIBLE_ERROR
,
1378 UNCORRECTIBLE_ERROR
, 13,
1379 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1380 18, UNCORRECTIBLE_ERROR
,
1381 4, UNCORRECTIBLE_ERROR
,
1382 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1383 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1384 16, UNCORRECTIBLE_ERROR
,
1385 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1386 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1387 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1388 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1389 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1390 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1391 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1392 UNCORRECTIBLE_ERROR
, 25,
1393 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1394 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1395 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1396 2, UNCORRECTIBLE_ERROR
,
1397 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1398 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1399 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1400 14, UNCORRECTIBLE_ERROR
,
1401 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1402 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1403 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1404 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1405 26, UNCORRECTIBLE_ERROR
,
1406 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1407 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1408 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1409 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1410 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1411 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1412 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1413 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1414 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1415 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1416 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1417 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1418 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1419 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1420 UNCORRECTIBLE_ERROR
, UNCORRECTIBLE_ERROR
,
1424 * Return an indication of whether there was an error in the cell header
1425 * and, if so, where the error was, if it was correctable.
1428 get_header_err(const guint8
*cell_header
)
1430 register guint8 syndrome
;
1431 register int i
, err_posn
;
1434 for (i
= 0; i
< 4; i
++)
1435 syndrome
= syndrome_table
[syndrome
^ cell_header
[i
]];
1436 syndrome
^= cell_header
[4] ^ COSET_LEADER
;
1438 err_posn
= err_posn_table
[syndrome
];
1441 return NO_ERROR_DETECTED
;
1442 else if (err_posn
< 40)
1445 return UNCORRECTIBLE_ERROR
;
1448 const value_string atm_pt_vals
[] = {
1449 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1450 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1451 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1452 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1453 { 4, "Segment OAM F5 flow related cell" },
1454 { 5, "End-to-end OAM F5 flow related cell" },
1455 { 6, "VC resource management cell" },
1460 * Charles Michael Heard's CRC-10 code, from
1462 * http://www.cell-relay.com/cell-relay/publications/software/CRC/crc10.html
1464 * with the CRC table initialized with values computed by
1465 * his "gen_byte_crc10_table()" routine, rather than by calling that
1466 * routine at run time, and with various data type cleanups.
1468 static const guint16 byte_crc10_table
[256] = {
1469 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
1470 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
1471 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce,
1472 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf,
1473 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d,
1474 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c,
1475 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac,
1476 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad,
1477 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b,
1478 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a,
1479 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a,
1480 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b,
1481 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259,
1482 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158,
1483 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268,
1484 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169,
1485 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377,
1486 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076,
1487 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346,
1488 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047,
1489 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315,
1490 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014,
1491 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324,
1492 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025,
1493 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3,
1494 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2,
1495 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382,
1496 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083,
1497 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1,
1498 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0,
1499 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0,
1500 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1,
1503 /* update the data block's CRC-10 remainder one byte at a time */
1505 update_crc10_by_bytes(guint16 crc10_accum
, const guint8
*data_blk_ptr
,
1510 for (i
= 0; i
< data_blk_size
; i
++) {
1511 crc10_accum
= ((crc10_accum
<< 8) & 0x3ff)
1512 ^ byte_crc10_table
[( crc10_accum
>> 2) & 0xff]
1518 static const value_string st_vals
[] = {
1526 #define OAM_TYPE_FM 1 /* Fault Management */
1527 #define OAM_TYPE_PM 2 /* Performance Management */
1528 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1530 static const value_string oam_type_vals
[] = {
1531 { OAM_TYPE_FM
, "Fault Management" },
1532 { OAM_TYPE_PM
, "Performance Management" },
1533 { OAM_TYPE_AD
, "Activation/Deactivation" },
1537 static const value_string ft_fm_vals
[] = {
1538 { 0, "Alarm Indication Signal" },
1539 { 1, "Far End Receive Failure" },
1540 { 8, "OAM Cell Loopback" },
1541 { 4, "Continuity Check" },
1545 static const value_string ft_pm_vals
[] = {
1546 { 0, "Forward Monitoring" },
1547 { 1, "Backward Reporting" },
1548 { 2, "Monitoring and Reporting" },
1552 static const value_string ft_ad_vals
[] = {
1553 { 0, "Performance Monitoring" },
1554 { 1, "Continuity Check" },
1560 * Check for OAM cells.
1561 * OAM F4 is VCI 3 or 4 and PT 0X0.
1565 atm_is_oam_cell(const guint16 vci
, const guint8 pt
)
1567 return (((vci
== 3 || vci
== 4) && ((pt
& 0x5) == 0))
1568 || ((pt
& 0x6) == 0x4));
1573 dissect_atm_cell(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1574 proto_tree
*atm_tree
, guint aal
, gboolean nni
,
1575 gboolean crc_stripped
, const pwatm_private_data_t
*pwpd
)
1578 proto_tree
*aal_tree
;
1582 guint16 vpi
, vci
, aal3_4_hdr
, crc10
;
1589 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1590 * and encoding at UNI reference point as:
1605 octet
= tvb_get_guint8(tvb
, 0);
1606 proto_tree_add_text(atm_tree
, tvb
, 0, 1, "GFC: 0x%x", octet
>> 4);
1607 vpi
= (octet
& 0xF) << 4;
1608 octet
= tvb_get_guint8(tvb
, 1);
1610 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 2, vpi
);
1613 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1614 * and encoding at NNI reference point as:
1629 octet
= tvb_get_guint8(tvb
, 0);
1631 octet
= tvb_get_guint8(tvb
, 1);
1632 vpi
|= (octet
& 0xF0) >> 4;
1633 proto_tree_add_uint(atm_tree
, hf_atm_vpi
, tvb
, 0, 2, vpi
);
1636 vci
= (octet
& 0x0F) << 12;
1637 octet
= tvb_get_guint8(tvb
, 2);
1639 octet
= tvb_get_guint8(tvb
, 3);
1641 proto_tree_add_uint(atm_tree
, hf_atm_vci
, tvb
, 1, 3, vci
);
1642 pt
= (octet
>> 1) & 0x7;
1643 proto_tree_add_item(atm_tree
, hf_atm_payload_type
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1644 proto_tree_add_item(atm_tree
, hf_atm_cell_loss_priority
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
1646 if (!crc_stripped
) {
1648 * FF: parse the Header Error Check (HEC).
1650 ti
= proto_tree_add_item(atm_tree
, hf_atm_header_error_check
, tvb
, 4, 1, ENC_BIG_ENDIAN
);
1651 err
= get_header_err(tvb_get_ptr(tvb
, 0, 5));
1652 if (err
== NO_ERROR_DETECTED
)
1653 proto_item_append_text(ti
, " (correct)");
1654 else if (err
== UNCORRECTIBLE_ERROR
)
1655 proto_item_append_text(ti
, " (uncorrectable error)");
1657 proto_item_append_text(ti
, " (error in bit %d)", err
);
1661 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1662 * Cell Mode) the Header Error Check (HEC) field is stripped.
1663 * So we do nothing here.
1670 offset
= 0; /* For PWs. Header is decoded by PW dissector.*/
1679 * Check for OAM cells.
1680 * XXX - do this for all AAL values, overriding whatever information
1681 * Wiretap got from the file?
1683 if (aal
== AAL_USER
|| aal
== AAL_UNKNOWN
) {
1684 if (atm_is_oam_cell(vci
,pt
)) {
1692 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AAL1");
1693 col_clear(pinfo
->cinfo
, COL_INFO
);
1694 ti
= proto_tree_add_item(tree
, proto_aal1
, tvb
, offset
, -1, ENC_NA
);
1695 aal_tree
= proto_item_add_subtree(ti
, ett_aal1
);
1696 octet
= tvb_get_guint8(tvb
, offset
);
1698 proto_tree_add_item(aal_tree
, hf_atm_aa1_csi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1699 proto_tree_add_item(aal_tree
, hf_atm_aa1_seq_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1700 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Sequence count = %u",
1701 (octet
>> 4) & 0x7);
1702 proto_tree_add_item(aal_tree
, hf_atm_aa1_crc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1703 proto_tree_add_item(aal_tree
, hf_atm_aa1_parity
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1706 proto_tree_add_item(aal_tree
, hf_atm_aa1_payload
, tvb
, offset
, 47, ENC_NA
);
1711 * XXX - or should this be the CS PDU?
1713 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "AAL3/4");
1714 col_clear(pinfo
->cinfo
, COL_INFO
);
1715 ti
= proto_tree_add_item(tree
, proto_aal3_4
, tvb
, offset
, -1, ENC_NA
);
1716 aal_tree
= proto_item_add_subtree(ti
, ett_aal3_4
);
1717 aal3_4_hdr
= tvb_get_ntohs(tvb
, offset
);
1718 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s, sequence number = %u",
1719 val_to_str(aal3_4_hdr
>> 14, st_vals
, "Unknown (%u)"),
1720 (aal3_4_hdr
>> 10) & 0xF);
1721 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_seg_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1722 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_seq_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1723 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_multiplex_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1725 length
= tvb_length_remaining(tvb
, offset
);
1726 crc10
= update_crc10_by_bytes(0, tvb_get_ptr(tvb
, offset
, length
),
1730 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_information
, tvb
, offset
, 44, ENC_NA
);
1733 proto_tree_add_item(aal_tree
, hf_atm_aal3_4_length_indicator
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1734 ti
= proto_tree_add_item(aal_tree
, hf_atm_aal3_4_crc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1735 proto_item_append_text(ti
, " (%s)", (crc10
== 0) ? " (correct)" : " (incorrect)");
1739 if (NULL
== pwpd
|| pwpd
->enable_fill_columns_by_atm_dissector
)
1741 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "OAM AAL");
1742 col_clear(pinfo
->cinfo
, COL_INFO
);
1744 ti
= proto_tree_add_item(tree
, proto_oamaal
, tvb
, offset
, -1, ENC_NA
);
1745 aal_tree
= proto_item_add_subtree(ti
, ett_oamaal
);
1746 octet
= tvb_get_guint8(tvb
, offset
);
1747 if (NULL
== pwpd
|| pwpd
->enable_fill_columns_by_atm_dissector
)
1749 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s",
1750 val_to_str(octet
>> 4, oam_type_vals
, "Unknown (%u)"));
1753 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1754 switch (octet
>> 4) {
1757 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_fm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1761 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_pm
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1765 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_ad
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1769 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_type_ft
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1772 length
= tvb_length_remaining(tvb
, offset
);
1773 crc10
= update_crc10_by_bytes(0, tvb_get_ptr(tvb
, offset
, length
),
1777 proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_func_spec
, tvb
, offset
, 45, ENC_NA
);
1780 ti
= proto_tree_add_item(aal_tree
, hf_atm_aal_oamcell_crc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1781 proto_item_append_text(ti
, " (%s)", (crc10
== 0) ? " (correct)" : " (incorrect)");
1785 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1786 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1792 dissect_atm_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1793 gboolean truncated
, const pwatm_private_data_t
*pwpd
)
1795 proto_tree
*atm_tree
= NULL
;
1796 proto_item
*atm_ti
= NULL
;
1797 gboolean pseudowire_mode
= (NULL
!= pwpd
);
1799 if ( pinfo
->pseudo_header
->atm
.aal
== AAL_5
&&
1800 pinfo
->pseudo_header
->atm
.type
== TRAF_LANE
&&
1801 dissect_lanesscop
) {
1802 pinfo
->pseudo_header
->atm
.aal
= AAL_SIGNALLING
;
1805 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM");
1807 if (!pseudowire_mode
) {
1808 switch (pinfo
->pseudo_header
->atm
.channel
) {
1811 /* Traffic from DTE to DCE. */
1812 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "DCE");
1813 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "DTE");
1817 /* Traffic from DCE to DTE. */
1818 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "DTE");
1819 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "DCE");
1824 if (pinfo
->pseudo_header
->atm
.aal
== AAL_5
) {
1825 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "AAL5 %s",
1826 val_to_str(pinfo
->pseudo_header
->atm
.type
, aal5_hltype_vals
,
1827 "Unknown traffic type (%u)"));
1829 col_add_str(pinfo
->cinfo
, COL_INFO
,
1830 val_to_str(pinfo
->pseudo_header
->atm
.aal
, aal_vals
,
1831 "Unknown AAL (%u)"));
1835 atm_ti
= proto_tree_add_item(tree
, proto_atm
, tvb
, 0, -1, ENC_NA
);
1836 atm_tree
= proto_item_add_subtree(atm_ti
, ett_atm
);
1838 if (!pseudowire_mode
) {
1839 proto_tree_add_uint(atm_tree
, hf_atm_channel
, tvb
, 0, 0, pinfo
->pseudo_header
->atm
.channel
);
1842 proto_tree_add_uint_format_value(atm_tree
, hf_atm_aal
, tvb
, 0, 0,
1843 pinfo
->pseudo_header
->atm
.aal
,
1845 val_to_str(pinfo
->pseudo_header
->atm
.aal
, aal_vals
,
1846 "Unknown AAL (%u)"));
1848 if (pinfo
->pseudo_header
->atm
.flags
& ATM_RAW_CELL
) {
1849 /* This is a single cell, with the cell header at the beginning. */
1850 if (pinfo
->pseudo_header
->atm
.flags
& ATM_NO_HEC
) {
1851 proto_item_set_len(atm_ti
, 4);
1853 proto_item_set_len(atm_ti
, 5);
1855 dissect_atm_cell(tvb
, pinfo
, tree
, atm_tree
,
1856 pinfo
->pseudo_header
->atm
.aal
, FALSE
,
1857 pinfo
->pseudo_header
->atm
.flags
& ATM_NO_HEC
, pwpd
);
1859 /* This is a reassembled PDU. */
1862 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
1863 * In such cases, the dissector data parameter is used to pass info from/to
1864 * PW dissector to ATM dissector. For decoding normal ATM traffic
1865 * data parameter should be NULL.
1867 dissect_reassembled_pdu(tvb
, pinfo
, tree
, atm_tree
, atm_ti
, truncated
, pwpd
!= NULL
);
1870 return tvb_length(tvb
);
1874 dissect_atm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1876 const pwatm_private_data_t
*pwpd
= (const pwatm_private_data_t
*)data
;
1878 return dissect_atm_common(tvb
, pinfo
, tree
, TRUE
, pwpd
);
1882 dissect_atm_untruncated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1884 const pwatm_private_data_t
*pwpd
= (const pwatm_private_data_t
*)data
;
1886 return dissect_atm_common(tvb
, pinfo
, tree
, FALSE
, pwpd
);
1890 dissect_atm_oam_cell(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1892 proto_tree
*atm_tree
= NULL
;
1893 proto_item
*atm_ti
= NULL
;
1894 const pwatm_private_data_t
*pwpd
= (const pwatm_private_data_t
*)data
;
1895 gboolean pseudowire_mode
= (NULL
!= pwpd
);
1897 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATM");
1899 if (!pseudowire_mode
) {
1900 atm_ti
= proto_tree_add_item(tree
, proto_atm
, tvb
, 0, 0, ENC_NA
);
1901 atm_tree
= proto_item_add_subtree(atm_ti
, ett_atm
);
1904 dissect_atm_cell(tvb
, pinfo
, tree
, atm_tree
, AAL_OAMCELL
, FALSE
, FALSE
, pwpd
);
1905 return tvb_length(tvb
);
1910 proto_register_atm(void)
1912 static hf_register_info hf
[] = {
1914 { "AAL", "atm.aal", FT_UINT8
, BASE_DEC
, VALS(aal_vals
), 0x0,
1918 { "VPI", "atm.vpi", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1922 { "VCI", "atm.vci", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1926 { "CID", "atm.cid", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1929 { &hf_atm_le_client_client
,
1930 { "LE Client", "atm.le_client.client", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1932 { &hf_atm_lan_destination_tag
,
1933 { "Tag", "atm.lan_destination.tag", FT_UINT16
, BASE_HEX
, VALS(le_control_landest_tag_vals
), 0x0,
1935 { &hf_atm_lan_destination_mac
,
1936 { "MAC address", "atm.lan_destination.mac", FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1938 { &hf_atm_le_control_tlv_type
,
1939 { "TLV Type", "atm.le_control.tlv_type", FT_UINT32
, BASE_HEX
, VALS(le_tlv_type_vals
), 0x0,
1941 { &hf_atm_le_control_tlv_length
,
1942 { "TLV Length", "atm.le_control.tlv_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1944 { &hf_atm_lan_destination_route_desc
,
1945 { "Route descriptor", "atm.lan_destination.route_desc", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1947 { &hf_atm_lan_destination_lan_id
,
1948 { "LAN ID", "atm.lan_destination.lan_id", FT_UINT16
, BASE_DEC
, NULL
, 0xFFF0,
1950 { &hf_atm_lan_destination_bridge_num
,
1951 { "Bridge number", "atm.lan_destination.bridge_num", FT_UINT16
, BASE_DEC
, NULL
, 0x000F,
1953 { &hf_atm_source_atm
,
1954 { "Source ATM address", "atm.source_atm", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1956 { &hf_atm_target_atm
,
1957 { "Target ATM address", "atm.target_atm", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1959 { &hf_atm_le_configure_join_frame_lan_type
,
1960 { "LAN type", "atm.le_configure_join_frame.lan_type", FT_UINT8
, BASE_HEX
, VALS(le_control_lan_type_vals
), 0x0,
1962 { &hf_atm_le_configure_join_frame_max_frame_size
,
1963 { "Maximum frame size", "atm.le_configure_join_frame.max_frame_size", FT_UINT8
, BASE_HEX
, VALS(le_control_frame_size_vals
), 0x0,
1965 { &hf_atm_le_configure_join_frame_num_tlvs
,
1966 { "Number of TLVs", "atm.le_configure_join_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1968 { &hf_atm_le_configure_join_frame_elan_name_size
,
1969 { "ELAN name size", "atm.le_configure_join_frame.elan_name_size", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1971 { &hf_atm_le_registration_frame_num_tlvs
,
1972 { "Number of TLVs", "atm.le_registration_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1974 { &hf_atm_le_arp_frame_num_tlvs
,
1975 { "Number of TLVs", "atm.le_arp_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1977 { &hf_atm_le_verify_frame_num_tlvs
,
1978 { "Number of TLVs", "atm.le_verify_frame.num_tlvs", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1980 { &hf_atm_le_configure_join_frame_elan_name
,
1981 { "ELAN name", "atm.le_configure_join_frame.elan_name", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1983 { &hf_atm_le_control_marker
,
1984 { "Marker", "atm.le_control.marker", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1986 { &hf_atm_le_control_protocol
,
1987 { "Protocol", "atm.le_control.protocol", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1989 { &hf_atm_le_control_version
,
1990 { "Version", "atm.le_control.version", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1992 { &hf_atm_le_control_opcode
,
1993 { "Opcode", "atm.le_control.opcode", FT_UINT16
, BASE_HEX
, VALS(le_control_opcode_vals
), 0x0,
1995 { &hf_atm_le_control_status
,
1996 { "Status", "atm.le_control.status", FT_UINT16
, BASE_HEX
, VALS(le_control_status_vals
), 0x0,
1998 { &hf_atm_le_control_transaction_id
,
1999 { "Transaction ID", "atm.le_control.transaction_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2001 { &hf_atm_le_control_requester_lecid
,
2002 { "Requester LECID", "atm.le_control.requester_lecid", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2004 { &hf_atm_le_control_flags
,
2005 { "Flags", "atm.le_control.flag", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2007 { &hf_atm_le_control_flag_v2_capable
,
2008 { "V2 capable", "atm.le_control.flag.v2_capable", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0002,
2010 { &hf_atm_le_control_flag_selective_multicast
,
2011 { "Selective multicast", "atm.le_control.flag.selective_multicast", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0004,
2013 { &hf_atm_le_control_flag_v2_required
,
2014 { "V2 required", "atm.le_control.flag.v2_required", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0008,
2016 { &hf_atm_le_control_flag_proxy
,
2017 { "Proxy", "atm.le_control.flag.flag_proxy", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0080,
2019 { &hf_atm_le_control_flag_exclude_explorer_frames
,
2020 { "Exclude explorer frames", "atm.le_control.flag.exclude_explorer_frames", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0200,
2022 { &hf_atm_le_control_flag_address
,
2023 { "Address", "atm.le_control.flag.address", FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0x0001,
2025 { &hf_atm_le_control_topology_change
,
2026 { "Topology change", "atm.le_control.flag.topology_change", FT_BOOLEAN
, 16, TFS(&tfs_remote_local
), 0x0100,
2028 { &hf_atm_traffic_type
,
2029 { "Traffic type", "atm.traffic_type", FT_UINT8
, BASE_DEC
, VALS(aal5_hltype_vals
), 0x0,
2031 { &hf_atm_traffic_vcmx
,
2032 { "VC multiplexed traffic type", "atm.traffic.vcmx", FT_UINT8
, BASE_DEC
, VALS(vcmx_type_vals
), 0x0,
2034 { &hf_atm_traffic_lane
,
2035 { "LANE traffic type", "atm.traffic.lane", FT_UINT8
, BASE_DEC
, VALS(lane_type_vals
), 0x0,
2037 { &hf_atm_traffic_ipsilon
,
2038 { "Ipsilon traffic type", "atm.traffic.ipsilon", FT_UINT8
, BASE_DEC
, VALS(ipsilon_type_vals
), 0x0,
2041 { "Cells", "atm.cells", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2044 { "AAL5 UU", "atm.hf_atm.aal5t_uu", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2047 { "AAL5 CPI", "atm.hf_atm.aal5t_cpi", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2050 { "AAL5 len", "atm.aal5t_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2053 { "AAL5 CRC", "atm.aal5t_crc", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2055 { &hf_atm_payload_type
,
2056 { "Payload Type", "atm.payload_type", FT_UINT8
, BASE_DEC
, NULL
, 0x0E,
2058 { &hf_atm_cell_loss_priority
,
2059 { "Cell Loss Priority", "atm.cell_loss_priority", FT_BOOLEAN
, 8, TFS(&tfs_low_high_priority
), 0x01,
2061 { &hf_atm_header_error_check
,
2062 { "Header Error Check", "atm.header_error_check", FT_UINT8
, BASE_HEX
, NULL
, 0,
2065 { "Channel", "atm.channel", FT_UINT16
, BASE_DEC
, VALS(atm_channel_vals
), 0,
2068 { "CSI", "atm.aa1.csi", FT_UINT8
, BASE_DEC
, NULL
, 0x80,
2070 { &hf_atm_aa1_seq_count
,
2071 { "Sequence Count", "atm.aa1.seq_count", FT_UINT8
, BASE_DEC
, NULL
, 0x70,
2074 { "CRC", "atm.aa1.crc", FT_UINT8
, BASE_DEC
, NULL
, 0x08,
2076 { &hf_atm_aa1_parity
,
2077 { "Parity", "atm.aa1.parity", FT_UINT8
, BASE_DEC
, NULL
, 0x07,
2079 { &hf_atm_aa1_payload
,
2080 { "Payload", "atm.aa1.payload", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2082 { &hf_atm_aal3_4_seg_type
,
2083 { "Segment Type", "atm.aal3_4.seg_type", FT_UINT16
, BASE_DEC
, VALS(st_vals
), 0xC000,
2085 { &hf_atm_aal3_4_seq_num
,
2086 { "Sequence Number", "atm.aal3_4.seq_num", FT_UINT16
, BASE_DEC
, NULL
, 0x3C00,
2088 { &hf_atm_aal3_4_multiplex_id
,
2089 { "Multiplex ID", "atm.aal3_4.multiplex_id", FT_UINT16
, BASE_DEC
, NULL
, 0x03FF,
2091 { &hf_atm_aal3_4_information
,
2092 { "Information", "atm.aal3_4.information", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2094 { &hf_atm_aal3_4_length_indicator
,
2095 { "Length Indicator", "atm.aal3_4.length_indicator", FT_UINT16
, BASE_DEC
, VALS(st_vals
), 0xFC00,
2097 { &hf_atm_aal3_4_crc
,
2098 { "CRC", "atm.aal3_4.crc", FT_UINT16
, BASE_DEC
, NULL
, 0x03FF,
2100 { &hf_atm_aal_oamcell_type
,
2101 { "OAM Type", "atm.aal_oamcell.type", FT_UINT8
, BASE_DEC
, VALS(oam_type_vals
), 0xF0,
2103 { &hf_atm_aal_oamcell_type_fm
,
2104 { "Function Type", "atm.aal_oamcell.type.fm", FT_UINT8
, BASE_DEC
, VALS(ft_fm_vals
), 0x0F,
2106 { &hf_atm_aal_oamcell_type_pm
,
2107 { "Function Type", "atm.aal_oamcell.type.pm", FT_UINT8
, BASE_DEC
, VALS(ft_pm_vals
), 0x0F,
2109 { &hf_atm_aal_oamcell_type_ad
,
2110 { "Function Type", "atm.aal_oamcell.type.ad", FT_UINT8
, BASE_DEC
, VALS(ft_ad_vals
), 0x0F,
2112 { &hf_atm_aal_oamcell_type_ft
,
2113 { "Function Type", "atm.aal_oamcell.type.ft", FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
2115 { &hf_atm_aal_oamcell_func_spec
,
2116 { "Function-specific information", "atm.aal_oamcell.func_spec", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2118 { &hf_atm_aal_oamcell_crc
,
2119 { "CRC-10", "atm.aal_oamcell.crc", FT_UINT16
, BASE_HEX
, NULL
, 0x3FF,
2123 static gint
*ett
[] = {
2130 &ett_atm_lane_lc_lan_dest
,
2131 &ett_atm_lane_lc_lan_dest_rd
,
2132 &ett_atm_lane_lc_flags
,
2133 &ett_atm_lane_lc_tlv
,
2136 static const enum_val_t unknown_aal2_options
[] = {
2137 { "raw", "Raw data", TRAF_UNKNOWN
},
2138 { "umts_fp", "UMTS FP", TRAF_UMTS_FP
},
2142 module_t
*atm_module
;
2144 proto_atm
= proto_register_protocol("Asynchronous Transfer Mode", "ATM", "atm");
2145 proto_aal1
= proto_register_protocol("ATM AAL1", "AAL1", "aal1");
2146 proto_aal3_4
= proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
2147 proto_oamaal
= proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
2148 proto_register_field_array(proto_atm
, hf
, array_length(hf
));
2149 proto_register_subtree_array(ett
, array_length(ett
));
2151 proto_ilmi
= proto_register_protocol("ILMI", "ILMI", "ilmi");
2153 register_dissector("ilmi", dissect_ilmi
, proto_ilmi
);
2155 proto_atm_lane
= proto_register_protocol("ATM LAN Emulation",
2156 "ATM LANE", "lane");
2158 register_dissector("lane", dissect_lane
, proto_atm_lane
);
2159 atm_handle
= new_register_dissector("atm_truncated", dissect_atm
, proto_atm
);
2160 atm_untruncated_handle
= new_register_dissector("atm_untruncated", dissect_atm_untruncated
, proto_atm
);
2161 new_register_dissector("atm_oam_cell", dissect_atm_oam_cell
, proto_oamaal
);
2163 atm_module
= prefs_register_protocol ( proto_atm
, NULL
);
2164 prefs_register_bool_preference(atm_module
, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
2165 "Autodection between LANE and SSCOP is hard. As default LANE is preferred",
2166 &dissect_lanesscop
);
2167 prefs_register_enum_preference(atm_module
, "unknown_aal2_type",
2168 "Decode unknown AAL2 traffic as",
2169 "Type used to dissect unknown AAL2 traffic",
2170 &unknown_aal2_type
, unknown_aal2_options
, FALSE
);
2175 proto_reg_handoff_atm(void)
2178 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
2179 * SSCOP, LANE, and ILMI dissectors.
2181 eth_withoutfcs_handle
= find_dissector("eth_withoutfcs");
2182 tr_handle
= find_dissector("tr");
2183 fr_handle
= find_dissector("fr");
2184 llc_handle
= find_dissector("llc");
2185 sscop_handle
= find_dissector("sscop");
2186 lane_handle
= find_dissector("lane");
2187 ilmi_handle
= find_dissector("ilmi");
2188 ppp_handle
= find_dissector("ppp");
2189 eth_handle
= find_dissector("eth");
2190 ip_handle
= find_dissector("ip");
2191 data_handle
= find_dissector("data");
2192 fp_handle
= find_dissector("fp");
2193 gprs_ns_handle
= find_dissector("gprs_ns");
2195 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS
, atm_handle
);
2197 dissector_add_uint("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED
,
2198 atm_untruncated_handle
);