From 35a6e092c3153cc7fbd1337c2230d596b0f7abcb Mon Sep 17 00:00:00 2001 From: gram 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. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@11410 f5534014-38df-0310-8fa8-9805f1628bb7 --- epan/dissectors/packet-sndcp.c | 577 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 577 insertions(+) create mode 100644 epan/dissectors/packet-sndcp.c (limited to 'epan/dissectors/packet-sndcp.c') diff --git a/epan/dissectors/packet-sndcp.c b/epan/dissectors/packet-sndcp.c new file mode 100644 index 0000000000..b6123b3310 --- /dev/null +++ b/epan/dissectors/packet-sndcp.c @@ -0,0 +1,577 @@ +/* packet-sndcp.c + * Routines for Subnetwork Dependent Convergence Protocol (SNDCP) dissection + * Copyright 2000, Christian Falckenberg + * + * $Id$ + * + * 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 + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include "reassemble.h" + +/* Bitmasks for the bits in the address field +*/ +#define MASK_X 0x80 +#define MASK_F 0x40 +#define MASK_T 0x20 +#define MASK_M 0x10 + +/* Initialize the protocol and registered fields +*/ +static int proto_sndcp = -1; +static int hf_sndcp_x = -1; +static int hf_sndcp_f = -1; +static int hf_sndcp_t = -1; +static int hf_sndcp_m = -1; +static int hf_sndcp_nsapi = -1; +static int hf_sndcp_nsapib = -1; +static int hf_sndcp_dcomp = -1; +static int hf_sndcp_pcomp = -1; +static int hf_sndcp_segment = -1; +static int hf_sndcp_npdu1 = -1; +static int hf_sndcp_npdu2 = -1; + +/* These fields are used when reassembling N-PDU fragments +*/ +static int hf_npdu_fragments = -1; +static int hf_npdu_fragment = -1; +static int hf_npdu_fragment_overlap = -1; +static int hf_npdu_fragment_overlap_conflict = -1; +static int hf_npdu_fragment_multiple_tails = -1; +static int hf_npdu_fragment_too_long_fragment = -1; +static int hf_npdu_fragment_error = -1; +static int hf_npdu_reassembled_in = -1; + +/* Initialize the subtree pointers +*/ +static gint ett_sndcp = -1; +static gint ett_sndcp_address_field = -1; +static gint ett_sndcp_compression_field = -1; +static gint ett_sndcp_npdu_field = -1; +static gint ett_npdu_fragment = -1; +static gint ett_npdu_fragments = -1; + +/* Structure needed for the fragmentation routines in reassemble.c +*/ +static const fragment_items npdu_frag_items = { + &ett_npdu_fragment, + &ett_npdu_fragments, + &hf_npdu_fragments, + &hf_npdu_fragment, + &hf_npdu_fragment_overlap, + &hf_npdu_fragment_overlap_conflict, + &hf_npdu_fragment_multiple_tails, + &hf_npdu_fragment_too_long_fragment, + &hf_npdu_fragment_error, + &hf_npdu_reassembled_in, + "fragments" +}; + +/* dissectors for the data portion of this protocol + */ +static dissector_handle_t data_handle; +static dissector_handle_t ip_handle; + +/* reassembly of N-PDU + */ +static GHashTable *npdu_fragment_table = NULL; +static void +sndcp_defragment_init(void) +{ + fragment_table_init(&npdu_fragment_table); +} + +/* value strings + */ +static const value_string nsapi_t[] = { + { 0, "Escape mechanism for future extensions"}, + { 1, "Point-to-Multipoint (PTM-M) Information" }, + { 2, "Reserved for future use" }, + { 3, "Reserved for future use" }, + { 4, "Reserved for future use" }, + { 5, "Dynamically allocated"}, + { 6, "Dynamically allocated"}, + { 7, "Dynamically allocated"}, + { 8, "Dynamically allocated"}, + { 9, "Dynamically allocated"}, + { 10, "Dynamically allocated"}, + { 11, "Dynamically allocated"}, + { 12, "Dynamically allocated"}, + { 13, "Dynamically allocated"}, + { 14, "Dynamically allocated"}, + { 15, "Dynamically allocated"}, + { 0, NULL }, +}; + +static const value_string nsapi_abrv[] = { + { 0, "0"}, + { 1, "PTM-M" }, + { 2, "2" }, + { 3, "3"}, + { 4, "4" }, + { 5, "DYN5" }, + { 6, "DYN6" }, + { 7, "DYN7" }, + { 8, "DYN8" }, + { 9, "DYN9" }, + { 10, "DYN10" }, + { 11, "DYN11" }, + { 12, "DYN12" }, + { 13, "DYN13" }, + { 14, "DYN14" }, + { 15, "DYN15" }, + { 0, NULL }, +}; + +static const value_string compression_vals[] = { + { 0, "No compression"}, + { 1, "Pointer to selected protocol/data compression mechanism" }, + { 2, "Pointer to selected protocol/data compression mechanism" }, + { 3, "Pointer to selected protocol/data compression mechanism" }, + { 4, "Pointer to selected protocol/data compression mechanism" }, + { 5, "Pointer to selected protocol/data compression mechanism" }, + { 6, "Pointer to selected protocol/data compression mechanism" }, + { 7, "Pointer to selected protocol/data compression mechanism" }, + { 8, "Pointer to selected protocol/data compression mechanism" }, + { 9, "Pointer to selected protocol/data compression mechanism" }, + { 10, "Pointer to selected protocol/data compression mechanism" }, + { 11, "Pointer to selected protocol/data compression mechanism" }, + { 12, "Pointer to selected protocol/data compression mechanism" }, + { 13, "Pointer to selected protocol/data compression mechanism" }, + { 14, "Pointer to selected protocol/data compression mechanism" }, + { 15, "Pointer to selected protocol/data compression mechanism" }, + { 0, NULL }, +}; + +static const true_false_string x_bit = { + "Invalid", + "Set to 0 by transmitting SNDCP entity (ignored by receiver)" +}; +static const true_false_string f_bit = { + "This SN-PDU is the first segment of an N-PDU", + "This SN-PDU is not the first segment of an N-PDU" +}; +static const true_false_string t_bit = { + "SN-UNITDATA PDU", + "SN-DATA PDU" +}; +static const true_false_string m_bit = { + "Not the last segment of N-PDU, more segments to follow", + "Last segment of N-PDU" +}; + +/* Code to actually dissect the packets +*/ +static void +dissect_sndcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 addr_field, comp_field, npdu_field1, nsapi, dcomp=0, pcomp=0; + guint16 offset=0, npdu=0, segment=0, npdu_field2; + tvbuff_t *next_tvb, *npdu_tvb; + guint32 len; + gboolean first, more_frags, unack; + + /* Set up structures needed to add the protocol subtree and manage it + */ + proto_item *ti, *address_field_item, *compression_field_item, *npdu_field_item; + proto_tree *sndcp_tree = NULL, *address_field_tree, *compression_field_tree, *npdu_field_tree; + + /* Make entries in Protocol column and clear Info column on summary display + */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SNDCP"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + /* create display subtree for the protocol + */ + if (tree) { + ti = proto_tree_add_item(tree, proto_sndcp, tvb, 0, -1, FALSE); + sndcp_tree = proto_item_add_subtree(ti, ett_sndcp); + } + + /* get address field from next byte + */ + addr_field = tvb_get_guint8(tvb,offset); + nsapi = addr_field & 0xF; + first = addr_field & MASK_F; + more_frags = addr_field & MASK_M; + unack = addr_field & MASK_T; + + /* add subtree for the address field + */ + if (tree) { + address_field_item = proto_tree_add_uint_format(sndcp_tree,hf_sndcp_nsapi, + tvb, offset,1, nsapi, + "Address field NSAPI: %d", nsapi ); + address_field_tree = proto_item_add_subtree(address_field_item, ett_sndcp_address_field); + proto_tree_add_boolean(address_field_tree, hf_sndcp_x, tvb,offset,1, addr_field ); + proto_tree_add_boolean(address_field_tree, hf_sndcp_f, tvb,offset,1, addr_field ); + proto_tree_add_boolean(address_field_tree, hf_sndcp_t, tvb,offset,1, addr_field ); + proto_tree_add_boolean(address_field_tree, hf_sndcp_m, tvb,offset,1, addr_field ); + proto_tree_add_uint(address_field_tree, hf_sndcp_nsapib, tvb, offset, 1, addr_field ); + } + offset++; + + /* get compression pointers from next byte if this is the first segment + */ + if (first) { + comp_field = tvb_get_guint8(tvb,offset); + dcomp = comp_field & 0xF0; + pcomp = comp_field & 0x0F; + + /* add subtree for the compression field + */ + if (tree) { + if (!pcomp) { + if (!dcomp) { + compression_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,1, "No compression"); + } + else { + compression_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,1, "Data compression"); + } + } + else { + if (!dcomp) { + compression_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,1, "Protocol compression"); + } + else { + compression_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,1, "Data and Protocol compression"); + } + } + compression_field_tree = proto_item_add_subtree(compression_field_item, ett_sndcp_compression_field); + proto_tree_add_uint(compression_field_tree, hf_sndcp_dcomp, tvb, offset, 1, comp_field ); + proto_tree_add_uint(compression_field_tree, hf_sndcp_pcomp, tvb, offset, 1, comp_field ); + } + offset++; + + /* get N-PDU number from next byte for acknowledged mode (only for first segment) + */ + if (!unack) { + npdu = npdu_field1 = tvb_get_guint8(tvb,offset); + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "SN-DATA N-PDU %d", npdu_field1); + if (tree) { + npdu_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,1, "Acknowledged mode, N-PDU %d", npdu_field1 ); + npdu_field_tree = proto_item_add_subtree(npdu_field_item, ett_sndcp_npdu_field); + proto_tree_add_uint(npdu_field_tree, hf_sndcp_npdu1, tvb, offset, 1, npdu_field1 ); + offset++; + } + } + } + + /* get segment and N-PDU number from next two bytes for unacknowledged mode + */ + if (unack) { + npdu_field2 = tvb_get_ntohs(tvb, offset); + segment = (npdu_field2 & 0xF000) >> 12; + npdu = (npdu_field2 & 0x0FFF); + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "SN-UNITDATA N-PDU %d (segment %d)", npdu, segment); + if (tree) { + npdu_field_item = proto_tree_add_text(sndcp_tree, tvb, offset,2, "Unacknowledged mode, N-PDU %d (segment %d)", npdu, segment ); + npdu_field_tree = proto_item_add_subtree(npdu_field_item, ett_sndcp_npdu_field); + proto_tree_add_uint(npdu_field_tree, hf_sndcp_segment, tvb, offset, 2, npdu_field2 ); + proto_tree_add_uint(npdu_field_tree, hf_sndcp_npdu2, tvb, offset, 2, npdu_field2 ); + } + offset += 2; + } + + /* handle N-PDU data, reassemble if necessary + */ + if (first && !more_frags) { + next_tvb = tvb_new_subset (tvb, offset, -1, -1); + + if (!dcomp && !pcomp) { + call_dissector(ip_handle, next_tvb, pinfo, tree); + } + else { + call_dissector(data_handle, next_tvb, pinfo, tree); + } + } + else { + /* Try reassembling fragments + */ + fragment_data *fd_npdu = NULL; + guint32 reassembled_in = 0; + gboolean save_fragmented = pinfo->fragmented; + + len = tvb_length_remaining(tvb, offset); + pinfo->fragmented = TRUE; + + if (unack) + fd_npdu = fragment_add_seq(tvb, offset, pinfo, npdu, + npdu_fragment_table, segment, len, more_frags); + else + fd_npdu = fragment_add(tvb, offset, pinfo, npdu, + npdu_fragment_table, offset, len, more_frags); + + npdu_tvb = process_reassembled_data(tvb, offset, pinfo, + "Reassembled N-PDU", fd_npdu, &npdu_frag_items, + NULL, sndcp_tree); + if (fd_npdu) { + /* Reassembled + */ + reassembled_in = fd_npdu->reassembled_in; + if (pinfo->fd->num == reassembled_in) { + /* Reassembled in this very packet: + * We can safely hand the tvb to the IP dissector + */ + call_dissector(ip_handle, npdu_tvb, pinfo, tree); + } + else { + /* Not reassembled in this packet + */ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_append_fstr(pinfo->cinfo, COL_INFO, + " (N-PDU payload reassembled in packet %u)", + fd_npdu->reassembled_in); + } + if (tree) { + proto_tree_add_text(sndcp_tree, tvb, offset, -1, "Payload"); + } + } + } else { + /* Not reassembled yet, or not reassembled at all + */ + if (check_col(pinfo->cinfo, COL_INFO)) { + if (unack) + col_append_fstr(pinfo->cinfo, COL_INFO, " (Unreassembled fragment %u)", segment); + else + col_append_str(pinfo->cinfo, COL_INFO, " (Unreassembled fragment)"); + } + if (tree) { + proto_tree_add_text(sndcp_tree, tvb, offset, -1, "Payload"); + } + } + /* Now reset fragmentation information in pinfo + */ + pinfo->fragmented = save_fragmented; + } +} + + +/* Register the protocol with Ethereal + this format is required because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_sndcp(void) +{ + /* Setup list of header fields + */ + static hf_register_info hf[] = { + { &hf_sndcp_nsapi, + { "NSAPI", + "sndcp.nsapi", + FT_UINT8, BASE_DEC, VALS(nsapi_abrv), 0x0, + "Network Layer Service Access Point Identifier", HFILL + } + }, + { &hf_sndcp_x, + { "Spare bit", + "sndcp.x", + FT_BOOLEAN,8, TFS(&x_bit), MASK_X, + "Spare bit (should be 0)", HFILL + } + }, + { &hf_sndcp_f, + { "First segment indicator bit", + "sndcp.f", + FT_BOOLEAN,8, TFS(&f_bit), MASK_F, + "First segment indicator bit", HFILL + } + }, + { &hf_sndcp_t, + { "Type", + "sndcp.t", + FT_BOOLEAN,8, TFS(&t_bit), MASK_T, + "SN-PDU Type", HFILL + } + }, + { &hf_sndcp_m, + { "More bit", + "sndcp.m", + FT_BOOLEAN,8, TFS(&m_bit), MASK_M, + "More bit", HFILL + } + }, + { &hf_sndcp_dcomp, + { "DCOMP", + "sndcp.dcomp", + FT_UINT8, BASE_DEC, VALS(compression_vals), 0xF0, + "Data compression coding", HFILL + } + }, + { &hf_sndcp_pcomp, + { "PCOMP", + "sndcp.pcomp", + FT_UINT8, BASE_DEC, VALS(compression_vals), 0x0F, + "Protocol compression coding", HFILL + } + }, + { &hf_sndcp_nsapib, + { "NSAPI", + "sndcp.nsapib", + FT_UINT8, BASE_DEC , VALS(nsapi_t), 0xf, + "Network Layer Service Access Point Identifier ",HFILL + } + }, + { &hf_sndcp_segment, + { "Segment", + "sndcp.segment", + FT_UINT16, BASE_DEC, NULL, 0xF000, + "Segment number", HFILL + } + }, + { &hf_sndcp_npdu1, + { "N-PDU", + "sndcp.npdu", + FT_UINT8, BASE_DEC, NULL, 0, + "N-PDU", HFILL + } + }, + { &hf_sndcp_npdu2, + { "N-PDU", + "sndcp.npdu", + FT_UINT16, BASE_DEC, NULL, 0x0FFF, + "N-PDU", HFILL + } + }, + + /* Fragment fields + */ + { &hf_npdu_fragment_overlap, + { "Fragment overlap", + "npdu.fragment.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment overlaps with other fragments", HFILL + } + }, + { &hf_npdu_fragment_overlap_conflict, + { "Conflicting data in fragment overlap", + "npdu.fragment.overlap.conflict", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Overlapping fragments contained conflicting data", HFILL + } + }, + { &hf_npdu_fragment_multiple_tails, + { "Multiple tail fragments found", + "npdu.fragment.multipletails", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Several tails were found when defragmenting the packet", HFILL + } + }, + { &hf_npdu_fragment_too_long_fragment, + { "Fragment too long", + "npdu.fragment.toolongfragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment contained data past end of packet", HFILL + } + }, + { &hf_npdu_fragment_error, + { "Defragmentation error", + "npdu.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "Defragmentation error due to illegal fragments", HFILL + } + }, + { &hf_npdu_reassembled_in, + { "Reassembled in", + "npdu.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "N-PDU fragments are reassembled in the given packet", HFILL + } + }, + { &hf_npdu_fragment, + { "N-PDU Fragment", + "npdu.fragment", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "N-PDU Fragment", HFILL + } + }, + { &hf_npdu_fragments, + { "N-PDU Fragments", + "npdu.fragments", + FT_NONE, BASE_NONE, NULL, 0x0, + "N-PDU Fragments", HFILL + } + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_sndcp , + &ett_sndcp_address_field, + &ett_sndcp_compression_field, + &ett_sndcp_npdu_field, + &ett_npdu_fragment, + &ett_npdu_fragments, + }; + + /* Register the protocol name and description */ + proto_sndcp = proto_register_protocol("Subnetwork Dependent Convergence Protocol", + "SNDCP", "sndcp"); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_sndcp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("sndcp", dissect_sndcp, proto_sndcp); + register_init_routine(sndcp_defragment_init); +} + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_sndcp(void) +{ + dissector_handle_t sndcp_handle; + + sndcp_handle = create_dissector_handle(dissect_sndcp, proto_sndcp); + + /* Register SNDCP dissector with LLC layer for SAPI 3,5,9 and 11 + */ + dissector_add("llcgprs.sapi", 3, sndcp_handle); + dissector_add("llcgprs.sapi", 5, sndcp_handle); + dissector_add("llcgprs.sapi", 9, sndcp_handle); + dissector_add("llcgprs.sapi", 11, sndcp_handle); + + /* Find IP and data handle for upper layer dissectors + */ + ip_handle = find_dissector("ip"); + data_handle = find_dissector("data"); +} -- cgit v1.2.3