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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 #include <epan/addr_resolv.h>
34 #include <epan/ppptypes.h>
36 #include "packet-atm.h"
37 #include "packet-snmp.h"
38 #include "packet-eth.h"
39 #include "packet-tr.h"
40 #include "packet-llc.h"
42 #include "packet-pw-atm.h"
44 static int proto_atm = -1;
45 static int hf_atm_aal = -1;
46 static int hf_atm_vpi = -1;
47 static int hf_atm_vci = -1;
48 static int hf_atm_cid = -1;
49 static int proto_atm_lane = -1;
50 static int proto_ilmi = -1;
51 static int proto_aal1 = -1;
52 static int proto_aal3_4 = -1;
53 static int proto_oamaal = -1;
55 static gint ett_atm = -1;
56 static gint ett_atm_lane = -1;
57 static gint ett_atm_lane_lc_lan_dest = -1;
58 static gint ett_atm_lane_lc_lan_dest_rd = -1;
59 static gint ett_atm_lane_lc_flags = -1;
60 static gint ett_atm_lane_lc_tlv = -1;
61 static gint ett_ilmi = -1;
62 static gint ett_aal1 = -1;
63 static gint ett_aal3_4 = -1;
64 static gint ett_oamaal = -1;
66 static dissector_handle_t eth_withoutfcs_handle;
67 static dissector_handle_t tr_handle;
68 static dissector_handle_t fr_handle;
69 static dissector_handle_t llc_handle;
70 static dissector_handle_t sscop_handle;
71 static dissector_handle_t lane_handle;
72 static dissector_handle_t ilmi_handle;
73 static dissector_handle_t fp_handle;
74 static dissector_handle_t ppp_handle;
75 static dissector_handle_t eth_handle;
76 static dissector_handle_t ip_handle;
77 static dissector_handle_t data_handle;
79 static gboolean dissect_lanesscop = FALSE;
84 * http://www.atmforum.org/atmforum/specs/approved.html
86 * for a number of ATM Forum specifications, e.g. the LAN Emulation
87 * over ATM 1.0 spec, whence I got most of this.
90 /* LE Control opcodes */
91 #define LE_CONFIGURE_REQUEST 0x0001
92 #define LE_CONFIGURE_RESPONSE 0x0101
93 #define LE_JOIN_REQUEST 0x0002
94 #define LE_JOIN_RESPONSE 0x0102
95 #define READY_QUERY 0x0003
96 #define READY_IND 0x0103
97 #define LE_REGISTER_REQUEST 0x0004
98 #define LE_REGISTER_RESPONSE 0x0104
99 #define LE_UNREGISTER_REQUEST 0x0005
100 #define LE_UNREGISTER_RESPONSE 0x0105
101 #define LE_ARP_REQUEST 0x0006
102 #define LE_ARP_RESPONSE 0x0106
103 #define LE_FLUSH_REQUEST 0x0007
104 #define LE_FLUSH_RESPONSE 0x0107
105 #define LE_NARP_REQUEST 0x0008
106 #define LE_TOPOLOGY_REQUEST 0x0009
107 #define LE_VERIFY_REQUEST 0x000A
108 #define LE_VERIFY_RESPONSE 0x010A
110 static const value_string le_control_opcode_vals[] = {
111 { LE_CONFIGURE_REQUEST, "LE_CONFIGURE_REQUEST" },
112 { LE_CONFIGURE_RESPONSE, "LE_CONFIGURE_RESPONSE" },
113 { LE_JOIN_REQUEST, "LE_JOIN_REQUEST" },
114 { LE_JOIN_RESPONSE, "LE_JOIN_RESPONSE" },
115 { READY_QUERY, "READY_QUERY" },
116 { READY_IND, "READY_IND" },
117 { LE_REGISTER_REQUEST, "LE_REGISTER_REQUEST" },
118 { LE_REGISTER_RESPONSE, "LE_REGISTER_RESPONSE" },
119 { LE_UNREGISTER_REQUEST, "LE_UNREGISTER_REQUEST" },
120 { LE_UNREGISTER_RESPONSE, "LE_UNREGISTER_RESPONSE" },
121 { LE_ARP_REQUEST, "LE_ARP_REQUEST" },
122 { LE_ARP_RESPONSE, "LE_ARP_RESPONSE" },
123 { LE_FLUSH_REQUEST, "LE_FLUSH_REQUEST" },
124 { LE_FLUSH_RESPONSE, "LE_FLUSH_RESPONSE" },
125 { LE_NARP_REQUEST, "LE_NARP_REQUEST" },
126 { LE_TOPOLOGY_REQUEST, "LE_TOPOLOGY_REQUEST" },
127 { LE_VERIFY_REQUEST, "LE_VERIFY_REQUEST" },
128 { LE_VERIFY_RESPONSE, "LE_VERIFY_RESPONSE" },
132 /* LE Control statuses */
133 static const value_string le_control_status_vals[] = {
135 { 1, "Version not supported" },
136 { 2, "Invalid request parameters" },
137 { 4, "Duplicate LAN destination registration" },
138 { 5, "Duplicate ATM address" },
139 { 6, "Insufficient resources to grant request" },
140 { 7, "Access denied" },
141 { 8, "Invalid REQUESTOR-ID" },
142 { 9, "Invalid LAN destination" },
143 { 10, "Invalid ATM address" },
144 { 20, "No configuration" },
145 { 21, "LE_CONFIGURE error" },
146 { 22, "Insufficient information" },
147 { 24, "TLV not found" },
151 /* LE Control LAN destination tags */
152 #define TAG_NOT_PRESENT 0x0000
153 #define TAG_MAC_ADDRESS 0x0001
154 #define TAG_ROUTE_DESCRIPTOR 0x0002
156 static const value_string le_control_landest_tag_vals[] = {
157 { TAG_NOT_PRESENT, "Not present" },
158 { TAG_MAC_ADDRESS, "MAC address" },
159 { TAG_ROUTE_DESCRIPTOR, "Route descriptor" },
163 /* LE Control LAN types */
164 #define LANT_UNSPEC 0x00
165 #define LANT_802_3 0x01
166 #define LANT_802_5 0x02
168 static const value_string le_control_lan_type_vals[] = {
169 { LANT_UNSPEC, "Unspecified" },
170 { LANT_802_3, "Ethernet/802.3" },
171 { LANT_802_5, "802.5" },
175 static const value_string le_control_frame_size_vals[] = {
176 { 0x00, "Unspecified" },
177 { 0x01, "1516/1528/1580/1592" },
178 { 0x02, "4544/4556/1580/1592" },
179 { 0x03, "9234/9246" },
180 { 0x04, "18190/18202" },
185 dissect_le_client(tvbuff_t *tvb, proto_tree *tree)
188 proto_tree *lane_tree;
191 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, 0, 2, "ATM LANE");
192 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
194 proto_tree_add_text(lane_tree, tvb, 0, 2, "LE Client: 0x%04X",
195 tvb_get_ntohs(tvb, 0));
200 dissect_lan_destination(tvbuff_t *tvb, int offset, const char *type, proto_tree *tree)
203 proto_tree *dest_tree;
207 guint16 route_descriptor;
209 td = proto_tree_add_text(tree, tvb, offset, 8, "%s LAN destination",
211 dest_tree = proto_item_add_subtree(td, ett_atm_lane_lc_lan_dest);
212 tag = tvb_get_ntohs(tvb, offset);
213 proto_tree_add_text(dest_tree, tvb, offset, 2, "Tag: %s",
214 val_to_str(tag, le_control_landest_tag_vals,
215 "Unknown (0x%04X)"));
220 case TAG_MAC_ADDRESS:
221 proto_tree_add_text(dest_tree, tvb, offset, 6, "MAC address: %s",
222 ether_to_str(tvb_get_ptr(tvb, offset, 6)));
225 case TAG_ROUTE_DESCRIPTOR:
227 route_descriptor = tvb_get_ntohs(tvb, offset);
228 trd = proto_tree_add_text(dest_tree, tvb, offset, 2, "Route descriptor: 0x%02X",
230 rd_tree = proto_item_add_subtree(td, ett_atm_lane_lc_lan_dest_rd);
231 proto_tree_add_text(rd_tree, tvb, offset, 2, "%s",
232 decode_numeric_bitfield(route_descriptor, 0xFFF0, 2*8,
234 proto_tree_add_text(rd_tree, tvb, offset, 2, "%s",
235 decode_numeric_bitfield(route_descriptor, 0x000F, 2*8,
236 "Bridge number = %u"));
242 * TLV values in LE Control frames.
244 #define TLV_TYPE(oui, ident) (((oui) << 8) | (ident))
246 #define LE_CONTROL_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x01)
247 #define LE_MAX_UNK_FRAME_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x02)
248 #define LE_MAX_UNK_FRAME_TIME TLV_TYPE(OUI_ATM_FORUM, 0x03)
249 #define LE_VCC_TIMEOUT_PERIOD TLV_TYPE(OUI_ATM_FORUM, 0x04)
250 #define LE_MAX_RETRY_COUNT TLV_TYPE(OUI_ATM_FORUM, 0x05)
251 #define LE_AGING_TIME TLV_TYPE(OUI_ATM_FORUM, 0x06)
252 #define LE_FORWARD_DELAY_TIME TLV_TYPE(OUI_ATM_FORUM, 0x07)
253 #define LE_EXPECTED_ARP_RESPONSE_TIME TLV_TYPE(OUI_ATM_FORUM, 0x08)
254 #define LE_FLUSH_TIMEOUT TLV_TYPE(OUI_ATM_FORUM, 0x09)
255 #define LE_PATH_SWITCHING_DELAY TLV_TYPE(OUI_ATM_FORUM, 0x0A)
256 #define LE_LOCAL_SEGMENT_ID TLV_TYPE(OUI_ATM_FORUM, 0x0B)
257 #define LE_MCAST_SEND_VCC_TYPE TLV_TYPE(OUI_ATM_FORUM, 0x0C)
258 #define LE_MCAST_SEND_VCC_AVGRATE TLV_TYPE(OUI_ATM_FORUM, 0x0D)
259 #define LE_MCAST_SEND_VCC_PEAKRATE TLV_TYPE(OUI_ATM_FORUM, 0x0E)
260 #define LE_CONN_COMPLETION_TIMER TLV_TYPE(OUI_ATM_FORUM, 0x0F)
261 #define LE_CONFIG_FRAG_INFO TLV_TYPE(OUI_ATM_FORUM, 0x10)
262 #define LE_LAYER_3_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x11)
263 #define LE_ELAN_ID TLV_TYPE(OUI_ATM_FORUM, 0x12)
264 #define LE_SERVICE_CATEGORY TLV_TYPE(OUI_ATM_FORUM, 0x13)
265 #define LE_LLC_MUXED_ATM_ADDRESS TLV_TYPE(OUI_ATM_FORUM, 0x2B)
266 #define LE_X5_ADJUSTMENT TLV_TYPE(OUI_ATM_FORUM, 0x2C)
267 #define LE_PREFERRED_LES TLV_TYPE(OUI_ATM_FORUM, 0x2D)
269 static const value_string le_tlv_type_vals[] = {
270 { LE_CONTROL_TIMEOUT, "Control Time-out" },
271 { LE_MAX_UNK_FRAME_COUNT, "Maximum Unknown Frame Count" },
272 { LE_MAX_UNK_FRAME_TIME, "Maximum Unknown Frame Time" },
273 { LE_VCC_TIMEOUT_PERIOD, "VCC Time-out" },
274 { LE_MAX_RETRY_COUNT, "Maximum Retry Count" },
275 { LE_AGING_TIME, "Aging Time" },
276 { LE_FORWARD_DELAY_TIME, "Forwarding Delay Time" },
277 { LE_EXPECTED_ARP_RESPONSE_TIME, "Expected LE_ARP Response Time" },
278 { LE_FLUSH_TIMEOUT, "Flush Time-out" },
279 { LE_PATH_SWITCHING_DELAY, "Path Switching Delay" },
280 { LE_LOCAL_SEGMENT_ID, "Local Segment ID" },
281 { LE_MCAST_SEND_VCC_TYPE, "Mcast Send VCC Type" },
282 { LE_MCAST_SEND_VCC_AVGRATE, "Mcast Send VCC AvgRate" },
283 { LE_MCAST_SEND_VCC_PEAKRATE, "Mcast Send VCC PeakRate" },
284 { LE_CONN_COMPLETION_TIMER, "Connection Completion Timer" },
285 { LE_CONFIG_FRAG_INFO, "Config Frag Info" },
286 { LE_LAYER_3_ADDRESS, "Layer 3 Address" },
287 { LE_ELAN_ID, "ELAN ID" },
288 { LE_SERVICE_CATEGORY, "Service Category" },
289 { LE_LLC_MUXED_ATM_ADDRESS, "LLC-muxed ATM Address" },
290 { LE_X5_ADJUSTMENT, "X5 Adjustment" },
291 { LE_PREFERRED_LES, "Preferred LES" },
296 dissect_le_control_tlvs(tvbuff_t *tvb, int offset, guint num_tlvs,
302 proto_tree *tlv_tree;
304 while (num_tlvs != 0) {
305 tlv_type = tvb_get_ntohl(tvb, offset);
306 tlv_length = tvb_get_guint8(tvb, offset+4);
307 ttlv = proto_tree_add_text(tree, tvb, offset, 5+tlv_length, "TLV type: %s",
308 val_to_str(tlv_type, le_tlv_type_vals, "Unknown (0x%08x)"));
309 tlv_tree = proto_item_add_subtree(ttlv, ett_atm_lane_lc_tlv);
310 proto_tree_add_text(tlv_tree, tvb, offset, 4, "TLV Type: %s",
311 val_to_str(tlv_type, le_tlv_type_vals, "Unknown (0x%08x)"));
312 proto_tree_add_text(tlv_tree, tvb, offset+4, 1, "TLV Length: %u", tlv_length);
313 offset += 5+tlv_length;
319 dissect_le_configure_join_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
324 dissect_lan_destination(tvb, offset, "Source", tree);
327 dissect_lan_destination(tvb, offset, "Target", tree);
330 proto_tree_add_text(tree, tvb, offset, 20, "Source ATM Address: %s",
331 tvb_bytes_to_str(tvb, offset, 20));
334 proto_tree_add_text(tree, tvb, offset, 1, "LAN type: %s",
335 val_to_str(tvb_get_guint8(tvb, offset), le_control_lan_type_vals,
336 "Unknown (0x%02X)"));
339 proto_tree_add_text(tree, tvb, offset, 1, "Maximum frame size: %s",
340 val_to_str(tvb_get_guint8(tvb, offset), le_control_frame_size_vals,
341 "Unknown (0x%02X)"));
344 num_tlvs = tvb_get_guint8(tvb, offset);
345 proto_tree_add_text(tree, tvb, offset, 1, "Number of TLVs: %u", num_tlvs);
348 name_size = tvb_get_guint8(tvb, offset);
349 proto_tree_add_text(tree, tvb, offset, 1, "ELAN name size: %u", name_size);
352 proto_tree_add_text(tree, tvb, offset, 20, "Target ATM Address: %s",
353 tvb_bytes_to_str(tvb, offset, 20));
358 if (name_size != 0) {
359 proto_tree_add_text(tree, tvb, offset, name_size, "ELAN name: %s",
360 tvb_bytes_to_str(tvb, offset, name_size));
364 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
368 dissect_le_registration_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
372 dissect_lan_destination(tvb, offset, "Source", tree);
375 dissect_lan_destination(tvb, offset, "Target", tree);
378 proto_tree_add_text(tree, tvb, offset, 20, "Source ATM Address: %s",
379 tvb_bytes_to_str(tvb, offset, 20));
385 num_tlvs = tvb_get_guint8(tvb, offset);
386 proto_tree_add_text(tree, tvb, offset, 1, "Number of TLVs: %u", num_tlvs);
392 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
396 dissect_le_arp_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
400 dissect_lan_destination(tvb, offset, "Source", tree);
403 dissect_lan_destination(tvb, offset, "Target", tree);
406 proto_tree_add_text(tree, tvb, offset, 20, "Source ATM Address: %s",
407 tvb_bytes_to_str(tvb, offset, 20));
413 num_tlvs = tvb_get_guint8(tvb, offset);
414 proto_tree_add_text(tree, tvb, offset, 1, "Number of TLVs: %u", num_tlvs);
420 proto_tree_add_text(tree, tvb, offset, 20, "Target ATM Address: %s",
421 tvb_bytes_to_str(tvb, offset, 20));
427 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
431 dissect_le_verify_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
438 num_tlvs = tvb_get_guint8(tvb, offset);
439 proto_tree_add_text(tree, tvb, offset, 1, "Number of TLVs: %u", num_tlvs);
445 proto_tree_add_text(tree, tvb, offset, 20, "Target ATM Address: %s",
446 tvb_bytes_to_str(tvb, offset, 20));
452 dissect_le_control_tlvs(tvb, offset, num_tlvs, tree);
456 dissect_le_flush_frame(tvbuff_t *tvb, int offset, proto_tree *tree)
458 dissect_lan_destination(tvb, offset, "Source", tree);
461 dissect_lan_destination(tvb, offset, "Target", tree);
464 proto_tree_add_text(tree, tvb, offset, 20, "Source ATM Address: %s",
465 tvb_bytes_to_str(tvb, offset, 20));
471 proto_tree_add_text(tree, tvb, offset, 20, "Target ATM Address: %s",
472 tvb_bytes_to_str(tvb, offset, 20));
480 dissect_le_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
483 proto_tree *lane_tree = NULL;
486 proto_tree *flags_tree;
490 col_set_str(pinfo->cinfo, COL_INFO, "LE Control");
493 ti = proto_tree_add_protocol_format(tree, proto_atm_lane, tvb, offset, 108, "ATM LANE");
494 lane_tree = proto_item_add_subtree(ti, ett_atm_lane);
496 proto_tree_add_text(lane_tree, tvb, offset, 2, "Marker: 0x%04X",
497 tvb_get_ntohs(tvb, offset));
502 proto_tree_add_text(lane_tree, tvb, offset, 1, "Protocol: 0x%02X",
503 tvb_get_guint8(tvb, offset));
508 proto_tree_add_text(lane_tree, tvb, offset, 1, "Version: 0x%02X",
509 tvb_get_guint8(tvb, offset));
513 opcode = tvb_get_ntohs(tvb, offset);
514 if (check_col(pinfo->cinfo, COL_INFO)) {
515 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
516 val_to_str(opcode, le_control_opcode_vals,
517 "Unknown opcode (0x%04X)"));
520 proto_tree_add_text(lane_tree, tvb, offset, 2, "Opcode: %s",
521 val_to_str(opcode, le_control_opcode_vals,
522 "Unknown (0x%04X)"));
526 if (opcode == READY_QUERY || opcode == READY_IND) {
527 /* There's nothing more in this packet. */
532 if (opcode & 0x0100) {
533 /* Response; decode status. */
534 proto_tree_add_text(lane_tree, tvb, offset, 2, "Status: %s",
535 val_to_str(tvb_get_ntohs(tvb, offset), le_control_status_vals,
536 "Unknown (0x%04X)"));
540 proto_tree_add_text(lane_tree, tvb, offset, 4, "Transaction ID: 0x%08X",
541 tvb_get_ntohl(tvb, offset));
544 proto_tree_add_text(lane_tree, tvb, offset, 2, "Requester LECID: 0x%04X",
545 tvb_get_ntohs(tvb, offset));
548 flags = tvb_get_ntohs(tvb, offset);
549 tf = proto_tree_add_text(lane_tree, tvb, offset, 2, "Flags: 0x%04X",
551 flags_tree = proto_item_add_subtree(tf, ett_atm_lane_lc_flags);
555 case LE_CONFIGURE_REQUEST:
556 case LE_CONFIGURE_RESPONSE:
557 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
558 decode_boolean_bitfield(flags, 0x0002, 8*2,
559 "V2 capable", "Not V2 capable"));
561 dissect_le_configure_join_frame(tvb, offset, lane_tree);
564 case LE_JOIN_REQUEST:
565 case LE_JOIN_RESPONSE:
566 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
567 decode_boolean_bitfield(flags, 0x0002, 8*2,
568 "V2 capable", "Not V2 capable"));
569 if (opcode == LE_JOIN_REQUEST) {
570 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
571 decode_boolean_bitfield(flags, 0x0004, 8*2,
572 "Selective multicast", "No selective multicast"));
574 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
575 decode_boolean_bitfield(flags, 0x0008, 8*2,
576 "V2 required", "V2 not required"));
578 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
579 decode_boolean_bitfield(flags, 0x0080, 8*2,
580 "Proxy", "Not proxy"));
581 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
582 decode_boolean_bitfield(flags, 0x0200, 8*2,
583 "Exclude explorer frames",
584 "Don't exclude explorer frames"));
586 dissect_le_configure_join_frame(tvb, offset, lane_tree);
589 case LE_REGISTER_REQUEST:
590 case LE_REGISTER_RESPONSE:
591 case LE_UNREGISTER_REQUEST:
592 case LE_UNREGISTER_RESPONSE:
594 dissect_le_registration_frame(tvb, offset, lane_tree);
598 case LE_ARP_RESPONSE:
599 case LE_NARP_REQUEST:
600 if (opcode != LE_NARP_REQUEST) {
601 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
602 decode_boolean_bitfield(flags, 0x0001, 8*2,
603 "Remote address", "Local address"));
606 dissect_le_arp_frame(tvb, offset, lane_tree);
609 case LE_TOPOLOGY_REQUEST:
610 proto_tree_add_text(flags_tree, tvb, offset, 2, "%s",
611 decode_boolean_bitfield(flags, 0x0100, 8*2,
612 "Topology change", "No topology change"));
614 /* 92 reserved bytes */
617 case LE_VERIFY_REQUEST:
618 case LE_VERIFY_RESPONSE:
620 dissect_le_verify_frame(tvb, offset, lane_tree);
623 case LE_FLUSH_REQUEST:
624 case LE_FLUSH_RESPONSE:
626 dissect_le_flush_frame(tvb, offset, lane_tree);
633 capture_lane(const union wtap_pseudo_header *pseudo_header, const guchar *pd,
634 int len, packet_counts *ld)
636 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
637 switch (pseudo_header->atm.subtype) {
639 case TRAF_ST_LANE_802_3:
640 case TRAF_ST_LANE_802_3_MC:
641 /* Dissect as Ethernet */
642 capture_eth(pd, 2, len, ld);
645 case TRAF_ST_LANE_802_5:
646 case TRAF_ST_LANE_802_5_MC:
647 /* Dissect as Token-Ring */
648 capture_tr(pd, 2, len, ld);
658 dissect_lane(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
661 tvbuff_t *next_tvb_le_client;
663 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM LANE");
665 /* Is it LE Control, 802.3, 802.5, or "none of the above"? */
666 switch (pinfo->pseudo_header->atm.subtype) {
668 case TRAF_ST_LANE_LE_CTRL:
669 dissect_le_control(tvb, pinfo, tree);
672 case TRAF_ST_LANE_802_3:
673 case TRAF_ST_LANE_802_3_MC:
674 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - Ethernet/802.3");
675 dissect_le_client(tvb, tree);
677 /* Dissect as Ethernet */
678 next_tvb_le_client = tvb_new_subset(tvb, 2, -1, -1);
679 call_dissector(eth_withoutfcs_handle, next_tvb_le_client, pinfo, tree);
682 case TRAF_ST_LANE_802_5:
683 case TRAF_ST_LANE_802_5_MC:
684 col_set_str(pinfo->cinfo, COL_INFO, "LE Client - 802.5");
685 dissect_le_client(tvb, tree);
687 /* Dissect as Token-Ring */
688 next_tvb_le_client = tvb_new_subset(tvb, 2, -1, -1);
689 call_dissector(tr_handle, next_tvb_le_client, pinfo, tree);
693 /* Dump it as raw data. */
694 col_set_str(pinfo->cinfo, COL_INFO, "Unknown LANE traffic type");
695 next_tvb = tvb_new_subset(tvb, 0, -1, -1);
696 call_dissector(data_handle,next_tvb, pinfo, tree);
702 dissect_ilmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
704 dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_ilmi, ett_ilmi, FALSE);
708 static const value_string aal_vals[] = {
709 { AAL_UNKNOWN, "Unknown AAL" },
712 { AAL_3_4, "AAL3/4" },
714 { AAL_USER, "User AAL" },
715 { AAL_SIGNALLING, "Signalling AAL" },
716 { AAL_OAMCELL, "OAM cell" },
720 /* AAL5 higher-level traffic types */
721 static const value_string aal5_hltype_vals[] = {
722 { TRAF_UNKNOWN, "Unknown traffic type" },
723 { TRAF_LLCMX, "LLC multiplexed" },
724 { TRAF_VCMX, "VC multiplexed" },
725 { TRAF_LANE, "LANE" },
726 { TRAF_ILMI, "ILMI" },
727 { TRAF_FR, "Frame Relay" },
728 { TRAF_SPANS, "FORE SPANS" },
729 { TRAF_IPSILON, "Ipsilon" },
733 /* Traffic subtypes for VC multiplexed traffic */
734 static const value_string vcmx_type_vals[] = {
735 { TRAF_ST_UNKNOWN, "Unknown VC multiplexed traffic type" },
736 { TRAF_ST_VCMX_802_3_FCS, "802.3 FCS" },
737 { TRAF_ST_VCMX_802_4_FCS, "802.4 FCS" },
738 { TRAF_ST_VCMX_802_5_FCS, "802.5 FCS" },
739 { TRAF_ST_VCMX_FDDI_FCS, "FDDI FCS" },
740 { TRAF_ST_VCMX_802_6_FCS, "802.6 FCS" },
741 { TRAF_ST_VCMX_802_3, "802.3" },
742 { TRAF_ST_VCMX_802_4, "802.4" },
743 { TRAF_ST_VCMX_802_5, "802.5" },
744 { TRAF_ST_VCMX_FDDI, "FDDI" },
745 { TRAF_ST_VCMX_802_6, "802.6" },
746 { TRAF_ST_VCMX_FRAGMENTS, "Fragments" },
747 { TRAF_ST_VCMX_BPDU, "BPDU" },
751 /* Traffic subtypes for LANE traffic */
752 static const value_string lane_type_vals[] = {
753 { TRAF_ST_UNKNOWN, "Unknown LANE traffic type" },
754 { TRAF_ST_LANE_LE_CTRL, "LE Control" },
755 { TRAF_ST_LANE_802_3, "802.3" },
756 { TRAF_ST_LANE_802_5, "802.5" },
757 { TRAF_ST_LANE_802_3_MC, "802.3 multicast" },
758 { TRAF_ST_LANE_802_5_MC, "802.5 multicast" },
762 /* Traffic subtypes for Ipsilon traffic */
763 static const value_string ipsilon_type_vals[] = {
764 { TRAF_ST_UNKNOWN, "Unknown Ipsilon traffic type" },
765 { TRAF_ST_IPSILON_FT0, "Flow type 0" },
766 { TRAF_ST_IPSILON_FT1, "Flow type 1" },
767 { TRAF_ST_IPSILON_FT2, "Flow type 2" },
772 capture_atm(const union wtap_pseudo_header *pseudo_header, const guchar *pd,
773 int len, packet_counts *ld)
775 if (pseudo_header->atm.aal == AAL_5) {
776 switch (pseudo_header->atm.type) {
779 /* Dissect as WTAP_ENCAP_ATM_RFC1483 */
780 /* The ATM iptrace capture that we have shows LLC at this point,
781 * so that's what I'm calling */
782 capture_llc(pd, 0, len, ld);
786 capture_lane(pseudo_header, pd, len, ld);
798 * Charles Michael Heard's CRC-32 code, from
800 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.c.html
802 * with the CRC table initialized with values computed by
803 * his "gen_crc_table()" routine, rather than by calling that routine
804 * at run time, and with various data type cleanups.
807 /* crc32h.c -- package to compute 32-bit CRC one byte at a time using */
808 /* the high-bit first (Big-Endian) bit ordering convention */
811 /* gen_crc_table() -- generates a 256-word table containing all CRC */
812 /* remainders for every possible 8-bit byte. It */
813 /* must be executed (once) before any CRC updates. */
815 /* unsigned update_crc(crc_accum, data_blk_ptr, data_blk_size) */
816 /* unsigned crc_accum; char *data_blk_ptr; int data_blk_size; */
817 /* Returns the updated value of the CRC accumulator after */
818 /* processing each byte in the addressed block of data. */
820 /* It is assumed that an unsigned long is at least 32 bits wide and */
821 /* that the predefined type char occupies one 8-bit byte of storage. */
823 /* The generator polynomial used for this version of the package is */
824 /* 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 */
825 /* as specified in the Autodin/Ethernet/ADCCP protocol standards. */
826 /* Other degree 32 polynomials may be substituted by re-defining the */
827 /* symbol POLYNOMIAL below. Lower degree polynomials must first be */
828 /* multiplied by an appropriate power of x. The representation used */
829 /* is that the coefficient of x^0 is stored in the LSB of the 32-bit */
830 /* word and the coefficient of x^31 is stored in the most significant */
831 /* bit. The CRC is to be appended to the data most significant byte */
832 /* first. For those protocols in which bytes are transmitted MSB */
833 /* first and in the same order as they are encountered in the block */
834 /* this convention results in the CRC remainder being transmitted with */
835 /* the coefficient of x^31 first and with that of x^0 last (just as */
836 /* would be done by a hardware shift register mechanization). */
838 /* The table lookup technique was adapted from the algorithm described */
839 /* by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).*/
841 static const guint32 crc_table[256] = {
842 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
843 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
844 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
845 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
846 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
847 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
848 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
849 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
850 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
851 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
852 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
853 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
854 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
855 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
856 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
857 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
858 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
859 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
860 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
861 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
862 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
863 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
864 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
865 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
866 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
867 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
868 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
869 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
870 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
871 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
872 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
873 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
874 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
875 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
876 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
877 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
878 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
879 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
880 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
881 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
882 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
883 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
884 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
885 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
886 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
887 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
888 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
889 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
890 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
891 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
892 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
893 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
894 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
895 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
896 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
897 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
898 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
899 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
900 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
901 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
902 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
903 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
904 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
905 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
909 update_crc(guint32 crc_accum, const guint8 *data_blk_ptr, int data_blk_size)
913 /* update the CRC on the data block one byte at a time */
914 for (j = 0; j < data_blk_size; j++) {
915 i = ( (int) ( crc_accum >> 24) ^ *data_blk_ptr++ ) & 0xff;
916 crc_accum = ( crc_accum << 8 ) ^ crc_table[i];
922 dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
924 proto_tree *atm_tree, gboolean truncated)
926 guint length, reported_length;
933 * ATM dissector is used as "sub-dissector" for ATM pseudowires.
934 * In such cases, pinfo->private_data is used to pass info from/to
935 * PW dissector to ATM dissector. For decoding normal ATM traffic
936 * private_data should be NULL.
938 gboolean pseudowire_mode = (NULL != pinfo->private_data);
941 * This is reassembled traffic, so the cell headers are missing;
942 * show the traffic type for AAL5 traffic, and the VPI and VCI,
943 * from the pseudo-header.
945 if (pinfo->pseudo_header->atm.aal == AAL_5) {
946 proto_tree_add_text(atm_tree, tvb, 0, 0, "Traffic type: %s",
947 val_to_str(pinfo->pseudo_header->atm.type, aal5_hltype_vals,
948 "Unknown AAL5 traffic type (%u)"));
949 switch (pinfo->pseudo_header->atm.type) {
952 proto_tree_add_text(atm_tree, tvb, 0, 0, "VC multiplexed traffic type: %s",
953 val_to_str(pinfo->pseudo_header->atm.subtype,
954 vcmx_type_vals, "Unknown VCMX traffic type (%u)"));
958 proto_tree_add_text(atm_tree, tvb, 0, 0, "LANE traffic type: %s",
959 val_to_str(pinfo->pseudo_header->atm.subtype,
960 lane_type_vals, "Unknown LANE traffic type (%u)"));
964 proto_tree_add_text(atm_tree, tvb, 0, 0, "Ipsilon traffic type: %s",
965 val_to_str(pinfo->pseudo_header->atm.subtype,
966 ipsilon_type_vals, "Unknown Ipsilon traffic type (%u)"));
970 if (!pseudowire_mode) {
971 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0,
972 pinfo->pseudo_header->atm.vpi);
973 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0,
974 pinfo->pseudo_header->atm.vci);
976 /* Also show vpi/vci in info column */
977 if (check_col(pinfo->cinfo, COL_INFO))
979 col_append_fstr(pinfo->cinfo, COL_INFO, " VPI=%u, VCI=%u",
980 pinfo->pseudo_header->atm.vpi,
981 pinfo->pseudo_header->atm.vci);
988 * The packet data does not include stuff such as the AAL5
991 if (pinfo->pseudo_header->atm.cells != 0) {
993 * If the cell count is 0, assume it means we don't know how
996 * XXX - also assume it means we don't know what was in the AAL5
997 * trailer. We may, however, find some capture program that can
998 * give us the AAL5 trailer information but not the cell count,
999 * in which case we need some other way of indicating whether we
1000 * have the AAL5 trailer information.
1003 proto_tree_add_text(atm_tree, tvb, 0, 0, "Cells: %u",
1004 pinfo->pseudo_header->atm.cells);
1005 proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 UU: 0x%02x",
1006 pinfo->pseudo_header->atm.aal5t_u2u >> 8);
1007 proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 CPI: 0x%02x",
1008 pinfo->pseudo_header->atm.aal5t_u2u & 0xFF);
1009 proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 len: %u",
1010 pinfo->pseudo_header->atm.aal5t_len);
1011 proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 CRC: 0x%08X",
1012 pinfo->pseudo_header->atm.aal5t_chksum);
1017 * The packet data includes stuff such as the AAL5 trailer, if
1018 * it wasn't cut off by the snapshot length.
1019 * Decode the trailer, if present, and then chop it off.
1021 length = tvb_length(tvb);
1022 reported_length = tvb_reported_length(tvb);
1023 if ((reported_length % 48) == 0) {
1025 * Reported length is a multiple of 48, so we can presumably
1026 * divide it by 48 to get the number of cells.
1028 proto_tree_add_text(atm_tree, tvb, 0, 0, "Cells: %u",
1029 reported_length/48);
1031 if ((pinfo->pseudo_header->atm.aal == AAL_5 ||
1032 pinfo->pseudo_header->atm.aal == AAL_SIGNALLING) &&
1033 length >= reported_length) {
1035 * XXX - what if the packet is truncated? Can that happen?
1036 * What if you capture with Windows Sniffer on an ATM link
1037 * and tell it not to save the entire packet? What happens
1040 aal5_length = tvb_get_ntohs(tvb, length - 6);
1043 * Check for sanity in the AAL5 length. It must be > 0
1044 * and must be less than the amount of space left after
1045 * we remove the trailer.
1047 * If it's not sane, assume we don't have a trailer.
1049 if (aal5_length > 0 && aal5_length <= length - 8) {
1051 * How much padding is there?
1053 pad_length = length - aal5_length - 8;
1056 * There is no reason for more than 47 bytes of padding.
1057 * The most padding you can have would be 7 bytes at the
1058 * end of the next-to-last cell (8 bytes after the end of
1059 * the data means you can fit the trailer in that cell),
1060 * plus 40 bytes in the last cell (with the last 8 bytes
1063 * If there's more than 47 bytes of padding, assume we don't
1066 if (pad_length <= 47) {
1068 if (pad_length > 0) {
1069 proto_tree_add_text(atm_tree, tvb, aal5_length, pad_length,
1072 proto_tree_add_text(atm_tree, tvb, length - 8, 1, "AAL5 UU: 0x%02x",
1073 tvb_get_guint8(tvb, length - 8));
1074 proto_tree_add_text(atm_tree, tvb, length - 7, 1, "AAL5 CPI: 0x%02x",
1075 tvb_get_guint8(tvb, length - 7));
1076 proto_tree_add_text(atm_tree, tvb, length - 6, 2, "AAL5 len: %u",
1078 crc = tvb_get_ntohl(tvb, length - 4);
1079 calc_crc = update_crc(0xFFFFFFFF, tvb_get_ptr(tvb, 0, length),
1081 proto_tree_add_text(atm_tree, tvb, length - 4, 4,
1082 "AAL5 CRC: 0x%08X (%s)", crc,
1083 (calc_crc == 0xC704DD7B) ? "correct" : "incorrect");
1085 next_tvb = tvb_new_subset(tvb, 0, aal5_length, aal5_length);
1091 switch (pinfo->pseudo_header->atm.aal) {
1093 case AAL_SIGNALLING:
1094 call_dissector(sscop_handle, next_tvb, pinfo, tree);
1098 switch (pinfo->pseudo_header->atm.type) {
1101 call_dissector(fr_handle, next_tvb, pinfo, tree);
1105 call_dissector(llc_handle, next_tvb, pinfo, tree);
1109 call_dissector(lane_handle, next_tvb, pinfo, tree);
1113 call_dissector(ilmi_handle, next_tvb, pinfo, tree);
1118 gboolean decoded = FALSE;
1120 if (tvb_length(next_tvb) > 7) /* sizeof(octet) */
1123 tvb_memcpy(next_tvb, octet, 0, sizeof(octet));
1126 if (octet[0] == 0xaa
1128 && octet[2] == 0x03) /* LLC SNAP as per RFC2684 */
1130 call_dissector(llc_handle, next_tvb, pinfo, tree);
1132 else if ((pntohs(octet) & 0xff) == PPP_IP)
1134 call_dissector(ppp_handle, next_tvb, pinfo, tree);
1136 else if (pntohs(octet) == 0x00)
1138 /* assume vc muxed bridged ethernet */
1139 proto_tree_add_text(tree, tvb, 0, 2, "Pad: 0x0000");
1140 next_tvb = tvb_new_subset(tvb, 2, -1, -1);
1141 call_dissector(eth_handle, next_tvb, pinfo, tree);
1143 else if (octet[2] == 0x03 && /* NLPID */
1144 ((octet[3] == 0xcc || /* IPv4 */
1145 octet[3] == 0x8e) || /* IPv6 */
1146 (octet[3] == 0x00 && /* Eth */
1147 octet[4] == 0x80))) /* Eth */
1149 /* assume network interworking with FR 2 byte header */
1150 call_dissector(fr_handle, next_tvb, pinfo, tree);
1152 else if (octet[4] == 0x03 && /* NLPID */
1153 ((octet[5] == 0xcc || /* IPv4 */
1154 octet[5] == 0x8e) || /* IPv6 */
1155 (octet[5] == 0x00 && /* Eth */
1156 octet[6] == 0x80))) /* Eth */
1158 /* assume network interworking with FR 4 byte header */
1159 call_dissector(fr_handle, next_tvb, pinfo, tree);
1161 else if (((octet[0] & 0xf0)== 0x40) ||
1162 ((octet[0] & 0xf0) == 0x60))
1164 call_dissector(ip_handle, next_tvb, pinfo, tree);
1172 if (tree && !decoded) {
1173 /* Dump it as raw data. */
1174 call_dissector(data_handle, next_tvb, pinfo, tree);
1182 switch (pinfo->pseudo_header->atm.type) {
1184 /* Skip first 4 bytes of message
1188 Ignoring for now... */
1189 proto_tree_add_uint(atm_tree, hf_atm_cid, tvb, 0, 0,
1190 pinfo->pseudo_header->atm.aal2_cid);
1191 proto_item_append_text(atm_ti, " (vpi=%u vci=%u cid=%u)",
1192 pinfo->pseudo_header->atm.vpi,
1193 pinfo->pseudo_header->atm.vci,
1194 pinfo->pseudo_header->atm.aal2_cid);
1196 next_tvb = tvb_new_subset(tvb, 4, -1, -1);
1197 call_dissector(fp_handle, next_tvb, pinfo, tree);
1202 /* Dump it as raw data. */
1203 call_dissector(data_handle, next_tvb, pinfo, tree);
1211 /* Dump it as raw data. */
1212 call_dissector(data_handle, next_tvb, pinfo, tree);
1219 * Charles Michael Heard's HEC code, from
1221 * http://www.cell-relay.com/cell-relay/publications/software/CRC/32bitCRC.tutorial.html
1223 * with the syndrome and error position tables initialized with values
1224 * computed by his "gen_syndrome_table()" and "gen_err_posn_table()" routines,
1225 * rather than by calling those routines at run time, and with various data
1226 * type cleanups and changes not to correct the header if a correctible
1227 * error was detected.
1229 #define COSET_LEADER 0x055 /* x^6 + x^4 + x^2 + 1 */
1231 static const guint8 syndrome_table[256] = {
1232 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
1233 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
1234 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
1235 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
1236 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
1237 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
1238 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
1239 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
1240 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
1241 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
1242 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
1243 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
1244 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
1245 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
1246 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
1247 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
1248 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
1249 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
1250 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
1251 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
1252 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
1253 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
1254 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
1255 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
1256 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
1257 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
1258 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
1259 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
1260 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
1261 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
1262 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
1263 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,
1266 #define NO_ERROR_DETECTED -128
1267 #define UNCORRECTIBLE_ERROR 128
1269 static const int err_posn_table[256] = {
1270 NO_ERROR_DETECTED, 39,
1271 38, UNCORRECTIBLE_ERROR,
1272 37, UNCORRECTIBLE_ERROR,
1273 UNCORRECTIBLE_ERROR, 31,
1274 36, UNCORRECTIBLE_ERROR,
1275 UNCORRECTIBLE_ERROR, 8,
1276 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1277 30, UNCORRECTIBLE_ERROR,
1278 35, UNCORRECTIBLE_ERROR,
1279 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1280 UNCORRECTIBLE_ERROR, 23,
1281 7, UNCORRECTIBLE_ERROR,
1282 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1283 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1284 29, UNCORRECTIBLE_ERROR,
1285 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1286 34, UNCORRECTIBLE_ERROR,
1287 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1288 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1289 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1290 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1291 22, UNCORRECTIBLE_ERROR,
1292 6, UNCORRECTIBLE_ERROR,
1293 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1294 UNCORRECTIBLE_ERROR, 0,
1295 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1296 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1297 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1298 28, UNCORRECTIBLE_ERROR,
1299 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1300 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1301 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1302 33, UNCORRECTIBLE_ERROR,
1303 UNCORRECTIBLE_ERROR, 10,
1304 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1305 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1306 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1307 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1308 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1309 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1310 UNCORRECTIBLE_ERROR, 12,
1311 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1312 21, UNCORRECTIBLE_ERROR,
1313 UNCORRECTIBLE_ERROR, 19,
1314 5, UNCORRECTIBLE_ERROR,
1315 UNCORRECTIBLE_ERROR, 17,
1316 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1317 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1318 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1319 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1320 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1321 UNCORRECTIBLE_ERROR, 3,
1322 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1323 UNCORRECTIBLE_ERROR, 15,
1324 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1325 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1326 27, UNCORRECTIBLE_ERROR,
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, UNCORRECTIBLE_ERROR,
1334 32, UNCORRECTIBLE_ERROR,
1335 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1336 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1337 9, UNCORRECTIBLE_ERROR,
1338 UNCORRECTIBLE_ERROR, 24,
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, UNCORRECTIBLE_ERROR,
1345 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1346 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1347 UNCORRECTIBLE_ERROR, 1,
1348 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1349 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1350 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1351 11, UNCORRECTIBLE_ERROR,
1352 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1353 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1354 20, UNCORRECTIBLE_ERROR,
1355 UNCORRECTIBLE_ERROR, 13,
1356 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1357 18, UNCORRECTIBLE_ERROR,
1358 4, UNCORRECTIBLE_ERROR,
1359 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1360 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1361 16, UNCORRECTIBLE_ERROR,
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, 25,
1370 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1371 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1372 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1373 2, UNCORRECTIBLE_ERROR,
1374 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1375 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1376 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1377 14, UNCORRECTIBLE_ERROR,
1378 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1379 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1380 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1381 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1382 26, UNCORRECTIBLE_ERROR,
1383 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1384 UNCORRECTIBLE_ERROR, 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, UNCORRECTIBLE_ERROR,
1393 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1394 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1395 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1396 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1397 UNCORRECTIBLE_ERROR, UNCORRECTIBLE_ERROR,
1401 * Return an indication of whether there was an error in the cell header
1402 * and, if so, where the error was, if it was correctable.
1405 get_header_err(const guint8 *cell_header)
1407 register guint8 syndrome;
1408 register int i, err_posn;
1411 for (i = 0; i < 4; i++)
1412 syndrome = syndrome_table[syndrome ^ cell_header[i]];
1413 syndrome ^= cell_header[4] ^ COSET_LEADER;
1415 err_posn = err_posn_table [syndrome];
1418 return NO_ERROR_DETECTED;
1419 else if (err_posn < 40)
1422 return UNCORRECTIBLE_ERROR;
1425 const value_string atm_pt_vals[] = {
1426 { 0, "User data cell, congestion not experienced, SDU-type = 0" },
1427 { 1, "User data cell, congestion not experienced, SDU-type = 1" },
1428 { 2, "User data cell, congestion experienced, SDU-type = 0" },
1429 { 3, "User data cell, congestion experienced, SDU-type = 1" },
1430 { 4, "Segment OAM F5 flow related cell" },
1431 { 5, "End-to-end OAM F5 flow related cell" },
1432 { 6, "VC resource management cell" },
1437 * Charles Michael Heard's CRC-10 code, from
1439 * http://www.cell-relay.com/cell-relay/publications/software/CRC/crc10.html
1441 * with the CRC table initialized with values computed by
1442 * his "gen_byte_crc10_table()" routine, rather than by calling that
1443 * routine at run time, and with various data type cleanups.
1445 static const guint16 byte_crc10_table[256] = {
1446 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
1447 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
1448 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce,
1449 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf,
1450 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d,
1451 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c,
1452 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac,
1453 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad,
1454 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b,
1455 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a,
1456 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a,
1457 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b,
1458 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259,
1459 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158,
1460 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268,
1461 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169,
1462 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377,
1463 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076,
1464 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346,
1465 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047,
1466 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315,
1467 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014,
1468 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324,
1469 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025,
1470 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3,
1471 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2,
1472 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382,
1473 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083,
1474 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1,
1475 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0,
1476 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0,
1477 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1,
1480 /* update the data block's CRC-10 remainder one byte at a time */
1482 update_crc10_by_bytes(guint16 crc10_accum, const guint8 *data_blk_ptr,
1487 for (i = 0; i < data_blk_size; i++) {
1488 crc10_accum = ((crc10_accum << 8) & 0x3ff)
1489 ^ byte_crc10_table[( crc10_accum >> 2) & 0xff]
1495 static const value_string st_vals[] = {
1503 #define OAM_TYPE_FM 1 /* Fault Management */
1504 #define OAM_TYPE_PM 2 /* Performance Management */
1505 #define OAM_TYPE_AD 8 /* Activation/Deactivation */
1507 static const value_string oam_type_vals[] = {
1508 { OAM_TYPE_FM, "Fault Management" },
1509 { OAM_TYPE_PM, "Performance Management" },
1510 { OAM_TYPE_AD, "Activation/Deactivation" },
1514 static const value_string ft_fm_vals[] = {
1515 { 0, "Alarm Indication Signal" },
1516 { 1, "Far End Receive Failure" },
1517 { 8, "OAM Cell Loopback" },
1518 { 4, "Continuity Check" },
1522 static const value_string ft_pm_vals[] = {
1523 { 0, "Forward Monitoring" },
1524 { 1, "Backward Reporting" },
1525 { 2, "Monitoring and Reporting" },
1529 static const value_string ft_ad_vals[] = {
1530 { 0, "Performance Monitoring" },
1531 { 1, "Continuity Check" },
1537 * Check for OAM cells.
1538 * OAM F4 is VCI 3 or 4 and PT 0X0.
1541 gboolean atm_is_oam_cell(const guint16 vci, const guint8 pt)
1543 return (((vci == 3 || vci == 4) && ((pt & 0x5) == 0))
1544 || ((pt & 0x6) == 0x4));
1549 dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1550 proto_tree *atm_tree, guint aal, gboolean nni,
1551 gboolean crc_stripped)
1554 proto_tree *aal_tree;
1561 guint16 aal3_4_hdr, aal3_4_trlr;
1566 const pwatm_private_data_t * pwpd = pinfo->private_data;
1571 * FF: ITU-T I.361 (Section 2.2) defines the cell header format
1572 * and encoding at UNI reference point as:
1587 octet = tvb_get_guint8(tvb, 0);
1588 proto_tree_add_text(atm_tree, tvb, 0, 1, "GFC: 0x%x", octet >> 4);
1589 vpi = (octet & 0xF) << 4;
1590 octet = tvb_get_guint8(tvb, 1);
1592 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1595 * FF: ITU-T I.361 (Section 2.3) defines the cell header format
1596 * and encoding at NNI reference point as:
1611 octet = tvb_get_guint8(tvb, 0);
1613 octet = tvb_get_guint8(tvb, 1);
1614 vpi |= (octet & 0xF0) >> 4;
1615 proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
1618 vci = (octet & 0x0F) << 12;
1619 octet = tvb_get_guint8(tvb, 2);
1621 octet = tvb_get_guint8(tvb, 3);
1623 proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 1, 3, vci);
1624 pt = (octet >> 1) & 0x7;
1625 proto_tree_add_text(atm_tree, tvb, 3, 1, "Payload Type: %s",
1626 val_to_str(pt, atm_pt_vals, "Unknown (%u)"));
1627 proto_tree_add_text(atm_tree, tvb, 3, 1, "Cell Loss Priority: %s",
1628 (octet & 0x01) ? "Low priority" : "High priority");
1630 if (!crc_stripped) {
1632 * FF: parse the Header Error Check (HEC).
1634 ti = proto_tree_add_text(atm_tree, tvb, 4, 1,
1635 "Header Error Check: 0x%02x",
1636 tvb_get_guint8(tvb, 4));
1637 err = get_header_err(tvb_get_ptr(tvb, 0, 5));
1638 if (err == NO_ERROR_DETECTED)
1639 proto_item_append_text(ti, " (correct)");
1640 else if (err == UNCORRECTIBLE_ERROR)
1641 proto_item_append_text(ti, " (uncorrectable error)");
1643 proto_item_append_text(ti, " (error in bit %d)", err);
1647 * FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
1648 * Cell Mode) the Header Error Check (HEC) field is stripped.
1649 * So we do nothing here.
1656 offset = 0; /* For PWs. Header is decoded by PW dissector.*/
1657 pwpd = pinfo->private_data;
1664 * Check for OAM cells.
1665 * XXX - do this for all AAL values, overriding whatever information
1666 * Wiretap got from the file?
1668 if (aal == AAL_USER) {
1669 if (atm_is_oam_cell(vci,pt)) {
1677 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL1");
1678 if (check_col(pinfo->cinfo, COL_INFO))
1679 col_clear(pinfo->cinfo, COL_INFO);
1680 ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, FALSE);
1681 aal_tree = proto_item_add_subtree(ti, ett_aal1);
1682 octet = tvb_get_guint8(tvb, offset);
1683 proto_tree_add_text(aal_tree, tvb, offset, 1, "CSI: %u", octet >> 7);
1684 proto_tree_add_text(aal_tree, tvb, offset, 1, "Sequence Count: %u",
1685 (octet >> 4) & 0x7);
1686 if (check_col(pinfo->cinfo, COL_INFO)) {
1687 col_add_fstr(pinfo->cinfo, COL_INFO, "Sequence count = %u",
1688 (octet >> 4) & 0x7);
1690 proto_tree_add_text(aal_tree, tvb, offset, 1, "CRC: 0x%x",
1691 (octet >> 1) & 0x7);
1692 proto_tree_add_text(aal_tree, tvb, offset, 1, "Parity: %u",
1696 proto_tree_add_text(aal_tree, tvb, offset, 47, "Payload");
1701 * XXX - or should this be the CS PDU?
1703 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL3/4");
1704 if (check_col(pinfo->cinfo, COL_INFO))
1705 col_clear(pinfo->cinfo, COL_INFO);
1706 ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, FALSE);
1707 aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
1708 aal3_4_hdr = tvb_get_ntohs(tvb, offset);
1709 if (check_col(pinfo->cinfo, COL_INFO)) {
1710 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, sequence number = %u",
1711 val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"),
1712 (aal3_4_hdr >> 10) & 0xF);
1714 proto_tree_add_text(aal_tree, tvb, offset, 2, "Segment Type: %s",
1715 val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"));
1716 proto_tree_add_text(aal_tree, tvb, offset, 2, "Sequence Number: %u",
1717 (aal3_4_hdr >> 10) & 0xF);
1718 proto_tree_add_text(aal_tree, tvb, offset, 2, "Multiplex ID: %u",
1719 aal3_4_hdr & 0x3FF);
1722 proto_tree_add_text(aal_tree, tvb, offset, 44, "Information");
1725 aal3_4_trlr = tvb_get_ntohs(tvb, offset);
1726 proto_tree_add_text(aal_tree, tvb, offset, 2, "Length Indicator: %u",
1727 (aal3_4_trlr >> 10) & 0x3F);
1728 length = tvb_length_remaining(tvb, 5);
1729 crc10 = update_crc10_by_bytes(0, tvb_get_ptr(tvb, 5, length),
1731 proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC: 0x%03x (%s)",
1732 aal3_4_trlr & 0x3FF,
1733 (crc10 == 0) ? "correct" : "incorrect");
1737 if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
1739 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
1740 if (check_col(pinfo->cinfo, COL_INFO))
1741 col_clear(pinfo->cinfo, COL_INFO);
1743 ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, FALSE);
1744 aal_tree = proto_item_add_subtree(ti, ett_oamaal);
1745 octet = tvb_get_guint8(tvb, offset);
1746 if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
1748 if (check_col(pinfo->cinfo, COL_INFO))
1749 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
1750 val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
1752 proto_tree_add_text(aal_tree, tvb, offset, 1, "OAM Type: %s",
1753 val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
1754 switch (octet >> 4) {
1757 proto_tree_add_text(aal_tree, tvb, offset, 1, "Function Type: %s",
1758 val_to_str(octet & 0x0F, ft_fm_vals, "Unknown (%u)"));
1762 proto_tree_add_text(aal_tree, tvb, offset, 1, "Function Type: %s",
1763 val_to_str(octet & 0x0F, ft_pm_vals, "Unknown (%u)"));
1767 proto_tree_add_text(aal_tree, tvb, offset, 1, "Function Type: %s",
1768 val_to_str(octet & 0x0F, ft_ad_vals, "Unknown (%u)"));
1772 proto_tree_add_text(aal_tree, tvb, offset, 1, "Function Type: %u",
1778 proto_tree_add_text(aal_tree, tvb, offset, 45, "Function-specific information");
1781 length = tvb_length_remaining(tvb, 5);
1782 crc10 = update_crc10_by_bytes(0, tvb_get_ptr(tvb, 5, length),
1784 oam_crc = tvb_get_ntohs(tvb, offset);
1785 proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC-10: 0x%03x (%s)",
1787 (crc10 == 0) ? "correct" : "incorrect");
1791 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1792 call_dissector(data_handle, next_tvb, pinfo, tree);
1798 dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1801 proto_tree *atm_tree = NULL;
1802 proto_item *atm_ti = NULL;
1803 gboolean pseudowire_mode = (NULL != pinfo->private_data);
1805 if ( pinfo->pseudo_header->atm.aal == AAL_5 &&
1806 pinfo->pseudo_header->atm.type == TRAF_LANE &&
1807 dissect_lanesscop ) {
1808 pinfo->pseudo_header->atm.aal = AAL_SIGNALLING;
1811 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1813 if (!pseudowire_mode) {
1814 switch (pinfo->pseudo_header->atm.channel) {
1817 /* Traffic from DTE to DCE. */
1818 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1819 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
1820 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1821 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
1825 /* Traffic from DCE to DTE. */
1826 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
1827 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
1828 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
1829 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
1834 if (check_col(pinfo->cinfo, COL_INFO)) {
1835 if (pinfo->pseudo_header->atm.aal == AAL_5) {
1836 col_add_fstr(pinfo->cinfo, COL_INFO, "AAL5 %s",
1837 val_to_str(pinfo->pseudo_header->atm.type, aal5_hltype_vals,
1838 "Unknown traffic type (%u)"));
1840 col_add_str(pinfo->cinfo, COL_INFO,
1841 val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
1842 "Unknown AAL (%u)"));
1847 atm_ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
1848 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1850 if (!pseudowire_mode) {
1851 switch (pinfo->pseudo_header->atm.channel) {
1854 /* Traffic from DTE to DCE. */
1855 proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DTE->DCE");
1859 /* Traffic from DCE to DTE. */
1860 proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DCE->DTE");
1864 /* Sniffers shouldn't provide anything other than 0 or 1. */
1865 proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: %u",
1866 pinfo->pseudo_header->atm.channel);
1871 proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0,
1872 pinfo->pseudo_header->atm.aal,
1874 val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
1875 "Unknown AAL (%u)"));
1877 if (pinfo->pseudo_header->atm.flags & ATM_RAW_CELL) {
1878 /* This is a single cell, with the cell header at the beginning. */
1879 proto_item_set_len(atm_ti, 5);
1880 dissect_atm_cell(tvb, pinfo, tree, atm_tree,
1881 pinfo->pseudo_header->atm.aal, FALSE, FALSE);
1883 /* This is a reassembled PDU. */
1884 dissect_reassembled_pdu(tvb, pinfo, tree, atm_tree, atm_ti, truncated);
1889 dissect_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1891 dissect_atm_common(tvb, pinfo, tree, TRUE);
1895 dissect_atm_untruncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1897 dissect_atm_common(tvb, pinfo, tree, FALSE);
1901 dissect_atm_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1903 proto_tree *atm_tree = NULL;
1904 proto_item *atm_ti = NULL;
1905 gboolean pseudowire_mode = (NULL != pinfo->private_data);
1907 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
1909 if (!pseudowire_mode) {
1911 atm_ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
1912 atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
1916 dissect_atm_cell(tvb, pinfo, tree, atm_tree, AAL_OAMCELL, FALSE, FALSE);
1921 proto_register_atm(void)
1923 static hf_register_info hf[] = {
1925 { "AAL", "atm.aal", FT_UINT8, BASE_DEC, VALS(aal_vals), 0x0,
1929 { "VPI", "atm.vpi", FT_UINT8, BASE_DEC, NULL, 0x0,
1933 { "VCI", "atm.vci", FT_UINT16, BASE_DEC, NULL, 0x0,
1937 { "CID", "atm.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
1941 static gint *ett[] = {
1948 &ett_atm_lane_lc_lan_dest,
1949 &ett_atm_lane_lc_lan_dest_rd,
1950 &ett_atm_lane_lc_flags,
1951 &ett_atm_lane_lc_tlv,
1954 module_t *atm_module;
1956 proto_atm = proto_register_protocol("ATM", "ATM", "atm");
1957 proto_aal1 = proto_register_protocol("ATM AAL1", "AAL1", "aal1");
1958 proto_aal3_4 = proto_register_protocol("ATM AAL3/4", "AAL3/4", "aal3_4");
1959 proto_oamaal = proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal");
1960 proto_register_field_array(proto_atm, hf, array_length(hf));
1961 proto_register_subtree_array(ett, array_length(ett));
1963 proto_ilmi = proto_register_protocol("ILMI", "ILMI", "ilmi");
1965 register_dissector("ilmi", dissect_ilmi, proto_ilmi);
1967 proto_atm_lane = proto_register_protocol("ATM LAN Emulation",
1968 "ATM LANE", "lane");
1970 register_dissector("lane", dissect_lane, proto_atm_lane);
1971 register_dissector("atm_untruncated", dissect_atm_untruncated, proto_atm);
1972 register_dissector("atm_truncated", dissect_atm, proto_atm);
1973 register_dissector("atm_oam_cell", dissect_atm_oam_cell, proto_oamaal);
1975 atm_module = prefs_register_protocol ( proto_atm, NULL );
1976 prefs_register_bool_preference ( atm_module, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
1977 "Autodection between LANE and SSCOP is hard. As default LANE is preferred",
1978 &dissect_lanesscop);
1982 proto_reg_handoff_atm(void)
1984 dissector_handle_t atm_handle, atm_untruncated_handle;
1987 * Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
1988 * SSCOP, LANE, and ILMI dissectors.
1990 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
1991 tr_handle = find_dissector("tr");
1992 fr_handle = find_dissector("fr");
1993 llc_handle = find_dissector("llc");
1994 sscop_handle = find_dissector("sscop");
1995 lane_handle = find_dissector("lane");
1996 ilmi_handle = find_dissector("ilmi");
1997 ppp_handle = find_dissector("ppp");
1998 eth_handle = find_dissector("eth");
1999 ip_handle = find_dissector("ip");
2000 data_handle = find_dissector("data");
2001 fp_handle = find_dissector("fp");
2003 atm_handle = create_dissector_handle(dissect_atm, proto_atm);
2004 dissector_add("wtap_encap", WTAP_ENCAP_ATM_PDUS, atm_handle);
2006 atm_untruncated_handle = create_dissector_handle(dissect_atm_untruncated,
2008 dissector_add("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,
2009 atm_untruncated_handle);