diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | file.c | 4 | ||||
-rw-r--r-- | packet-atm.c | 546 | ||||
-rw-r--r-- | packet-eth.c | 34 | ||||
-rw-r--r-- | packet-lapb.c | 8 | ||||
-rw-r--r-- | packet-tr.c | 111 | ||||
-rw-r--r-- | packet-x25.c | 42 | ||||
-rw-r--r-- | packet.c | 9 | ||||
-rw-r--r-- | packet.h | 18 | ||||
-rw-r--r-- | proto.c | 4 | ||||
-rw-r--r-- | wiretap/ngsniffer.c | 330 | ||||
-rw-r--r-- | wiretap/radcom.c | 2 | ||||
-rw-r--r-- | wiretap/wtap.h | 84 |
13 files changed, 795 insertions, 398 deletions
diff --git a/Makefile.am b/Makefile.am index 97e530d104..1011f256f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,7 @@ ethereal_SOURCES = \ packet-aarp.c \ packet-arp.c \ packet-atalk.c \ + packet-atm.c \ packet-bootp.c \ packet-cdp.c \ packet-clip.c \ @@ -1,7 +1,7 @@ /* file.c * File I/O routines * - * $Id: file.c,v 1.75 1999/08/19 05:31:22 guy Exp $ + * $Id: file.c,v 1.76 1999/08/20 06:55:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -557,7 +557,7 @@ wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset, fdata->lnk_t = phdr->pkt_encap; fdata->abs_secs = phdr->ts.tv_sec; fdata->abs_usecs = phdr->ts.tv_usec; - fdata->flags = phdr->flags; + fdata->pseudo_header = phdr->pseudo_header; fdata->cinfo = NULL; passed = TRUE; diff --git a/packet-atm.c b/packet-atm.c new file mode 100644 index 0000000000..71b0d191c5 --- /dev/null +++ b/packet-atm.c @@ -0,0 +1,546 @@ +/* packet-atm.c + * Routines for ATM packet disassembly + * + * $Id: packet-atm.c,v 1.1 1999/08/20 06:55:05 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@zing.org> + * Copyright 1998 Gerald Combs + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#include <stdio.h> +#include <glib.h> +#include "packet.h" +#include "resolv.h" + +static int proto_atm = -1; +static int proto_atm_lane = -1; + +/* + * See + * + * http://www.atmforum.org/atmforum/specs/approved.html + * + * for a number of ATM Forum specifications, e.g. the LAN Emulation + * over ATM 1.0 spec, whence I got most of this. + */ + +/* LE Control opcodes */ +#define LE_CONFIGURE_REQUEST 0x0001 +#define LE_CONFIGURE_RESPONSE 0x0101 +#define LE_JOIN_REQUEST 0x0002 +#define LE_JOIN_RESPONSE 0x0102 +#define READY_QUERY 0x0003 +#define READY_IND 0x0103 +#define LE_REGISTER_REQUEST 0x0004 +#define LE_REGISTER_RESPONSE 0x0104 +#define LE_UNREGISTER_REQUEST 0x0005 +#define LE_UNREGISTER_RESPONSE 0x0105 +#define LE_ARP_REQUEST 0x0006 +#define LE_ARP_RESPONSE 0x0106 +#define LE_FLUSH_REQUEST 0x0007 +#define LE_FLUSH_RESPONSE 0x0107 +#define LE_NARP_REQUEST 0x0008 +#define LE_TOPOLOGY_REQUEST 0x0009 + +static const value_string le_control_opcode_vals[] = { + { LE_CONFIGURE_REQUEST, "LE_CONFIGURE_REQUEST" }, + { LE_CONFIGURE_RESPONSE, "LE_CONFIGURE_RESPONSE" }, + { LE_JOIN_REQUEST, "LE_JOIN_REQUEST" }, + { LE_JOIN_RESPONSE, "LE_JOIN_RESPONSE" }, + { READY_QUERY, "READY_QUERY" }, + { READY_IND, "READY_IND" }, + { LE_REGISTER_REQUEST, "LE_REGISTER_REQUEST" }, + { LE_REGISTER_RESPONSE, "LE_REGISTER_RESPONSE" }, + { LE_UNREGISTER_REQUEST, "LE_UNREGISTER_REQUEST" }, + { LE_UNREGISTER_RESPONSE, "LE_UNREGISTER_RESPONSE" }, + { LE_ARP_REQUEST, "LE_ARP_REQUEST" }, + { LE_ARP_RESPONSE, "LE_ARP_RESPONSE" }, + { LE_FLUSH_REQUEST, "LE_FLUSH_REQUEST" }, + { LE_FLUSH_RESPONSE, "LE_FLUSH_RESPONSE" }, + { LE_NARP_REQUEST, "LE_NARP_REQUEST" }, + { LE_TOPOLOGY_REQUEST, "LE_TOPOLOGY_REQUEST" }, + { 0, NULL } +}; + +/* LE Control statuses */ +static const value_string le_control_status_vals[] = { + { 0, "Success" }, + { 1, "Version not supported" }, + { 2, "Invalid request parameters" }, + { 4, "Duplicate LAN destination registration" }, + { 5, "Duplicate ATM address" }, + { 6, "Insufficient resources to grant request" }, + { 7, "Access denied" }, + { 8, "Invalid REQUESTOR-ID" }, + { 9, "Invalid LAN destination" }, + { 10, "Invalid ATM address" }, + { 20, "No configuraton" }, + { 21, "LE_CONFIGURE error" }, + { 22, "Insufficient information" }, + { 0, NULL } +}; + +/* LE Control LAN destination tags */ +#define TAG_NOT_PRESENT 0x0000 +#define TAG_MAC_ADDRESS 0x0001 +#define TAG_ROUTE_DESCRIPTOR 0x0002 + +static const value_string le_control_landest_tag_vals[] = { + { TAG_NOT_PRESENT, "Not present" }, + { TAG_MAC_ADDRESS, "MAC address" }, + { TAG_ROUTE_DESCRIPTOR, "Route descriptor" }, + { 0, NULL } +}; + +/* LE Control LAN types */ +#define LANT_UNSPEC 0x00 +#define LANT_802_3 0x01 +#define LANT_802_5 0x02 + +static const value_string le_control_lan_type_vals[] = { + { LANT_UNSPEC, "Unspecified" }, + { LANT_802_3, "Ethernet/802.3" }, + { LANT_802_5, "802.5" }, + { 0, NULL } +}; + +static void +dissect_le_client(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + proto_item *ti; + proto_tree *lane_tree; + + if (tree) { + ti = proto_tree_add_item_format(tree, proto_atm_lane, offset, 2, NULL, + "ATM LANE"); + lane_tree = proto_item_add_subtree(ti, ETT_ATM_LANE); + + proto_tree_add_text(lane_tree, offset, 2, "LE Client: 0x%04X", + pntohs(&pd[offset])); + } +} + +static void +dissect_lan_destination(const u_char *pd, int offset, const char *type, proto_tree *tree) +{ + proto_item *td; + proto_tree *dest_tree; + guint16 tag; + proto_item *trd; + proto_tree *rd_tree; + guint16 route_descriptor; + + td = proto_tree_add_text(tree, offset, 8, "%s LAN destination", + type); + dest_tree = proto_item_add_subtree(td, ETT_ATM_LANE_LC_LAN_DEST); + tag = pntohs(&pd[offset]); + proto_tree_add_text(dest_tree, offset, 2, "Tag: %s", + val_to_str(tag, le_control_landest_tag_vals, + "Unknown (%x)")); + offset += 2; + + switch (tag) { + + case TAG_MAC_ADDRESS: + proto_tree_add_text(dest_tree, offset, 6, "MAC address: %s", + ether_to_str((u_char *)&pd[offset])); + break; + + case TAG_ROUTE_DESCRIPTOR: + offset += 4; + route_descriptor = pntohs(&pd[offset]); + trd = proto_tree_add_text(dest_tree, offset, 2, "Route descriptor: 0x%02X", + route_descriptor); + rd_tree = proto_item_add_subtree(td, ETT_ATM_LANE_LC_LAN_DEST_RD); + proto_tree_add_text(rd_tree, offset, 2, + decode_numeric_bitfield(route_descriptor, 0xFFF0, 2*8, + "LAN ID = %u")); + proto_tree_add_text(rd_tree, offset, 2, + decode_numeric_bitfield(route_descriptor, 0x000F, 2*8, + "Bridge number = %u")); + break; + } +} + +static void +dissect_le_control(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + proto_item *ti; + proto_tree *lane_tree; + proto_item *tf; + proto_tree *flags_tree; + guint16 opcode; + guint16 flags; + + if (check_col(fd, COL_INFO)) + col_add_str(fd, COL_INFO, "LE Control"); + + if (tree) { + ti = proto_tree_add_item_format(tree, proto_atm_lane, offset, 108, NULL, + "ATM LANE"); + lane_tree = proto_item_add_subtree(ti, ETT_ATM_LANE); + + proto_tree_add_text(lane_tree, offset, 2, "Marker: 0x%04X", + pntohs(&pd[offset])); + offset += 2; + + proto_tree_add_text(lane_tree, offset, 1, "Protocol: 0x%02X", + pd[offset]); + offset += 1; + + proto_tree_add_text(lane_tree, offset, 1, "Version: 0x%02X", + pd[offset]); + offset += 1; + + opcode = pntohs(&pd[offset]); + proto_tree_add_text(lane_tree, offset, 2, "Opcode: %s", + val_to_str(opcode, le_control_opcode_vals, + "Unknown (%x)")); + offset += 2; + + if (opcode == READY_QUERY || opcode == READY_IND) { + /* There's nothing more in this packet. */ + return; + } + + if (opcode & 0x0100) { + /* Response; decode status. */ + proto_tree_add_text(lane_tree, offset, 2, "Status: %s", + val_to_str(pntohs(&pd[offset]), le_control_status_vals, + "Unknown (%x)")); + } + offset += 2; + + proto_tree_add_text(lane_tree, offset, 4, "Transaction ID: 0x%08X", + pntohl(&pd[offset])); + offset += 4; + + proto_tree_add_text(lane_tree, offset, 2, "Requester LECID: 0x%04X", + pntohs(&pd[offset])); + offset += 2; + + flags = pntohs(&pd[offset]); + tf = proto_tree_add_text(lane_tree, offset, 2, "Flags: 0x%04X", + pntohs(&pd[offset])); + flags_tree = proto_item_add_subtree(tf, ETT_ATM_LANE_LC_FLAGS); + proto_tree_add_text(flags_tree, offset, 2, "%s", + decode_boolean_bitfield(flags, 0x0001, 8*2, + "Remote address", "Local address")); + proto_tree_add_text(flags_tree, offset, 2, "%s", + decode_boolean_bitfield(flags, 0x0080, 8*2, + "Proxy", "Not proxy")); + proto_tree_add_text(flags_tree, offset, 2, "%s", + decode_boolean_bitfield(flags, 0x0100, 8*2, + "Topology change", "No topology change")); + offset += 2; + + dissect_lan_destination(pd, offset, "Source", lane_tree); + offset += 8; + + dissect_lan_destination(pd, offset, "Target", lane_tree); + offset += 8; + + proto_tree_add_text(lane_tree, offset, 20, "Source ATM Address: %s", + bytes_to_str(&pd[offset], 20)); + offset += 20; + + proto_tree_add_text(lane_tree, offset, 1, "LAN type: %s", + val_to_str(pd[offset], le_control_lan_type_vals, + "Unknown (%x)")); + offset += 1; + + proto_tree_add_text(lane_tree, offset, 1, "Maximum frame size: %u", + pd[offset]); + offset += 1; + + proto_tree_add_text(lane_tree, offset, 1, "Number of TLVs: %u", + pd[offset]); + offset += 1; + + proto_tree_add_text(lane_tree, offset, 1, "ELAN name size: %u", + pd[offset]); + offset += 1; + + proto_tree_add_text(lane_tree, offset, 20, "Target ATM Address: %s", + bytes_to_str(&pd[offset], 20)); + offset += 20; + + proto_tree_add_text(lane_tree, offset, 32, "ELAN name: %s", + bytes_to_str(&pd[offset], 32)); + offset += 32; + } +} + +static void +dissect_lane(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "ATM LANE"); + if (check_col(fd, COL_INFO)) + col_add_str(fd, COL_INFO, "ATM LANE"); + + /* Is it LE Control, 802.3, 802.5, or "none of the above"? */ + switch (fd->pseudo_header.ngsniffer_atm.AppHLType) { + + case AHLT_LANE_LE_CTRL: + dissect_le_control(pd, offset, fd, tree); + break; + + case AHLT_LANE_802_3: + case AHLT_LANE_802_3_MC: + dissect_le_client(pd, offset, fd, tree); + offset += 2; + + /* Dissect as Ethernet */ + dissect_eth(pd, offset, fd, tree); + break; + + case AHLT_LANE_802_5: + case AHLT_LANE_802_5_MC: + dissect_le_client(pd, offset, fd, tree); + offset += 2; + + /* Dissect as Token-Ring */ + dissect_tr(pd, offset, fd, tree); + break; + + default: + /* Dump it as raw data. */ + dissect_data(pd, offset, fd, tree); + break; + } +} + +/* AAL types */ +static const value_string aal_vals[] = { + { ATT_AAL_UNKNOWN, "Unknown AAL" }, + { ATT_AAL1, "AAL1" }, + { ATT_AAL3_4, "AAL3/4" }, + { ATT_AAL5, "AAL5" }, + { ATT_AAL_USER, "User AAL" }, + { ATT_AAL_SIGNALLING, "Signalling AAL" }, + { ATT_OAMCELL, "OAM cell" }, + { 0, NULL } +}; + +/* AAL5 higher-level traffic types */ +static const value_string aal5_hltype_vals[] = { + { ATT_HL_UNKNOWN, "Unknown traffic type" }, + { ATT_HL_LLCMX, "LLC multiplexed" }, + { ATT_HL_VCMX, "VC multiplexed" }, + { ATT_HL_LANE, "LANE" }, + { ATT_HL_ILMI, "ILMI" }, + { ATT_HL_FRMR, "Frame Relay" }, + { ATT_HL_SPANS, "FORE SPANS" }, + { ATT_HL_IPSILON, "Ipsilon" }, + { 0, NULL } +}; + +/* Traffic subtypes for VC multiplexed traffic */ +static const value_string vcmx_type_vals[] = { + { AHLT_UNKNOWN, "Unknown VC multiplexed traffic type" }, + { AHLT_VCMX_802_3_FCS, "802.3 FCS" }, + { AHLT_VCMX_802_4_FCS, "802.4 FCS" }, + { AHLT_VCMX_802_5_FCS, "802.5 FCS" }, + { AHLT_VCMX_FDDI_FCS, "FDDI FCS" }, + { AHLT_VCMX_802_6_FCS, "802.6 FCS" }, + { AHLT_VCMX_802_3, "802.3" }, + { AHLT_VCMX_802_4, "802.4" }, + { AHLT_VCMX_802_5, "802.5" }, + { AHLT_VCMX_FDDI, "FDDI" }, + { AHLT_VCMX_802_6, "802.6" }, + { AHLT_VCMX_FRAGMENTS, "Fragments" }, + { AHLT_VCMX_BPDU, "BPDU" }, + { 0, NULL } +}; + +/* Traffic subtypes for LANE traffic */ +static const value_string lane_type_vals[] = { + { AHLT_UNKNOWN, "Unknown LANE traffic type" }, + { AHLT_LANE_LE_CTRL, "LE Control" }, + { AHLT_LANE_802_3, "802.3" }, + { AHLT_LANE_802_5, "802.5" }, + { AHLT_LANE_802_3_MC, "802.3 multicast" }, + { AHLT_LANE_802_5_MC, "802.5 multicast" }, + { 0, NULL } +}; + +/* Traffic subtypes for Ipsilon traffic */ +static const value_string ipsilon_type_vals[] = { + { AHLT_UNKNOWN, "Unknown Ipsilon traffic type" }, + { AHLT_IPSILON_FT0, "Flow type 0" }, + { AHLT_IPSILON_FT1, "Flow type 1" }, + { AHLT_IPSILON_FT2, "Flow type 2" }, + { 0, NULL } +}; + +void +dissect_atm(const u_char *pd, frame_data *fd, proto_tree *tree) +{ + int offset = 0; + proto_tree *atm_tree; + proto_item *ti; + guint aal_type; + guint hl_type; + + aal_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_AALTYPE; + hl_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_HLTYPE; + + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "ATM"); + + switch (fd->pseudo_header.ngsniffer_atm.channel) { + + case 0: + /* Traffic from DCE to DTE. */ + if (check_col(fd, COL_RES_DL_DST)) + col_add_str(fd, COL_RES_DL_DST, "DTE"); + if (check_col(fd, COL_RES_DL_SRC)) + col_add_str(fd, COL_RES_DL_SRC, "DCE"); + break; + + case 1: + /* Traffic from DTE to DCE. */ + if (check_col(fd, COL_RES_DL_DST)) + col_add_str(fd, COL_RES_DL_DST, "DCE"); + if (check_col(fd, COL_RES_DL_SRC)) + col_add_str(fd, COL_RES_DL_SRC, "DTE"); + break; + } + + if (check_col(fd, COL_INFO)) { + if (aal_type == ATT_AAL5) { + col_add_fstr(fd, COL_INFO, "AAL5 %s", + val_to_str(hl_type, aal5_hltype_vals, + "Unknown traffic type (%x)")); + } else { + col_add_str(fd, COL_INFO, + val_to_str(aal_type, aal_vals, "Unknown AAL (%x)")); + } + } + + if (tree) { + ti = proto_tree_add_item_format(tree, proto_atm, 0, 0, NULL, + "ATM"); + atm_tree = proto_item_add_subtree(ti, ETT_ATM); + + proto_tree_add_text(atm_tree, 0, 0, "AAL: %s", + val_to_str(aal_type, aal_vals, "Unknown AAL (%x)")); + if (aal_type == ATT_AAL5) { + proto_tree_add_text(atm_tree, 0, 0, "Traffic type: %s", + val_to_str(hl_type, aal5_hltype_vals, "Unknown AAL5 traffic type (%x)")); + } + if (aal_type == ATT_AAL5) { + switch (hl_type) { + + case ATT_HL_VCMX: + proto_tree_add_text(atm_tree, 0, 0, "VC multiplexed traffic type: %s", + val_to_str(fd->pseudo_header.ngsniffer_atm.AppHLType, + vcmx_type_vals, "Unknown VCMX traffic type (%x)")); + break; + + case ATT_HL_LANE: + proto_tree_add_text(atm_tree, 0, 0, "LANE traffic type: %s", + val_to_str(fd->pseudo_header.ngsniffer_atm.AppHLType, + lane_type_vals, "Unknown LANE traffic type (%x)")); + break; + + case ATT_HL_IPSILON: + proto_tree_add_text(atm_tree, 0, 0, "Ipsilon traffic type: %s", + val_to_str(fd->pseudo_header.ngsniffer_atm.AppHLType, + ipsilon_type_vals, "Unknown Ipsilon traffic type (%x)")); + break; + } + } + proto_tree_add_text(atm_tree, 0, 0, "VPI: %u", + fd->pseudo_header.ngsniffer_atm.Vpi); + proto_tree_add_text(atm_tree, 0, 0, "VCI: %u", + fd->pseudo_header.ngsniffer_atm.Vci); + switch (fd->pseudo_header.ngsniffer_atm.channel) { + + case 0: + /* Traffic from DCE to DTE. */ + proto_tree_add_text(atm_tree, 0, 0, "Channel: DCE->DTE"); + break; + + case 1: + /* Traffic from DTE to DCE. */ + proto_tree_add_text(atm_tree, 0, 0, "Channel: DTE->DCE"); + break; + + default: + /* Sniffers shouldn't provide anything other than 0 or 1. */ + proto_tree_add_text(atm_tree, 0, 0, "Channel: %u", + fd->pseudo_header.ngsniffer_atm.channel); + break; + } + proto_tree_add_text(atm_tree, 0, 0, "Cells: %u", + fd->pseudo_header.ngsniffer_atm.cells); + if (aal_type == ATT_AAL5) { + proto_tree_add_text(atm_tree, 0, 0, "AAL5 U2U: %u", + fd->pseudo_header.ngsniffer_atm.aal5t_u2u); + proto_tree_add_text(atm_tree, 0, 0, "AAL5 len: %u", + fd->pseudo_header.ngsniffer_atm.aal5t_len); + proto_tree_add_text(atm_tree, 0, 0, "AAL5 checksum: 0x%08X", + fd->pseudo_header.ngsniffer_atm.aal5t_chksum); + } + } + + if (aal_type == ATT_AAL5) { + switch (hl_type) { + +#if 0 + case ATT_HL_LLCMX: + /* Dissect as WTAP_ENCAP_ATM_RFC1483 */ + break; +#endif + + case ATT_HL_LANE: + dissect_lane(pd, offset, fd, tree); + break; + + default: + if (tree) { + /* Dump it as raw data. */ + dissect_data(pd, offset, fd, tree); + break; + } + } + } else { + if (tree) { + /* Dump it as raw data. (Is this a single cell?) */ + dissect_data(pd, offset, fd, tree); + } + } +} + +void +proto_register_atm(void) +{ + proto_atm = proto_register_protocol("ATM", "atm"); + proto_atm_lane = proto_register_protocol("ATM LANE", "lane"); +} diff --git a/packet-eth.c b/packet-eth.c index 1cde4f4ff4..af8928ee31 100644 --- a/packet-eth.c +++ b/packet-eth.c @@ -1,7 +1,7 @@ /* packet-eth.c * Routines for ethernet packet disassembly * - * $Id: packet-eth.c,v 1.15 1999/08/18 00:57:50 guy Exp $ + * $Id: packet-eth.c,v 1.16 1999/08/20 06:55:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -104,27 +104,26 @@ capture_eth(const u_char *pd, guint32 cap_len, packet_counts *ld) { } void -dissect_eth(const u_char *pd, frame_data *fd, proto_tree *tree) { +dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { guint16 etype, length; - int offset = ETH_HEADER_SIZE; proto_tree *fh_tree = NULL; proto_item *ti; int ethhdr_type; /* the type of ethernet frame */ if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, get_ether_name((u_char *)&pd[0])); + col_add_str(fd, COL_RES_DL_DST, get_ether_name((u_char *)&pd[offset+0])); if (check_col(fd, COL_RES_DL_SRC)) - col_add_str(fd, COL_RES_DL_SRC, get_ether_name((u_char *)&pd[6])); + col_add_str(fd, COL_RES_DL_SRC, get_ether_name((u_char *)&pd[offset+6])); if (check_col(fd, COL_UNRES_DL_DST)) - col_add_str(fd, COL_UNRES_DL_DST, ether_to_str((u_char *)&pd[0])); + col_add_str(fd, COL_UNRES_DL_DST, ether_to_str((u_char *)&pd[offset+0])); if (check_col(fd, COL_UNRES_DL_SRC)) - col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str((u_char *)&pd[6])); + col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str((u_char *)&pd[offset+6])); if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "N/A"); if (check_col(fd, COL_INFO)) col_add_str(fd, COL_INFO, "Ethernet II"); - etype = (pd[12] << 8) | pd[13]; + etype = (pd[offset+12] << 8) | pd[offset+13]; /* either ethernet802.3 or ethernet802.2 */ if (etype <= IEEE_802_3_MAX_LEN) { @@ -136,7 +135,7 @@ dissect_eth(const u_char *pd, frame_data *fd, proto_tree *tree) { (IPX/SPX is they only thing that can be contained inside a straight 802.3 packet). A non-0xffff value means that there's an 802.2 layer inside the 802.3 layer */ - if (pd[14] == 0xff && pd[15] == 0xff) { + if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) { ethhdr_type = ETHERNET_802_3; } else { @@ -152,8 +151,8 @@ dissect_eth(const u_char *pd, frame_data *fd, proto_tree *tree) { fh_tree = proto_item_add_subtree(ti, ETT_IEEE8023); - proto_tree_add_item(fh_tree, hf_eth_dst, 0, 6, &pd[0]); - proto_tree_add_item(fh_tree, hf_eth_src, 6, 6, &pd[6]); + proto_tree_add_item(fh_tree, hf_eth_dst, 0, 6, &pd[offset+0]); + proto_tree_add_item(fh_tree, hf_eth_src, 6, 6, &pd[offset+6]); proto_tree_add_item(fh_tree, hf_eth_len, 12, 2, length); /* Convert the LLC length from the 802.3 header to a total @@ -176,15 +175,16 @@ dissect_eth(const u_char *pd, frame_data *fd, proto_tree *tree) { fh_tree = proto_item_add_subtree(ti, ETT_ETHER2); - proto_tree_add_item_format(fh_tree, hf_eth_dst, 0, 6, &pd[0], - "Destination: %s (%s)", ether_to_str((guint8 *) &pd[0]), - get_ether_name((u_char *) &pd[0])); + proto_tree_add_item_format(fh_tree, hf_eth_dst, 0, 6, &pd[offset+0], + "Destination: %s (%s)", ether_to_str((guint8 *) &pd[offset+0]), + get_ether_name((u_char *) &pd[offset+0])); - proto_tree_add_item_format(fh_tree, hf_eth_src, 6, 6, &pd[6], - "Source: %s (%s)", ether_to_str((guint8 *) &pd[6]), - get_ether_name((u_char *) &pd[6])); + proto_tree_add_item_format(fh_tree, hf_eth_src, 6, 6, &pd[offset+6], + "Source: %s (%s)", ether_to_str((guint8 *) &pd[offset+6]), + get_ether_name((u_char *) &pd[offset+6])); } } + offset += ETH_HEADER_SIZE; switch (ethhdr_type) { case ETHERNET_802_3: diff --git a/packet-lapb.c b/packet-lapb.c index 1a985907ce..c4cb9d203e 100644 --- a/packet-lapb.c +++ b/packet-lapb.c @@ -2,7 +2,7 @@ * Routines for lapb frame disassembly * Olivier Abad <abad@daba.dhis.org> * - * $Id: packet-lapb.c,v 1.3 1999/08/05 02:26:21 guy Exp $ + * $Id: packet-lapb.c,v 1.4 1999/08/20 06:55:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -55,7 +55,7 @@ dissect_lapb(const u_char *pd, frame_data *fd, proto_tree *tree) if(check_col(fd, COL_RES_DL_SRC)) col_add_fstr(fd, COL_RES_DL_SRC, "0x%02X", pd[0]); - if (fd->flags & FROM_DCE) { + if (fd->pseudo_header.x25.flags & FROM_DCE) { if(check_col(fd, COL_RES_DL_DST)) col_add_str(fd, COL_RES_DL_DST, "DTE"); if(check_col(fd, COL_RES_DL_SRC)) @@ -68,8 +68,8 @@ dissect_lapb(const u_char *pd, frame_data *fd, proto_tree *tree) col_add_str(fd, COL_RES_DL_SRC, "DTE"); } - if (((fd->flags & FROM_DCE) && pd[0] == 0x01) || - (!(fd->flags & FROM_DCE) && pd[0] == 0x03)) + if (((fd->pseudo_header.x25.flags & FROM_DCE) && pd[0] == 0x01) || + (!(fd->pseudo_header.x25.flags & FROM_DCE) && pd[0] == 0x03)) is_response = TRUE; else is_response = FALSE; diff --git a/packet-tr.c b/packet-tr.c index fe59c7216c..7553b047f8 100644 --- a/packet-tr.c +++ b/packet-tr.c @@ -2,7 +2,7 @@ * Routines for Token-Ring packet disassembly * Gilbert Ramirez <gram@verdict.uthscsa.edu> * - * $Id: packet-tr.c,v 1.19 1999/08/10 02:54:59 gram Exp $ + * $Id: packet-tr.c,v 1.20 1999/08/20 06:55:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@unicom.net> @@ -111,7 +111,7 @@ static const value_string direction_vals[] = { }; static void -add_ring_bridge_pairs(int rcf_len, const u_char *pd, proto_tree *tree); +add_ring_bridge_pairs(int rcf_len, const u_char *pd, int offset, proto_tree *tree); void capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) { @@ -204,11 +204,10 @@ capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) { void -dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { +dissect_tr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { proto_tree *tr_tree, *bf_tree; proto_item *ti; - int offset = 14; int source_routed = 0; int frame_type; @@ -232,14 +231,14 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { char *fc[] = { "MAC", "LLC", "Reserved", "Unknown" }; /* get the data */ - memcpy(&trn_ac, &pd[0], sizeof(guint8)); - memcpy(&trn_fc, &pd[1], sizeof(guint8)); - memcpy(trn_dhost, &pd[2], 6 * sizeof(guint8)); - memcpy(trn_shost, &pd[8], 6 * sizeof(guint8)); - memcpy(&trn_rcf, &pd[14], sizeof(guint16)); - memcpy(trn_rseg, &pd[16], 8 * sizeof(guint16)); - - memcpy(trn_shost_nonsr, &pd[8], 6 * sizeof(guint8)); + memcpy(&trn_ac, &pd[offset+0], sizeof(guint8)); + memcpy(&trn_fc, &pd[offset+1], sizeof(guint8)); + memcpy(trn_dhost, &pd[offset+2], 6 * sizeof(guint8)); + memcpy(trn_shost, &pd[offset+8], 6 * sizeof(guint8)); + memcpy(&trn_rcf, &pd[offset+14], sizeof(guint16)); + memcpy(trn_rseg, &pd[offset+16], 8 * sizeof(guint16)); + + memcpy(trn_shost_nonsr, &pd[offset+8], 6 * sizeof(guint8)); trn_shost_nonsr[0] &= 127; frame_type = (trn_fc & 192) >> 6; @@ -247,7 +246,7 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { this packet is source-routed */ source_routed = trn_shost[0] & 128; - trn_rif_bytes = pd[14] & 31; + trn_rif_bytes = pd[offset+14] & 31; /* sometimes we have a RCF but no RIF... half source-routed? */ /* I'll check for 2 bytes of RIF and the 0x70 byte */ @@ -263,18 +262,20 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { * my RIF fields. */ else if ( ( - pd[0x0e + trn_rif_bytes] == 0xaa && - pd[0x0f + trn_rif_bytes] == 0xaa && - pd[0x10 + trn_rif_bytes] == 0x03) || + pd[offset + 0x0e + trn_rif_bytes] == 0xaa && + pd[offset + 0x0f + trn_rif_bytes] == 0xaa && + pd[offset + 0x10 + trn_rif_bytes] == 0x03) || ( - pd[0x0e + trn_rif_bytes] == 0xe0 && - pd[0x0f + trn_rif_bytes] == 0xe0) ) { + pd[offset + 0x0e + trn_rif_bytes] == 0xe0 && + pd[offset + 0x0f + trn_rif_bytes] == 0xe0) ) { source_routed = 1; } /* else { - printf("0e+%d = %02X 0f+%d = %02X\n", trn_rif_bytes, pd[0x0e + trn_rif_bytes], - trn_rif_bytes, pd[0x0f + trn_rif_bytes]); + printf("0e+%d = %02X 0f+%d = %02X\n", trn_rif_bytes, + pd[offset + 0x0e + trn_rif_bytes], + trn_rif_bytes, + pd[offset + 0x0f + trn_rif_bytes]); } */ } @@ -293,17 +294,20 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { if ((source_routed && trn_rif_bytes == 2 && frame_type == 1) || (!source_routed && frame_type == 1)) { /* look for SNAP or IPX only */ - if ( (pd[0x20] == 0xaa && pd[0x21] == 0xaa && pd[0x22] == 03) || - (pd[0x20] == 0xe0 && pd[0x21] == 0xe0) ) { + if ( (pd[offset + 0x20] == 0xaa && + pd[offset + 0x21] == 0xaa && + pd[offset + 0x22] == 03) + || + (pd[offset + 0x20] == 0xe0 && + pd[offset + 0x21] == 0xe0) ) { actual_rif_bytes = 18; } } - offset += actual_rif_bytes; - /* information window */ if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, ether_to_str((guint8 *)&pd[2])); + col_add_str(fd, COL_RES_DL_DST, + ether_to_str((guint8 *)&pd[offset + 2])); if (check_col(fd, COL_RES_DL_SRC)) col_add_str(fd, COL_RES_DL_SRC, ether_to_str(trn_shost_nonsr)); if (check_col(fd, COL_PROTOCOL)) @@ -314,57 +318,58 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { /* protocol analysis tree */ if (tree) { /* Create Token-Ring Tree */ - ti = proto_tree_add_item(tree, proto_tr, 0, 14 + actual_rif_bytes, NULL); + ti = proto_tree_add_item(tree, proto_tr, offset, 14 + actual_rif_bytes, NULL); tr_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING); /* Create the Access Control bitfield tree */ - ti = proto_tree_add_item_format(tr_tree, hf_tr_ac, 0, 1, trn_ac, + ti = proto_tree_add_item_format(tr_tree, hf_tr_ac, offset, 1, trn_ac, "Access Control (0x%02x)", trn_ac); bf_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING_AC); - proto_tree_add_item_format(bf_tree, hf_tr_priority, 0, 1, trn_ac & 0xe0, + proto_tree_add_item_format(bf_tree, hf_tr_priority, offset, 1, trn_ac & 0xe0, decode_numeric_bitfield(trn_ac, 0xe0, 8, "Priority = %d")); - proto_tree_add_item_format(bf_tree, hf_tr_frame, 0, 1, trn_ac & 0x10, + proto_tree_add_item_format(bf_tree, hf_tr_frame, offset, 1, trn_ac & 0x10, decode_enumerated_bitfield(trn_ac, 0x10, 8, ac_vals, "%s")); - proto_tree_add_item_format(bf_tree, hf_tr_monitor_cnt, 0, 1, trn_ac & 0x08, + proto_tree_add_item_format(bf_tree, hf_tr_monitor_cnt, offset, 1, trn_ac & 0x08, decode_numeric_bitfield(trn_ac, 0x08, 8, "Monitor Count")); - proto_tree_add_item_format(bf_tree, hf_tr_priority_reservation, 0, 1, trn_ac & 0x07, + proto_tree_add_item_format(bf_tree, hf_tr_priority_reservation, offset, 1, trn_ac & 0x07, decode_numeric_bitfield(trn_ac, 0x07, 8, "Priority Reservation = %d")); /* Create the Frame Control bitfield tree */ - ti = proto_tree_add_item_format(tr_tree, hf_tr_fc, 1, 1, trn_fc, + ti = proto_tree_add_item_format(tr_tree, hf_tr_fc, offset + 1, 1, trn_fc, "Frame Control (0x%02x)", trn_fc); bf_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING_FC); - proto_tree_add_item_format(bf_tree, hf_tr_fc_type, 1, 1, trn_fc & 0xc0, + proto_tree_add_item_format(bf_tree, hf_tr_fc_type, offset + 1, 1, trn_fc & 0xc0, decode_enumerated_bitfield(trn_fc, 0xc0, 8, frame_vals, "%s")); - proto_tree_add_item_format(bf_tree, hf_tr_fc_pcf, 1, 1, trn_fc & 0x0f, + proto_tree_add_item_format(bf_tree, hf_tr_fc_pcf, offset + 1, 1, trn_fc & 0x0f, decode_enumerated_bitfield(trn_fc, 0x0f, 8, pcf_vals, "%s")); - proto_tree_add_item(tr_tree, hf_tr_dst, 2, 6, trn_dhost); - proto_tree_add_item(tr_tree, hf_tr_src, 8, 6, trn_shost); - proto_tree_add_item_hidden(tr_tree, hf_tr_sr, 8, 1, source_routed); + proto_tree_add_item(tr_tree, hf_tr_dst, offset + 2, 6, trn_dhost); + proto_tree_add_item(tr_tree, hf_tr_src, offset + 8, 6, trn_shost); + proto_tree_add_item_hidden(tr_tree, hf_tr_sr, offset + 8, 1, source_routed); /* non-source-routed version of src addr */ - proto_tree_add_item_hidden(tr_tree, hf_tr_src, 8, 6, trn_shost_nonsr); + proto_tree_add_item_hidden(tr_tree, hf_tr_src, offset + 8, 6, trn_shost_nonsr); if (source_routed) { /* RCF Byte 1 */ - proto_tree_add_item(tr_tree, hf_tr_rif_bytes, 14, 1, trn_rif_bytes); - proto_tree_add_item(tr_tree, hf_tr_broadcast, 14, 1, pd[14] & 224); + proto_tree_add_item(tr_tree, hf_tr_rif_bytes, offset + 14, 1, trn_rif_bytes); + proto_tree_add_item(tr_tree, hf_tr_broadcast, offset + 14, 1, pd[offset + 14] & 224); /* RCF Byte 2 */ - proto_tree_add_item(tr_tree, hf_tr_max_frame_size, 15, 1, pd[15] & 112); - proto_tree_add_item(tr_tree, hf_tr_direction, 15, 1, pd[15] & 128); + proto_tree_add_item(tr_tree, hf_tr_max_frame_size, offset + 15, 1, pd[offset + 15] & 112); + proto_tree_add_item(tr_tree, hf_tr_direction, offset + 15, 1, pd[offset + 15] & 128); /* if we have more than 2 bytes of RIF, then we have ring/bridge pairs */ if (trn_rif_bytes > 2) { - add_ring_bridge_pairs(trn_rif_bytes, pd, tr_tree); + add_ring_bridge_pairs(trn_rif_bytes, + pd + offset, offset, tr_tree); } } @@ -383,6 +388,8 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { "is also running a protocol stack."); } } + offset += 14 + actual_rif_bytes; + /* The package is either MAC or LLC */ switch (frame_type) { /* MAC */ @@ -400,9 +407,9 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { } /* this routine is taken from the Linux net/802/tr.c code, which shows -ring-bridge paires in the /proc/net/tr_rif virtual file. */ +ring-bridge pairs in the /proc/net/tr_rif virtual file. */ static void -add_ring_bridge_pairs(int rcf_len, const u_char *pd, proto_tree *tree) +add_ring_bridge_pairs(int rcf_len, const u_char *pd, int offset, proto_tree *tree) { int j, size; int segment, brdgnmb; @@ -413,19 +420,19 @@ add_ring_bridge_pairs(int rcf_len, const u_char *pd, proto_tree *tree) for(j = 1; j < rcf_len - 1; j += 2) { if (j==1) { - segment=pntohs(&pd[16]) >> 4; + segment=pntohs(&pd[offset + 16]) >> 4; size = sprintf(buffer, "%03X",segment); - proto_tree_add_item_hidden(tree, hf_tr_rif_ring, 16, 2, segment); + proto_tree_add_item_hidden(tree, hf_tr_rif_ring, offset + 16, 2, segment); buff_offset += size; } - segment=pntohs(&pd[17+j]) >> 4; - brdgnmb=pd[16+j] & 0x0f; + segment=pntohs(&pd[offset+17+j]) >> 4; + brdgnmb=pd[offset+16+j] & 0x0f; size = sprintf(buffer+buff_offset, "-%01X-%03X",brdgnmb,segment); - proto_tree_add_item_hidden(tree, hf_tr_rif_ring, 17+j, 2, segment); - proto_tree_add_item_hidden(tree, hf_tr_rif_bridge, 16+j, 1, brdgnmb); + proto_tree_add_item_hidden(tree, hf_tr_rif_ring, offset+17+j, 2, segment); + proto_tree_add_item_hidden(tree, hf_tr_rif_bridge, offset+16+j, 1, brdgnmb); buff_offset += size; } - proto_tree_add_item(tree, hf_tr_rif, 16, rcf_len, buffer); + proto_tree_add_item(tree, hf_tr_rif, offset+16, rcf_len, buffer); } void diff --git a/packet-x25.c b/packet-x25.c index dfe52b67c6..606a85eaef 100644 --- a/packet-x25.c +++ b/packet-x25.c @@ -2,7 +2,7 @@ * Routines for x25 packet disassembly * Olivier Abad <abad@daba.dhis.org> * - * $Id: packet-x25.c,v 1.4 1999/08/05 02:26:21 guy Exp $ + * $Id: packet-x25.c,v 1.5 1999/08/20 06:55:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -1024,14 +1024,14 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "%s VC:%d", - (fd->flags & FROM_DCE) ? "Inc. call" - : "Call req." , + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Inc. call" + : "Call req." , vc); if (x25_tree) proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, "CALL", - (fd->flags & FROM_DCE) ? "Incoming call" - : "Call request"); + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Incoming call" + : "Call request"); localoffset += 3; x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa); @@ -1075,14 +1075,14 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "%s VC:%d", - (fd->flags & FROM_DCE) ? "Call conn." - : "Call acc." , + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Call conn." + : "Call acc." , vc); if (x25_tree) proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, "CALL ACC", - (fd->flags & FROM_DCE) ? "Call connected" - : "Call accepted"); + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Call connected" + : "Call accepted"); localoffset += 3; x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa); @@ -1099,8 +1099,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) case X25_CLEAR_REQUEST: if(check_col(fd, COL_INFO)) { col_add_fstr(fd, COL_INFO, "%s VC:%d %s - %s", - (fd->flags & FROM_DCE) ? "Clear ind." - : "Clear req." , + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Clear ind." + : "Clear req." , vc, clear_code(pd[localoffset+3]), clear_diag(pd[localoffset+4])); } @@ -1108,8 +1108,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) if (x25_tree) { proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, "CLEAR", - (fd->flags & FROM_DCE) ? "Clear indication" - : "Clear request"); + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Clear indication" + : "Clear request"); proto_tree_add_text(x25_tree, localoffset+3, 1, "Cause : %s", clear_code(pd[localoffset+3])); proto_tree_add_text(x25_tree, localoffset+4, 1, @@ -1167,8 +1167,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) case X25_RESET_REQUEST: if(check_col(fd, COL_INFO)) { col_add_fstr(fd, COL_INFO, "%s VC:%d %s - Diag.:%d", - (fd->flags & FROM_DCE) ? "Reset ind." - : "Reset req.", + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Reset ind." + : "Reset req.", vc, reset_code(pd[localoffset+3]), (int)pd[localoffset+4]); } @@ -1176,8 +1176,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) if (x25_tree) { proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, "RESET", - (fd->flags & FROM_DCE) ? "Reset indication" - : "Reset request"); + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Reset indication" + : "Reset request"); proto_tree_add_text(x25_tree, localoffset+3, 1, "Cause : %s", reset_code(pd[localoffset+3])); proto_tree_add_text(x25_tree, localoffset+4, 1, @@ -1196,8 +1196,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) case X25_RESTART_REQUEST: if(check_col(fd, COL_INFO)) { col_add_fstr(fd, COL_INFO, "%s VC:%d %s - Diag.:%d", - (fd->flags & FROM_DCE) ? "Restart ind." - : "Restart req.", + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Restart ind." + : "Restart req.", vc, restart_code(pd[localoffset+3]), (int)pd[localoffset+4]); } @@ -1205,8 +1205,8 @@ dissect_x25(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) if (x25_tree) { proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, "RESTART", - (fd->flags & FROM_DCE) ? "Restart indication" - : "Restart request"); + (fd->pseudo_header.x25.flags & FROM_DCE) ? "Restart indication" + : "Restart request"); proto_tree_add_text(x25_tree, localoffset+3, 1, "Cause : %s", restart_code(pd[localoffset+3])); proto_tree_add_text(x25_tree, localoffset+4, 1, @@ -1,7 +1,7 @@ /* packet.c * Routines for packet disassembly * - * $Id: packet.c,v 1.37 1999/08/18 00:57:54 guy Exp $ + * $Id: packet.c,v 1.38 1999/08/20 06:55:05 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -655,13 +655,13 @@ dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree) switch (fd->lnk_t) { case WTAP_ENCAP_ETHERNET : - dissect_eth(pd, fd, tree); + dissect_eth(pd, 0, fd, tree); break; case WTAP_ENCAP_FDDI : dissect_fddi(pd, fd, tree); break; case WTAP_ENCAP_TR : - dissect_tr(pd, fd, tree); + dissect_tr(pd, 0, fd, tree); break; case WTAP_ENCAP_NONE : dissect_null(pd, fd, tree); @@ -678,6 +678,9 @@ dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree) case WTAP_ENCAP_LINUX_ATM_CLIP : dissect_clip(pd, fd, tree); break; + case WTAP_ENCAP_ATM_SNIFFER : + dissect_atm(pd, fd, tree); + break; } } @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.85 1999/08/18 16:28:22 gram Exp $ + * $Id: packet.h,v 1.86 1999/08/20 06:55:05 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -27,6 +27,10 @@ #ifndef __PACKET_H__ #define __PACKET_H__ +#ifndef __WTAP_H__ +#include "wiretap/wtap.h" +#endif + #ifndef __PROTO_H__ #include "proto.h" #endif @@ -119,7 +123,7 @@ typedef struct _frame_data { gint row; /* Row number for this packet in the display */ int lnk_t; /* Per-packet encapsulation/data-link type */ gboolean passed_dfilter; /* TRUE = display, FALSE = no display */ - guint8 flags; /* for ENCAP_LAPB : 1st bit means From DCE */ + union pseudo_header pseudo_header; /* "pseudo-header" from wiretap */ } frame_data; typedef struct _packet_info { @@ -309,6 +313,11 @@ enum { ETT_LAPB, ETT_X25, ETT_XDLC_CONTROL, + ETT_ATM, + ETT_ATM_LANE, + ETT_ATM_LANE_LC_FLAGS, + ETT_ATM_LANE_LC_LAN_DEST, + ETT_ATM_LANE_LC_LAN_DEST_RD, NUM_TREE_TYPES /* last item number plus one */ }; @@ -375,14 +384,13 @@ void capture_ip(const u_char *, int, guint32, packet_counts *); * Routines should take three args: packet data *, frame_data *, tree * * They should never modify the packet data. */ +void dissect_atm(const u_char *, frame_data *, proto_tree *); void dissect_clip(const u_char *, frame_data *, proto_tree *); -void dissect_eth(const u_char *, frame_data *, proto_tree *); void dissect_fddi(const u_char *, frame_data *, proto_tree *); void dissect_lapb(const u_char *, frame_data *, proto_tree *); void dissect_null(const u_char *, frame_data *, proto_tree *); void dissect_ppp(const u_char *, frame_data *, proto_tree *); void dissect_raw(const u_char *, frame_data *, proto_tree *); -void dissect_tr(const u_char *, frame_data *, proto_tree *); /* * Routines in packet-*.c @@ -400,6 +408,7 @@ void dissect_data(const u_char *, int, frame_data *, proto_tree *); void dissect_ddp(const u_char *, int, frame_data *, proto_tree *); void dissect_dns(const u_char *, int, frame_data *, proto_tree *); void dissect_esp(const u_char *, int, frame_data *, proto_tree *); +void dissect_eth(const u_char *, int, frame_data *, proto_tree *); void dissect_ftp(const u_char *, int, frame_data *, proto_tree *); void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *); void dissect_giop(const u_char *, int, frame_data *, proto_tree *); @@ -436,6 +445,7 @@ void dissect_snmp(const u_char *, int, frame_data *, proto_tree *); void dissect_tcp(const u_char *, int, frame_data *, proto_tree *); void dissect_telnet(const u_char *, int, frame_data *, proto_tree *); void dissect_tftp(const u_char *, int, frame_data *, proto_tree *); +void dissect_tr(const u_char *, int, frame_data *, proto_tree *); void dissect_trmac(const u_char *, int, frame_data *, proto_tree *); void dissect_udp(const u_char *, int, frame_data *, proto_tree *); void dissect_vines(const u_char *, int, frame_data *, proto_tree *); @@ -1,7 +1,7 @@ /* proto.c * Routines for protocol tree * - * $Id: proto.c,v 1.15 1999/08/14 01:26:38 gram Exp $ + * $Id: proto.c,v 1.16 1999/08/20 06:55:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -89,6 +89,7 @@ void dfilter_yacc_init(void); void proto_register_aarp(void); void proto_register_arp(void); void proto_register_atalk(void); +void proto_register_atm(void); void proto_register_bootp(void); void proto_register_cdp(void); void proto_register_data(void); @@ -185,6 +186,7 @@ proto_init(void) proto_register_aarp(); proto_register_arp(); proto_register_atalk(); + proto_register_atm(); proto_register_bootp(); proto_register_cdp(); proto_register_data(); diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c index bd7bc0fe37..a95bfac96d 100644 --- a/wiretap/ngsniffer.c +++ b/wiretap/ngsniffer.c @@ -1,6 +1,6 @@ /* ngsniffer.c * - * $Id: ngsniffer.c,v 1.15 1999/08/19 05:31:33 guy Exp $ + * $Id: ngsniffer.c,v 1.16 1999/08/20 06:55:19 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu> @@ -234,12 +234,6 @@ struct frame4_rec { ATMSaveInfo atm_info; /* ATM-specific stuff */ }; -/* - * Size of ATM LANE header - we have to strip it off as our caller expects - * a MAC header at the beginning of the frame data. - */ -#define ATM_LANE_HEADER_LEN 2 - /* values for V.timeunit */ #define NUM_NGSNIFF_TIMEUNITS 7 static double Usec[] = { 15.0, 0.838096, 15.0, 0.5, 2.0, 0.0, 0.1 }; @@ -257,14 +251,11 @@ static int sniffer_encap[] = { WTAP_ENCAP_LAPB, /* Internetwork analyzer */ WTAP_ENCAP_NONE, /* type 8 not defined in Sniffer */ WTAP_ENCAP_FDDI, - WTAP_ENCAP_NONE /* ATM */ + WTAP_ENCAP_ATM_SNIFFER /* ATM */ }; static int ngsniffer_read(wtap *wth, int *err); -static int get_atm_linktype(wtap *wth, int *err); -static int linktype_for_packet(u_int app_traf_type, u_int app_hl_type); - int ngsniffer_open(wtap *wth, int *err) { int bytes_read; @@ -358,6 +349,8 @@ int ngsniffer_open(wtap *wth, int *err) wth->snapshot_length = 16384; /* not available in header, only in frame */ wth->capture.ngsniffer->timeunit = Usec[version.timeunit]; wth->file_encap = sniffer_encap[version.network]; + wth->capture.ngsniffer->is_atm = + (wth->file_encap == WTAP_ENCAP_ATM_SNIFFER); /* Get capture start time */ start_time = pletohs(&version.time); @@ -390,239 +383,9 @@ int ngsniffer_open(wtap *wth, int *err) * isn't stored in the capture file. */ - /* - * Unless this is an ATM capture file, we won't have to read - * any data records to figure out the network type; zero out - * "pkt_len" to indicate that we've not read the first packet's - * header. - */ - wth->capture.ngsniffer->pkt_len = 0; - wth->capture.ngsniffer->is_atm = 0; - - if (version.network == NGSNIFF_ENCAP_ATM) { - /* - * Gak. There's no link-layer header; however, the - * frame is probably the data that AAL5 handed up, - * which contains RFC 1483 stuff or LANE stuff or SPANS - * stuff or whatever, or, if the "frame" is just an - * ATM cell, it's probably just the cell. - * - * I.e., there *is* no appropriate "link type". - * - * So what we do is scan forward, looking for the first - * LANE or RFC 1483 LLC-multiplexed frame, use that to - * determine the link type, and arrange to discard all - * frames other than those of that type. That denies - * "libpcap" applications access to anything other - * than that, but I *suspect* you don't get a mix of - * RFC 1483 LLC-multiplexed and LANE traffic, and - * the applications probably would have no idea how - * to cope with raw cells or other types of frames - * anyway; the only place you lose is with FORE - * SPANS. - * - * XXX - eventually add a "Sniffer ATM encapsulation" - * that returns the full data, including the ATM - * pseudo-header. - */ - *err = WTAP_ERR_UNSUPPORTED; - wth->file_encap = get_atm_linktype(wth, err); - if (wth->file_encap == -1) { - /* - * Oops, we couldn't find a link type we can - * handle. - */ - free(wth->capture.ngsniffer); - g_message("ngsniffer: no LANE or RFC 1483 LLC-multiplexed frames found"); - return -1; - } - wth->capture.ngsniffer->is_atm = 1; - } return 1; } -static int get_atm_linktype(wtap *wth, int *err) -{ - int bytes_read; - char record_type[2]; - char record_length[4]; /* only 1st 2 bytes are length */ - guint16 type, length; - struct frame4_rec frame4; - int linktype; - guint16 time_low, time_med, time_high, true_size, size; - - for (;;) { - /* - * Read the record header. - */ - errno = WTAP_ERR_CANT_READ; - bytes_read = fread(record_type, 1, 2, wth->fh); - if (bytes_read != 2) { - /* - * End of file or error. Probably means there *are* - * no LANE or RFC 1483 LLC-multiplexed frames, - * which means we can't handle this in - * "wiretap". Return an error. - */ - if (ferror(wth->fh)) - *err = errno; - else { - /* - * If we read no bytes at all, treat - * that as an EOF, not a short read; - * "*err" got set initially to - * WTAP_ERR_UNSUPPORTED, which is the - * most appropriate error if we just - * ran out of packets without seeing - * any LANE or RFC 1483 LLC-multiplexed - * frames. - */ - if (bytes_read != 0) - *err = WTAP_ERR_SHORT_READ; - } - return -1; - } - errno = WTAP_ERR_CANT_READ; - bytes_read = fread(record_length, 1, 4, wth->fh); - if (bytes_read != 4) { - if (ferror(wth->fh)) - *err = errno; - else - *err = WTAP_ERR_SHORT_READ; - return -1; - } - - type = pletohs(record_type); - length = pletohs(record_length); - - if (type == REC_EOF) { - /* - * End of file. Probably means there *are* - * no LANE or RFC 1483 LLC-multiplexed frames, - * which means we can't handle this in - * "wiretap". "*err" got set initially to - * WTAP_ERR_UNSUPPORTED, which is the most - * appropriate error if we just ran out of - * packets without seeing any LANE or RFC - * 1483 LLC-multiplexed frames. - */ - return -1; - } - - switch (type) { - - case REC_FRAME2: - /* - * Umm, we're not supposed to get these in an - * ATM Sniffer file; return an error. - */ - g_message("ngsniffer: REC_FRAME2 record in an ATM Sniffer file"); - *err = WTAP_ERR_BAD_RECORD; - return -1; - - case REC_FRAME4: - /* Read the f_frame4_struct */ - errno = WTAP_ERR_CANT_READ; - bytes_read = fread(&frame4, 1, sizeof frame4, wth->fh); - if (bytes_read != sizeof frame4) { - if (ferror(wth->fh)) - *err = errno; - else - *err = WTAP_ERR_SHORT_READ; - return -1; - } - time_low = pletohs(&frame4.time_low); - time_med = pletohs(&frame4.time_med); - time_high = frame4.time_high; - size = pletohs(&frame4.size); - true_size = pletohs(&frame4.true_size); - - length -= sizeof frame4; /* we already read that much */ - - /* - * Skip it if it's not an AAL5 frame. - */ - if ((frame4.atm_info.AppTrafType & ATT_AALTYPE) - != ATT_AAL5) - break; - - /* - * OK, can we determine a network type from it? - */ - linktype = linktype_for_packet( - frame4.atm_info.AppTrafType, - frame4.atm_info.AppHLType); - if (linktype == -1) { - /* - * Nope - keep looking. - */ - break; - } - - /* - * XXX - use the "time_day" field? Is that for captures - * that take a *really* long time? - */ - wth->capture.ngsniffer->t = (double)time_low+(double)(time_med)*65536.0 + - (double)time_high*4294967296.0; - - wth->capture.ngsniffer->true_size = true_size; - wth->capture.ngsniffer->size = size; - goto found; - - default: - break; /* unknown type, skip it */ - } - - /* - * Well, we don't know what it is, or we know what - * it is but can't handle it. Skip past the data - * portion, and keep looping. - */ - fseek(wth->fh, length, SEEK_CUR); - } - -found: - /* - * Note that we've already read the header, so that we don't do - * it in "ngsniffer_read()"; we've saved the stuff we need - * from the header, so we use it instead - and we save the - * length of the record, so we know how much to read. - */ - wth->capture.ngsniffer->pkt_len = length; - return (linktype); -} - -static int linktype_for_packet(u_int app_traf_type, u_int app_hl_type) -{ - switch (app_traf_type & ATT_HLTYPE) { - - case ATT_HL_LLCMX: - return (WTAP_ENCAP_ATM_RFC1483); - - case ATT_HL_LANE: - /* - * OK, is it 802.3, 802.5, or "none of the above"? - */ - switch (app_hl_type) { - - case AHLT_LANE_802_3: - case AHLT_LANE_802_3_MC: - return (WTAP_ENCAP_ETHERNET); - - case AHLT_LANE_802_5: - case AHLT_LANE_802_5_MC: - return (WTAP_ENCAP_TR); - } - } - - /* - * Keep looking until we find one of the above or run out of - * capture file. - */ - return (-1); -} - /* Read the next packet */ static int ngsniffer_read(wtap *wth, int *err) { @@ -637,20 +400,6 @@ static int ngsniffer_read(wtap *wth, int *err) guint16 time_low, time_med, time_high, true_size, size; int data_offset; - /* - * If we've already read the first packet's header, get the - * information we saved from it, and skip ahead and read - * the data. - */ - if (wth->capture.ngsniffer->pkt_len != 0) { - length = wth->capture.ngsniffer->pkt_len; - true_size = wth->capture.ngsniffer->true_size; - size = wth->capture.ngsniffer->size; - t = wth->capture.ngsniffer->t; - wth->capture.ngsniffer->pkt_len = 0; /* won't have read header for next packet */ - goto found; - } - for (;;) { /* * Read the record header. @@ -684,6 +433,16 @@ static int ngsniffer_read(wtap *wth, int *err) switch (type) { case REC_FRAME2: + if (wth->capture.ngsniffer->is_atm) { + /* + * We shouldn't get a frame2 record in + * an ATM capture. + */ + g_message("ngsniffer: REC_FRAME2 record in an ATM Sniffer file"); + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + /* Read the f_frame2_struct */ errno = WTAP_ERR_CANT_READ; bytes_read = fread(&frame2, 1, sizeof frame2, wth->fh); @@ -705,11 +464,21 @@ static int ngsniffer_read(wtap *wth, int *err) t = (double)time_low+(double)(time_med)*65536.0 + (double)time_high*4294967296.0; - wth->phdr.flags = frame2.fs & 0x80; + wth->phdr.pseudo_header.x25.flags = frame2.fs & 0x80; goto found; case REC_FRAME4: + if (!wth->capture.ngsniffer->is_atm) { + /* + * We shouldn't get a frame2 record in + * a non-ATM capture. + */ + g_message("ngsniffer: REC_FRAME4 record in a non-ATM Sniffer file"); + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + /* Read the f_frame4_struct */ errno = WTAP_ERR_CANT_READ; bytes_read = fread(&frame4, 1, sizeof frame4, wth->fh); @@ -729,29 +498,30 @@ static int ngsniffer_read(wtap *wth, int *err) length -= sizeof frame4; /* we already read that much */ /* - * Skip it if it's not an AAL5 frame. - */ - if ((frame4.atm_info.AppTrafType & ATT_AALTYPE) - != ATT_AAL5) - break; - - /* - * Skip it if it's not a frame of the type we're - * handling. - */ - linktype = linktype_for_packet( - frame4.atm_info.AppTrafType, - frame4.atm_info.AppHLType); - if (wth->file_encap != linktype) - break; - - /* * XXX - use the "time_day" field? Is that for captures * that take a *really* long time? */ t = (double)time_low+(double)(time_med)*65536.0 + (double)time_high*4294967296.0; + wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = + frame4.atm_info.AppTrafType; + wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = + frame4.atm_info.AppHLType; + wth->phdr.pseudo_header.ngsniffer_atm.Vpi = + frame4.atm_info.Vpi; + wth->phdr.pseudo_header.ngsniffer_atm.Vci = + frame4.atm_info.Vci; + wth->phdr.pseudo_header.ngsniffer_atm.channel = + frame4.atm_info.channel; + wth->phdr.pseudo_header.ngsniffer_atm.cells = + frame4.atm_info.cells; + wth->phdr.pseudo_header.ngsniffer_atm.aal5t_u2u = + frame4.atm_info.Trailer.aal5t_u2u; + wth->phdr.pseudo_header.ngsniffer_atm.aal5t_len = + frame4.atm_info.Trailer.aal5t_len; + wth->phdr.pseudo_header.ngsniffer_atm.aal5t_chksum = + frame4.atm_info.Trailer.aal5t_chksum; goto found; case REC_EOF: @@ -777,20 +547,6 @@ found: wth->phdr.caplen = size; /* - * For ATM LANE, skip the 2-byte LAN Emulation header. That - * leaves an Ethernet/802.3 header for Ethernet/802.3, and - * leaves a pad byte and an 802.5 frame control byte for 802.5. - */ - if (wth->capture.ngsniffer->is_atm && wth->file_encap != WTAP_ENCAP_ATM_RFC1483) { - if (length <= ATM_LANE_HEADER_LEN) - return -1; - fseek(wth->fh, ATM_LANE_HEADER_LEN, SEEK_CUR); - wth->phdr.caplen -= ATM_LANE_HEADER_LEN; - wth->phdr.len -= ATM_LANE_HEADER_LEN; - length -= ATM_LANE_HEADER_LEN; - } - - /* * Read the packet data. */ buffer_assure_space(wth->frame_buffer, length); diff --git a/wiretap/radcom.c b/wiretap/radcom.c index 09d47efb71..6444e8d102 100644 --- a/wiretap/radcom.c +++ b/wiretap/radcom.c @@ -248,7 +248,7 @@ static int radcom_read(wtap *wth, int *err) *err = WTAP_ERR_SHORT_READ; return -1; } - wth->phdr.flags = (dce & 0x1) ? 0x00 : 0x80; + wth->phdr.pseudo_header.x25.flags = (dce & 0x1) ? 0x00 : 0x80; fseek(wth->fh, 9, SEEK_CUR); diff --git a/wiretap/wtap.h b/wiretap/wtap.h index fc4ca818e9..c7bcf5c10c 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.28 1999/08/20 04:49:18 gram Exp $ + * $Id: wtap.h,v 1.29 1999/08/20 06:55:19 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu> @@ -54,6 +54,7 @@ #define WTAP_ENCAP_ATM_RFC1483 8 #define WTAP_ENCAP_LINUX_ATM_CLIP 9 #define WTAP_ENCAP_LAPB 10 +#define WTAP_ENCAP_ATM_SNIFFER 11 /* last WTAP_ENCAP_ value + 1 */ #define WTAP_NUM_ENCAP_TYPES 11 @@ -91,10 +92,6 @@ typedef struct { double timeunit; time_t start; - guint16 pkt_len; - guint16 size; - guint16 true_size; - double t; int is_atm; } ngsniffer_t; @@ -128,12 +125,87 @@ typedef struct { int version_major; } netxray_t; +/* Packet "pseudo-header" information for X.25 capture files. */ +struct x25_phdr { + guint8 flags; /* ENCAP_LAPB : 1st bit means From DCE */ +}; + +/* Packet "pseudo-header" for ATM Sniffer capture files. */ +struct ngsniffer_atm_phdr { + guint8 AppTrafType; /* traffic type */ + guint8 AppHLType; /* protocol type */ + guint16 Vpi; /* virtual path identifier */ + guint16 Vci; /* virtual circuit identifier */ + guint16 channel; /* link: 0 for DCE, 1 for DTE */ + guint16 cells; /* number of cells */ + guint16 aal5t_u2u; /* user-to-user indicator */ + guint16 aal5t_len; /* length of the packet */ + guint32 aal5t_chksum; /* checksum for AAL5 packet */ +}; + +/* + * Bits in AppTrafType. + * + * For AAL types other than AAL5, the packet data is presumably for a + * single cell, not a reassembled frame, as the ATM Sniffer manual says + * it dosn't reassemble cells other than AAL5 cells. + */ +#define ATT_AALTYPE 0x0F /* AAL type: */ +#define ATT_AAL_UNKNOWN 0x00 /* Unknown AAL */ +#define ATT_AAL1 0x01 /* AAL1 */ +#define ATT_AAL3_4 0x02 /* AAL3/4 */ +#define ATT_AAL5 0x03 /* AAL5 */ +#define ATT_AAL_USER 0x04 /* User AAL */ +#define ATT_AAL_SIGNALLING 0x05 /* Signaling AAL */ +#define ATT_OAMCELL 0x06 /* OAM cell */ + +#define ATT_HLTYPE 0xF0 /* Higher-layer type: */ +#define ATT_HL_UNKNOWN 0x00 /* unknown */ +#define ATT_HL_LLCMX 0x10 /* LLC multiplexed (probably RFC 1483) */ +#define ATT_HL_VCMX 0x20 /* VC multiplexed (probably RFC 1483) */ +#define ATT_HL_LANE 0x30 /* LAN Emulation */ +#define ATT_HL_ILMI 0x40 /* ILMI */ +#define ATT_HL_FRMR 0x50 /* Frame Relay */ +#define ATT_HL_SPANS 0x60 /* FORE SPANS */ +#define ATT_HL_IPSILON 0x70 /* Ipsilon */ + +/* + * Values for AppHLType; the interpretation depends on the ATT_HLTYPE + * bits in AppTrafType. + */ +#define AHLT_UNKNOWN 0x0 +#define AHLT_VCMX_802_3_FCS 0x1 /* VCMX: 802.3 FCS */ +#define AHLT_LANE_LE_CTRL 0x1 /* LANE: LE Ctrl */ +#define AHLT_IPSILON_FT0 0x1 /* Ipsilon: Flow Type 0 */ +#define AHLT_VCMX_802_4_FCS 0x2 /* VCMX: 802.4 FCS */ +#define AHLT_LANE_802_3 0x2 /* LANE: 802.3 */ +#define AHLT_IPSILON_FT1 0x2 /* Ipsilon: Flow Type 1 */ +#define AHLT_VCMX_802_5_FCS 0x3 /* VCMX: 802.5 FCS */ +#define AHLT_LANE_802_5 0x3 /* LANE: 802.5 */ +#define AHLT_IPSILON_FT2 0x3 /* Ipsilon: Flow Type 2 */ +#define AHLT_VCMX_FDDI_FCS 0x4 /* VCMX: FDDI FCS */ +#define AHLT_LANE_802_3_MC 0x4 /* LANE: 802.3 multicast */ +#define AHLT_VCMX_802_6_FCS 0x5 /* VCMX: 802.6 FCS */ +#define AHLT_LANE_802_5_MC 0x5 /* LANE: 802.5 multicast */ +#define AHLT_VCMX_802_3 0x7 /* VCMX: 802.3 */ +#define AHLT_VCMX_802_4 0x8 /* VCMX: 802.4 */ +#define AHLT_VCMX_802_5 0x9 /* VCMX: 802.5 */ +#define AHLT_VCMX_FDDI 0xa /* VCMX: FDDI */ +#define AHLT_VCMX_802_6 0xb /* VCMX: 802.6 */ +#define AHLT_VCMX_FRAGMENTS 0xc /* VCMX: Fragments */ +#define AHLT_VCMX_BPDU 0xe /* VCMX: BPDU */ + +union pseudo_header { + struct x25_phdr x25; + struct ngsniffer_atm_phdr ngsniffer_atm; +}; + struct wtap_pkthdr { struct timeval ts; guint32 caplen; guint32 len; int pkt_encap; - guint8 flags; /* ENCAP_LAPB : 1st bit means From DCE */ + union pseudo_header pseudo_header; }; typedef void (*wtap_handler)(u_char*, const struct wtap_pkthdr*, |