From 669db206cb1f270046ad400fff7655e20c63e723 Mon Sep 17 00:00:00 2001 From: Gilbert Ramirez Date: Sun, 18 Jul 2004 18:06:47 +0000 Subject: Move dissectors to epan/dissectors directory. Also move ncp222.py, x11-fields, process-x11-fields.pl, make-reg-dotc, and make-reg-dotc.py. Adjust #include lines in files that include packet-*.h files. svn path=/trunk/; revision=11410 --- epan/dissectors/packet-clnp.c | 2396 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2396 insertions(+) create mode 100644 epan/dissectors/packet-clnp.c (limited to 'epan/dissectors/packet-clnp.c') diff --git a/epan/dissectors/packet-clnp.c b/epan/dissectors/packet-clnp.c new file mode 100644 index 0000000000..c94b855043 --- /dev/null +++ b/epan/dissectors/packet-clnp.c @@ -0,0 +1,2396 @@ +/* packet-clnp.c + * Routines for ISO/OSI network and transport protocol packet disassembly + * + * $Id$ + * Laurent Deniel + * Ralf Schneider + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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 +#include +#include +#include +#include +#include "prefs.h" +#include +#include "reassemble.h" +#include "packet-osi.h" +#include "packet-osi-options.h" +#include "packet-isis.h" +#include "packet-esis.h" +#include "nlpid.h" +#include "ipproto.h" + +/* protocols and fields */ + +static int proto_clnp = -1; +static gint ett_clnp = -1; +static gint ett_clnp_type = -1; +static gint ett_clnp_segments = -1; +static gint ett_clnp_segment = -1; +static gint ett_clnp_disc_pdu = -1; + +static int hf_clnp_id = -1; +static int hf_clnp_length = -1; +static int hf_clnp_version = -1; +static int hf_clnp_ttl = -1; +static int hf_clnp_type = -1; +static int hf_clnp_pdu_length = -1; +static int hf_clnp_checksum = -1; +static int hf_clnp_dest_length = -1; +static int hf_clnp_dest = -1; +static int hf_clnp_src_length = -1; +static int hf_clnp_src = -1; +static int hf_clnp_segments = -1; +static int hf_clnp_segment = -1; +static int hf_clnp_segment_overlap = -1; +static int hf_clnp_segment_overlap_conflict = -1; +static int hf_clnp_segment_multiple_tails = -1; +static int hf_clnp_segment_too_long_segment = -1; +static int hf_clnp_segment_error = -1; +static int hf_clnp_reassembled_in = -1; + +static int proto_cotp = -1; +static gint ett_cotp = -1; +static gint ett_cotp_segments = -1; +static gint ett_cotp_segment = -1; + +static int hf_cotp_srcref = -1; +static int hf_cotp_destref = -1; +static int hf_cotp_type = -1; +static int hf_cotp_segments = -1; +static int hf_cotp_segment = -1; +static int hf_cotp_segment_overlap = -1; +static int hf_cotp_segment_overlap_conflict = -1; +static int hf_cotp_segment_multiple_tails = -1; +static int hf_cotp_segment_too_long_segment = -1; +static int hf_cotp_segment_error = -1; +static int hf_cotp_reassembled_in = -1; + +static int proto_cltp = -1; +static gint ett_cltp = -1; + +static int hf_cltp_type = -1; + +static const fragment_items clnp_frag_items = { + &ett_clnp_segment, + &ett_clnp_segments, + &hf_clnp_segments, + &hf_clnp_segment, + &hf_clnp_segment_overlap, + &hf_clnp_segment_overlap_conflict, + &hf_clnp_segment_multiple_tails, + &hf_clnp_segment_too_long_segment, + &hf_clnp_segment_error, + &hf_clnp_reassembled_in, + "segments" +}; + +static const fragment_items cotp_frag_items = { + &ett_cotp_segment, + &ett_cotp_segments, + &hf_cotp_segments, + &hf_cotp_segment, + &hf_cotp_segment_overlap, + &hf_cotp_segment_overlap_conflict, + &hf_cotp_segment_multiple_tails, + &hf_cotp_segment_too_long_segment, + &hf_cotp_segment_error, + &hf_cotp_reassembled_in, + "segments" +}; + +static dissector_handle_t clnp_handle; +static dissector_handle_t data_handle; + +/* + * ISO 8473 OSI CLNP definition (see RFC994) + * + * _________________________________ + * | Fixed Part | + * |_________________________________| + * | Address Part | + * |_________________________________| + * | Segmentation Part (optional) | + * |_________________________________| + * | Options Part (optional) | + * |_________________________________| + * | Data (optional) | + * |_________________________________| + */ + +#define ISO8473_V1 0x01 /* CLNP version 1 */ + +/* Fixed part */ + +#define CNF_TYPE 0x1f +#define CNF_ERR_OK 0x20 +#define CNF_MORE_SEGS 0x40 +#define CNF_SEG_OK 0x80 + +#define DT_NPDU 0x1C +#define MD_NPDU 0x1D +#define ER_NPDU 0x01 +#define ERQ_NPDU 0x1E +#define ERP_NPDU 0x1F + +static const value_string npdu_type_abbrev_vals[] = { + { DT_NPDU, "DT" }, + { MD_NPDU, "MD" }, + { ER_NPDU, "ER" }, + { ERQ_NPDU, "ERQ" }, + { ERP_NPDU, "ERP" }, + { 0, NULL } +}; + +static const value_string npdu_type_vals[] = { + { DT_NPDU, "Data" }, + { MD_NPDU, "Multicast Data" }, + { ER_NPDU, "Error Report" }, + { ERQ_NPDU, "Echo Request" }, + { ERP_NPDU, "Echo Response" }, + { 0, NULL } +}; + +/* field position */ + +#define P_CLNP_PROTO_ID 0 +#define P_CLNP_HDR_LEN 1 +#define P_CLNP_VERS 2 +#define P_CLNP_TTL 3 +#define P_CLNP_TYPE 4 +#define P_CLNP_SEGLEN 5 +#define P_CLNP_CKSUM 7 +#define P_CLNP_ADDRESS_PART 9 + +/* Segmentation part */ + +struct clnp_segment { + gushort cng_id; /* data unit identifier */ + gushort cng_off; /* segment offset */ + gushort cng_tot_len; /* total length */ +}; + +/* NSAP selector */ + +#define NSEL_NET 0x00 +#define NSEL_NP 0x20 +#define NSEL_TP 0x21 + +/* + * ISO8073 OSI COTP definition (see RFC905) + */ + +/* don't use specific TPDU types to avoid alignment problems & copy overhead */ + +/* TPDU definition */ + +#define ED_TPDU 0x1 /* COTP */ +#define EA_TPDU 0x2 /* COTP */ +#define UD_TPDU 0x4 /* CLTP */ +#define RJ_TPDU 0x5 /* COTP */ +#define AK_TPDU 0x6 /* COTP */ +#define ER_TPDU 0x7 /* COTP */ +#define DR_TPDU 0x8 /* COTP */ +#define DC_TPDU 0xC /* COTP */ +#define CC_TPDU 0xD /* COTP */ +#define CR_TPDU 0xE /* COTP */ +#define DT_TPDU 0xF /* COTP */ + +static const value_string cotp_tpdu_type_abbrev_vals[] = { + { ED_TPDU, "ED" }, + { EA_TPDU, "EA" }, + { RJ_TPDU, "RJ" }, + { AK_TPDU, "AK" }, + { ER_TPDU, "ER" }, + { DR_TPDU, "DR" }, + { DC_TPDU, "DC" }, + { CC_TPDU, "CC" }, + { CR_TPDU, "CR" }, + { DT_TPDU, "DT" }, + { 0, NULL } +}; + +static const value_string cltp_tpdu_type_abbrev_vals[] = { + { UD_TPDU, "UD" }, + { 0, NULL } +}; + +/* field position */ + +#define P_LI 0 +#define P_TPDU 1 +#define P_CDT 1 +#define P_DST_REF 2 +#define P_SRC_REF 4 +#define P_TPDU_NR_0_1 2 +#define P_TPDU_NR_234 4 +#define P_VAR_PART_NDT 5 +#define P_VAR_PART_EDT 8 +#define P_VAR_PART_DC 6 +#define P_CDT_IN_AK 8 +#define P_CDT_IN_RJ 8 +#define P_REJECT_ER 4 +#define P_REASON_IN_DR 6 +#define P_CLASS_OPTION 6 + +/* TPDU length indicator */ + +#define LI_NORMAL_DT_CLASS_01 2 +#define LI_NORMAL_DT_WITH_CHECKSUM 8 +#define LI_NORMAL_DT_WITHOUT_CHECKSUM 4 +#define LI_EXTENDED_DT_WITH_CHECKSUM 11 +#define LI_EXTENDED_DT_WITHOUT_CHECKSUM 7 +#define LI_NORMAL_EA_WITH_CHECKSUM 8 +#define LI_NORMAL_EA_WITHOUT_CHECKSUM 4 +#define LI_EXTENDED_EA_WITH_CHECKSUM 11 +#define LI_EXTENDED_EA_WITHOUT_CHECKSUM 7 +#define LI_NORMAL_RJ 4 +#define LI_EXTENDED_RJ 9 +#define LI_MIN_DR 6 +#define LI_MAX_DC 9 +#define LI_MAX_AK 27 +#define LI_MAX_EA 11 +#define LI_MAX_ER 8 +/* XXX - can we always decide this based on whether the length + indicator is odd or not? What if the variable part has an odd + number of octets? */ +#define is_LI_NORMAL_AK(p) ( ( p & 0x01 ) == 0 ) + +/* variant part */ + +#define VP_ACK_TIME 0x85 +#define VP_RES_ERROR 0x86 +#define VP_PRIORITY 0x87 +#define VP_TRANSIT_DEL 0x88 +#define VP_THROUGHPUT 0x89 +#define VP_SEQ_NR 0x8A /* in AK */ +#define VP_REASSIGNMENT 0x8B +#define VP_FLOW_CNTL 0x8C /* in AK */ +#define VP_TPDU_SIZE 0xC0 +#define VP_SRC_TSAP 0xC1 /* in CR/CC */ +#define VP_DST_TSAP 0xC2 +#define VP_CHECKSUM 0xC3 +#define VP_VERSION_NR 0xC4 +#define VP_PROTECTION 0xC5 +#define VP_OPT_SEL 0xC6 +#define VP_PROTO_CLASS 0xC7 +#define VP_PREF_MAX_TPDU_SIZE 0xF0 +#define VP_INACTIVITY_TIMER 0xF2 + +static const value_string tp_vpart_type_vals[] = { + { VP_ACK_TIME, "ack time" }, + { VP_RES_ERROR, "res error" }, + { VP_PRIORITY, "priority" }, + { VP_TRANSIT_DEL, "transit delay" }, + { VP_THROUGHPUT, "throughput" }, + { VP_SEQ_NR, "seq number" }, + { VP_REASSIGNMENT, "reassignment" }, + { VP_FLOW_CNTL, "flow control" }, + { VP_TPDU_SIZE, "tpdu-size" }, + { VP_SRC_TSAP, "src-tsap" }, + { VP_DST_TSAP, "dst-tsap" }, + { VP_CHECKSUM, "checksum" }, + { VP_VERSION_NR, "version" }, + { VP_PROTECTION, "protection" }, + { VP_OPT_SEL, "options" }, + { VP_PROTO_CLASS, "proto class" }, + { VP_PREF_MAX_TPDU_SIZE, "preferred max TPDU size" }, + { 0, NULL } +}; + +static int hf_cotp_vp_src_tsap = -1; +static int hf_cotp_vp_dst_tsap = -1; +static int hf_cotp_vp_src_tsap_bytes = -1; +static int hf_cotp_vp_dst_tsap_bytes = -1; + + +/* misc */ + +#define EXTRACT_SHORT(p) pntohs(p) +#define EXTRACT_LONG(p) pntohl(p) + +/* global variables */ + +/* List of dissectors to call for COTP packets put atop the Inactive + Subset of CLNP. */ +static heur_dissector_list_t cotp_is_heur_subdissector_list; +/* List of dissectors to call for COTP packets put atop CLNP */ +static heur_dissector_list_t cotp_heur_subdissector_list; +/* List of dissectors to call for CLNP packets */ +static heur_dissector_list_t clnp_heur_subdissector_list; + +/* + * Reassembly of CLNP. + */ +static GHashTable *clnp_segment_table = NULL; +static GHashTable *clnp_reassembled_table = NULL; + +/* + * Reassembly of COTP. + */ +static GHashTable *cotp_segment_table = NULL; +static GHashTable *cotp_reassembled_table = NULL; + +#define TSAP_DISPLAY_AUTO 0 +#define TSAP_DISPLAY_STRING 1 +#define TSAP_DISPLAY_BYTES 2 + + +/* options */ +static guint tp_nsap_selector = NSEL_TP; +static gboolean always_decode_transport = FALSE; +static gboolean clnp_reassemble = FALSE; +static gboolean cotp_reassemble = FALSE; +static gint32 tsap_display = TSAP_DISPLAY_AUTO; + +const enum_val_t tsap_display_options[] = { + {"auto", "As strings if printable", TSAP_DISPLAY_AUTO}, + {"string", "As strings", TSAP_DISPLAY_STRING}, + {"bytes", "As bytes", TSAP_DISPLAY_BYTES}, + {NULL, NULL, -1} +}; + + +/* function definitions */ + +#define MAX_TSAP_LEN 32 +static gboolean is_all_printable(const guchar *stringtocheck, int length) +{ + gboolean allprintable; + int i; + + allprintable=TRUE; + for (i=0;i MAX_TSAP_LEN) + sprintf(cur, ""); + else { + allprintable = is_all_printable(tsap,length); + if (!allprintable) + strcat(cur,"0x"); + while (length != 0) { + if (allprintable) + sprintf(tmp, "%c", *tsap ++); + else + sprintf(tmp, "%02x", *tsap ++); + strcat(cur, tmp); + length --; + } + } + return cur; + +} /* print_tsap */ + +static gboolean ositp_decode_var_part(tvbuff_t *tvb, int offset, + int vp_length, int class_option, + proto_tree *tree) +{ + guint8 code, length; + guint8 c1; + guint16 s, s1,s2,s3,s4; + guint32 t1, t2, t3, t4; + guint32 pref_max_tpdu_size; + + while (vp_length != 0) { + code = tvb_get_guint8(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 1, + "Parameter code: 0x%02x (%s)", + code, + val_to_str(code, tp_vpart_type_vals, "Unknown")); + offset += 1; + vp_length -= 1; + + if (vp_length == 0) + break; + length = tvb_get_guint8(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 1, + "Parameter length: %u", length); + offset += 1; + vp_length -= 1; + + switch (code) { + + case VP_ACK_TIME: + s = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, length, + "Ack time (ms): %u", s); + offset += length; + vp_length -= length; + break; + + case VP_RES_ERROR: + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, target value: 10^%u", + tvb_get_guint8(tvb, offset)); + offset += 1; + length -= 1; + vp_length -= 1; + + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, minimum acceptable: 10^%u", + tvb_get_guint8(tvb, offset)); + offset += 1; + length -= 1; + vp_length -= 1; + + + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, TSDU size of interest: %u", + 1<