2001-03-23 19:22:02 +00:00
|
|
|
/* packet-wcp.c
|
|
|
|
* Routines for Wellfleet Compression frame disassembly
|
|
|
|
* Copyright 2001, Jeffrey C. Foster <jfoste@woodward.com>
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
2001-03-23 19:22:02 +00:00
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2001-03-23 19:22:02 +00:00
|
|
|
* Copyright 1998
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-03-23 19:22:02 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-03-23 19:22:02 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
2001-03-23 19:22:02 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-06-28 22:56:06 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2001-03-23 19:22:02 +00:00
|
|
|
*
|
|
|
|
* ToDo:
|
|
|
|
* Add preference to allow/disallow decompression
|
|
|
|
* Calculate and verify check byte (last byte), if only we knew how!
|
|
|
|
* Handle Wellfleet compression over PPP links.
|
|
|
|
* - This will require changing the sub-dissector call
|
|
|
|
* routine to determine if layer 2 is frame relay or
|
|
|
|
* or PPP and different sub-dissector routines for each.
|
|
|
|
*
|
|
|
|
* Based upon information in the Nortel TCL based Pcaptap code.
|
|
|
|
*http://www.mynetworkforum.com/tools/PCAPTAP/pcaptap-Win32-3.00.exe
|
|
|
|
*
|
|
|
|
* And lzss algorithm
|
|
|
|
*http://www.rasip.fer.hr/research/compress/algorithms/fund/lz/lzss.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Wellfleet compression is a variation on LZSS encoding.
|
|
|
|
*
|
2002-08-28 21:04:11 +00:00
|
|
|
* Compression is done by keeping a sliding window of previous
|
|
|
|
* data transmited. The sender will use a pattern match to
|
2001-03-23 19:22:02 +00:00
|
|
|
* encode repeated data as a data pointer field. Then a stream
|
|
|
|
* of pointers and actual data bytes. The pointer values include
|
|
|
|
* an offset to previous data in the stream and the length of the
|
|
|
|
* matching data.
|
|
|
|
*
|
2011-10-12 16:31:41 +00:00
|
|
|
* The data pattern matching is done on the octets.
|
2001-03-23 19:22:02 +00:00
|
|
|
*
|
|
|
|
* The data is encoded as 8 field blocks with a compression flag
|
|
|
|
* byte at the beginning. If the bit is set in the compression
|
|
|
|
* flag, then that field has a compression field. If it isn't set
|
|
|
|
* then the byte is raw data.
|
|
|
|
*
|
|
|
|
* The compression field is either 2 or 3 bytes long. The length
|
|
|
|
* is determined by the length of the matching data, for short
|
|
|
|
* matches the match length is encoded in the high nibble of the
|
2002-08-28 21:04:11 +00:00
|
|
|
* first byte. Otherwise the third byte of the field contains
|
2001-03-23 19:22:02 +00:00
|
|
|
* the match length.
|
|
|
|
*
|
|
|
|
* First byte -
|
|
|
|
* lower 4 bits:
|
|
|
|
* High order nibble of the offset
|
|
|
|
*
|
|
|
|
* upper 4 bits:
|
2002-08-28 21:04:11 +00:00
|
|
|
* 1 = length is in 3rd byte
|
2001-03-23 19:22:02 +00:00
|
|
|
* 2-F = length of matching data - 1
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
|
|
|
* Second byte -
|
2001-03-23 19:22:02 +00:00
|
|
|
* Lower byte of the source offset.
|
|
|
|
*
|
2002-08-28 21:04:11 +00:00
|
|
|
* Third byte -
|
2001-03-23 19:22:02 +00:00
|
|
|
* Length of match - 1 if First byte upper nibble = 1, otherwise
|
|
|
|
* this byte isn't added to data stream.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* Uncompressed data (hex): 11 22 22 22 22 33 44 55 66 77
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Compression data :
|
|
|
|
* Flag bits: 0x20 (third field is compressed)
|
|
|
|
* Data: 11 22 20 00 33 44 55
|
|
|
|
* / / / /
|
2002-08-28 21:04:11 +00:00
|
|
|
* raw data ------+--+ / /
|
2001-03-23 19:22:02 +00:00
|
|
|
* (Comp length - 1)<<4+ /
|
|
|
|
* Data offset ----------+
|
|
|
|
*
|
|
|
|
* Output data (hex): 20 11 22 20 00 33 44 55 66 77
|
|
|
|
*
|
|
|
|
* In this example the copy src is one byte behind the copy destination
|
|
|
|
* so if appears as if output is being loaded with the source byte.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-09-20 02:03:38 +00:00
|
|
|
#include "config.h"
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <string.h>
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2002-10-22 08:22:07 +00:00
|
|
|
#include <epan/circuit.h>
|
2005-08-13 01:29:31 +00:00
|
|
|
#include <epan/emem.h>
|
2005-09-17 00:02:31 +00:00
|
|
|
#include <epan/etypes.h>
|
|
|
|
#include <epan/nlpid.h>
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
#include <epan/expert.h>
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
#define MAX_WIN_BUF_LEN 0x7fff /* storage size for decompressed data */
|
|
|
|
#define MAX_WCP_BUF_LEN 2048 /* storage size for decompressed data */
|
|
|
|
#define FROM_DCE 0x80 /* for direction setting */
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
guint8 *buf_cur;
|
|
|
|
guint8 buffer[MAX_WIN_BUF_LEN];
|
|
|
|
|
|
|
|
}wcp_window_t;
|
|
|
|
|
2002-10-22 08:22:07 +00:00
|
|
|
typedef struct {
|
|
|
|
wcp_window_t recv;
|
|
|
|
wcp_window_t send;
|
|
|
|
} wcp_circuit_data_t;
|
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
/*XXX do I really want the length in here */
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
guint16 len;
|
|
|
|
guint8 buffer[MAX_WCP_BUF_LEN];
|
|
|
|
|
|
|
|
}wcp_pdata_t;
|
|
|
|
|
|
|
|
|
|
|
|
static int proto_wcp = -1;
|
|
|
|
static int hf_wcp_cmd = -1;
|
|
|
|
static int hf_wcp_ext_cmd = -1;
|
|
|
|
static int hf_wcp_seq = -1;
|
|
|
|
static int hf_wcp_chksum = -1;
|
|
|
|
static int hf_wcp_tid = -1;
|
|
|
|
static int hf_wcp_rev = -1;
|
|
|
|
static int hf_wcp_init = -1;
|
|
|
|
static int hf_wcp_seq_size = -1;
|
|
|
|
static int hf_wcp_alg = -1;
|
|
|
|
static int hf_wcp_alg_cnt = -1;
|
|
|
|
static int hf_wcp_alg_a = -1;
|
|
|
|
static int hf_wcp_alg_b = -1;
|
|
|
|
static int hf_wcp_alg_c = -1;
|
|
|
|
static int hf_wcp_alg_d = -1;
|
2013-01-26 18:54:53 +00:00
|
|
|
/* static int hf_wcp_rexmit = -1; */
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
static int hf_wcp_hist_size = -1;
|
|
|
|
static int hf_wcp_ppc = -1;
|
|
|
|
static int hf_wcp_pib = -1;
|
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
static int hf_wcp_compressed_data = -1;
|
2001-03-23 19:22:02 +00:00
|
|
|
static int hf_wcp_comp_bits = -1;
|
2013-01-26 18:54:53 +00:00
|
|
|
/* static int hf_wcp_comp_marker = -1; */
|
2001-03-23 19:22:02 +00:00
|
|
|
static int hf_wcp_short_len = -1;
|
|
|
|
static int hf_wcp_long_len = -1;
|
|
|
|
static int hf_wcp_short_run = -1;
|
|
|
|
static int hf_wcp_long_run = -1;
|
|
|
|
static int hf_wcp_offset = -1;
|
|
|
|
|
|
|
|
static gint ett_wcp = -1;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
static gint ett_wcp_comp_data = -1;
|
2001-03-23 19:22:02 +00:00
|
|
|
static gint ett_wcp_field = -1;
|
|
|
|
|
2002-07-31 19:27:57 +00:00
|
|
|
static dissector_handle_t fr_uncompressed_handle;
|
2001-11-27 07:13:32 +00:00
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
/*
|
|
|
|
* Bits in the address field.
|
|
|
|
*/
|
|
|
|
#define WCP_CMD 0xf0 /* WCP Command */
|
|
|
|
#define WCP_EXT_CMD 0x0f /* WCP Extended Command */
|
|
|
|
#define WCP_SEQ 0x0fff /* WCP Sequence number */
|
|
|
|
#define WCP_OFFSET_MASK 0x0fff /* WCP Pattern source offset */
|
|
|
|
|
|
|
|
#define PPC_COMPRESSED_IND 0x0
|
|
|
|
#define PPC_UNCOMPRESSED_IND 0x1
|
|
|
|
#define PPC_TPPC_COMPRESSED_IND 0x2
|
|
|
|
#define PPC_TPPC_UNCOMPRESSED_IND 0x3
|
|
|
|
#define CONNECT_REQ 0x4
|
|
|
|
#define CONNECT_ACK 0x5
|
|
|
|
#define CONNECT_NAK 0x6
|
|
|
|
#define DISCONNECT_REQ 0x7
|
|
|
|
#define DISCONNECT_ACK 0x8
|
|
|
|
#define INIT_REQ 0x9
|
|
|
|
#define INIT_ACK 0xa
|
|
|
|
#define RESET_REQ 0xb
|
|
|
|
#define RESET_ACK 0xc
|
|
|
|
#define REXMIT_NAK 0xd
|
|
|
|
|
|
|
|
|
|
|
|
static const value_string cmd_string[] = {
|
|
|
|
{0, "Compressed Data"},
|
|
|
|
{1, "Uncompressed Data"},
|
|
|
|
{15, "Extended"},
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ext_cmd_string[] = {
|
|
|
|
{0, "Per Packet Compression"},
|
|
|
|
{4, "Connect Req"},
|
|
|
|
{5, "Connect Ack"},
|
|
|
|
{9, "Init Req"},
|
|
|
|
{0x0a, "Init Ack"},
|
|
|
|
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pinfo, proto_tree *tree);
|
|
|
|
static wcp_window_t *get_wcp_window_ptr( packet_info *pinfo);
|
|
|
|
|
|
|
|
static void
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_con_req(tvbuff_t *tvb, int offset, proto_tree *tree) {
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* WCP connector request message */
|
|
|
|
|
|
|
|
guint alg_cnt = tvb_get_guint8(tvb, 5);
|
|
|
|
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_tid, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_rev, tvb, offset + 2, 1, tvb_get_guint8(tvb, offset + 2));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_init, tvb, offset + 3, 1, tvb_get_guint8(tvb, offset + 3));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_seq_size, tvb, offset + 4, 1, tvb_get_guint8(tvb, offset + 4));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg_cnt, tvb, offset + 5, 1, alg_cnt);
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg_a, tvb, offset + 6, 1, tvb_get_guint8(tvb, offset + 6));
|
|
|
|
if ( alg_cnt > 1)
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg_b, tvb, offset + 7, 1, tvb_get_guint8(tvb, offset + 7));
|
|
|
|
if ( alg_cnt > 2)
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg_c, tvb, offset + 8, 1, tvb_get_guint8(tvb, offset + 8));
|
|
|
|
if ( alg_cnt > 3)
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg_d, tvb, offset + 9, 1, tvb_get_guint8(tvb, offset + 9));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_con_ack( tvbuff_t *tvb, int offset, proto_tree *tree){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* WCP connector ack message */
|
|
|
|
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_tid, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_rev, tvb, offset + 2, 1, tvb_get_guint8(tvb, offset + 2));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_seq_size, tvb, offset + 3, 1, tvb_get_guint8(tvb, offset + 3));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_alg, tvb, offset + 4, 1, tvb_get_guint8(tvb, offset + 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_init( tvbuff_t *tvb, int offset, proto_tree *tree){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* WCP Initiate Request/Ack message */
|
|
|
|
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_tid, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_rev, tvb, offset + 2, 1, tvb_get_guint8(tvb, offset + 2));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_hist_size, tvb, offset + 3, 1, tvb_get_guint8(tvb, offset + 3));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_ppc, tvb, offset + 4, 1, tvb_get_guint8(tvb, offset + 4));
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_pib, tvb, offset + 5, 1, tvb_get_guint8(tvb, offset + 5));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_reset( tvbuff_t *tvb, int offset, proto_tree *tree){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* Process WCP Reset Request/Ack message */
|
|
|
|
|
|
|
|
proto_tree_add_uint(tree, hf_wcp_tid, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-11-27 07:36:23 +00:00
|
|
|
static void wcp_save_data( tvbuff_t *tvb, packet_info *pinfo){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
wcp_window_t *buf_ptr = 0;
|
2009-04-04 19:34:06 +00:00
|
|
|
size_t len;
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* discard first 2 bytes, header and last byte (check byte) */
|
|
|
|
len = tvb_reported_length( tvb)-3;
|
2002-08-28 21:04:11 +00:00
|
|
|
buf_ptr = get_wcp_window_ptr( pinfo);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
if (( buf_ptr->buf_cur + len) <= (buf_ptr->buffer + MAX_WIN_BUF_LEN)){
|
|
|
|
tvb_memcpy( tvb, buf_ptr->buf_cur, 2, len);
|
|
|
|
buf_ptr->buf_cur = buf_ptr->buf_cur + len;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
} else {
|
2002-08-28 21:04:11 +00:00
|
|
|
guint8 *buf_end = buf_ptr->buffer + MAX_WIN_BUF_LEN;
|
2001-03-23 19:22:02 +00:00
|
|
|
tvb_memcpy( tvb, buf_ptr->buf_cur, 2, buf_end - buf_ptr->buf_cur);
|
2009-04-04 19:34:06 +00:00
|
|
|
tvb_memcpy( tvb, buf_ptr->buffer, (gint) (buf_end - buf_ptr->buf_cur-2),
|
2009-04-03 18:55:25 +00:00
|
|
|
len - (buf_end - buf_ptr->buf_cur));
|
2001-03-23 19:22:02 +00:00
|
|
|
buf_ptr->buf_cur = buf_ptr->buf_cur + len - MAX_WIN_BUF_LEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-11-27 07:36:23 +00:00
|
|
|
static void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
proto_tree *wcp_tree;
|
|
|
|
proto_item *ti;
|
|
|
|
int wcp_header_len;
|
|
|
|
guint16 temp, cmd, ext_cmd, seq;
|
|
|
|
tvbuff_t *next_tvb;
|
|
|
|
|
2009-08-09 06:26:46 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WCP");
|
2009-08-09 07:36:13 +00:00
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
temp =tvb_get_ntohs(tvb, 0);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
cmd = (temp & 0xf000) >> 12;
|
|
|
|
ext_cmd = (temp & 0x0f00) >> 8;
|
|
|
|
|
|
|
|
if ( cmd == 0xf)
|
|
|
|
wcp_header_len= 1;
|
2002-08-28 21:04:11 +00:00
|
|
|
else
|
2001-03-23 19:22:02 +00:00
|
|
|
wcp_header_len= 2;
|
|
|
|
|
|
|
|
seq = temp & 0x0fff;
|
|
|
|
|
|
|
|
/*XXX should test seq to be sure it the last + 1 !! */
|
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)){
|
2012-08-10 22:55:02 +00:00
|
|
|
col_add_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmd, cmd_string, "Unknown"));
|
2001-03-23 19:22:02 +00:00
|
|
|
if ( cmd == 0xf)
|
2001-12-10 00:26:21 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
|
2012-08-10 22:55:02 +00:00
|
|
|
val_to_str_const(ext_cmd, ext_cmd_string, "Unknown"));
|
2002-08-28 21:04:11 +00:00
|
|
|
}
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2011-10-21 02:10:19 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_wcp, tvb, 0, wcp_header_len, ENC_NA);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
wcp_tree = proto_item_add_subtree(ti, ett_wcp);
|
|
|
|
|
|
|
|
proto_tree_add_uint(wcp_tree, hf_wcp_cmd, tvb, 0, 1, tvb_get_guint8( tvb, 0));
|
|
|
|
if ( cmd == 0xf){
|
|
|
|
proto_tree_add_uint(wcp_tree, hf_wcp_ext_cmd, tvb, 1, 1,
|
|
|
|
tvb_get_guint8( tvb, 0));
|
|
|
|
switch (ext_cmd){
|
|
|
|
case CONNECT_REQ:
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_con_req( tvb, 1, wcp_tree);
|
2001-03-23 19:22:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CONNECT_ACK:
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_con_ack( tvb, 1, wcp_tree);
|
2001-03-23 19:22:02 +00:00
|
|
|
break;
|
|
|
|
case INIT_REQ:
|
|
|
|
case INIT_ACK:
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_init( tvb, 1, wcp_tree);
|
2001-03-23 19:22:02 +00:00
|
|
|
break;
|
|
|
|
case RESET_REQ:
|
|
|
|
case RESET_ACK:
|
2002-04-11 09:38:03 +00:00
|
|
|
dissect_wcp_reset( tvb, 1, wcp_tree);
|
2001-03-23 19:22:02 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
}else {
|
2001-03-23 19:22:02 +00:00
|
|
|
proto_tree_add_uint(wcp_tree, hf_wcp_seq, tvb, 0, 2, seq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
wcp_tree = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* exit if done */
|
2002-08-28 21:04:11 +00:00
|
|
|
if ( cmd != 1 && cmd != 0 && !(cmd == 0xf && ext_cmd == 0))
|
2001-03-23 19:22:02 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if ( cmd == 1) { /* uncompressed data */
|
|
|
|
if ( !pinfo->fd->flags.visited){ /* if first pass */
|
|
|
|
wcp_save_data( tvb, pinfo);
|
|
|
|
}
|
2009-08-16 12:36:22 +00:00
|
|
|
next_tvb = tvb_new_subset_remaining(tvb, wcp_header_len);
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
|
|
|
else { /* cmd == 0 || (cmd == 0xf && ext_cmd == 0) */
|
|
|
|
|
|
|
|
next_tvb = wcp_uncompress( tvb, wcp_header_len, pinfo, wcp_tree);
|
|
|
|
|
|
|
|
if ( !next_tvb){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( tree) /* add the check byte */
|
|
|
|
proto_tree_add_uint(wcp_tree, hf_wcp_chksum, tvb,
|
|
|
|
tvb_reported_length( tvb)-1, 1,
|
|
|
|
tvb_get_guint8( tvb, tvb_reported_length(tvb)-1));
|
|
|
|
|
2002-07-31 19:27:57 +00:00
|
|
|
call_dissector(fr_uncompressed_handle, next_tvb, pinfo, tree);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-11 09:38:03 +00:00
|
|
|
static guint8 *decompressed_entry( guint8 *src, guint8 *dst, int *len, guint8 * buf_start, guint8 *buf_end){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
/* do the decompression for one field */
|
|
|
|
|
|
|
|
guint16 data_offset, data_cnt;
|
|
|
|
guint8 tmp = *src;
|
|
|
|
|
|
|
|
data_offset = (*(src++) & 0xf) << 8; /* get high byte */
|
|
|
|
data_offset += *(src++); /* add next byte */
|
|
|
|
|
|
|
|
if (( tmp & 0xf0) == 0x10){ /* 2 byte count */
|
|
|
|
data_cnt = *src;
|
|
|
|
data_cnt++;
|
|
|
|
|
|
|
|
}else { /* one byte count */
|
|
|
|
data_cnt = tmp >> 4;
|
|
|
|
data_cnt++;
|
2002-08-28 21:04:11 +00:00
|
|
|
}
|
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
src = (dst - 1 - data_offset);
|
|
|
|
if ( src < buf_start)
|
|
|
|
src += MAX_WIN_BUF_LEN;
|
|
|
|
|
|
|
|
|
|
|
|
/*XXX could do some fancy memory moves, later if speed is problem */
|
|
|
|
|
|
|
|
while( data_cnt--){
|
|
|
|
*dst = *src;
|
|
|
|
if ( ++(*len) >MAX_WCP_BUF_LEN){
|
|
|
|
return NULL; /* end of buffer error */
|
|
|
|
}
|
|
|
|
if ( dst++ == buf_end)
|
|
|
|
dst = buf_start;
|
|
|
|
if ( src++ == buf_end)
|
|
|
|
src = buf_start;
|
|
|
|
|
|
|
|
}
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
static
|
2001-03-23 19:22:02 +00:00
|
|
|
wcp_window_t *get_wcp_window_ptr( packet_info *pinfo){
|
|
|
|
|
2002-10-22 08:22:07 +00:00
|
|
|
/* find the circuit for this DLCI, create one if needed */
|
2001-03-23 19:22:02 +00:00
|
|
|
/* and return the wcp_window data structure pointer */
|
2002-10-22 08:22:07 +00:00
|
|
|
/* for the direction of this packet */
|
|
|
|
|
|
|
|
circuit_t *circuit;
|
|
|
|
wcp_circuit_data_t *wcp_circuit_data;
|
2001-03-23 19:22:02 +00:00
|
|
|
|
2002-11-08 01:00:07 +00:00
|
|
|
circuit = find_circuit( pinfo->ctype, pinfo->circuit_id,
|
|
|
|
pinfo->fd->num);
|
2002-10-22 08:22:07 +00:00
|
|
|
if ( !circuit){
|
2002-11-08 01:00:07 +00:00
|
|
|
circuit = circuit_new( pinfo->ctype, pinfo->circuit_id,
|
|
|
|
pinfo->fd->num);
|
2001-09-03 10:33:12 +00:00
|
|
|
}
|
2013-03-04 07:25:57 +00:00
|
|
|
wcp_circuit_data = (wcp_circuit_data_t *)circuit_get_proto_data(circuit, proto_wcp);
|
2002-10-22 08:22:07 +00:00
|
|
|
if ( !wcp_circuit_data){
|
2013-03-04 07:25:57 +00:00
|
|
|
wcp_circuit_data = se_new(wcp_circuit_data_t);
|
2002-10-22 08:22:07 +00:00
|
|
|
wcp_circuit_data->recv.buf_cur = wcp_circuit_data->recv.buffer;
|
|
|
|
wcp_circuit_data->send.buf_cur = wcp_circuit_data->send.buffer;
|
|
|
|
circuit_add_proto_data(circuit, proto_wcp, wcp_circuit_data);
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
2002-10-22 08:22:07 +00:00
|
|
|
if (pinfo->pseudo_header->x25.flags & FROM_DCE)
|
|
|
|
return &wcp_circuit_data->recv;
|
|
|
|
else
|
|
|
|
return &wcp_circuit_data->send;
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pinfo, proto_tree *tree) {
|
|
|
|
|
|
|
|
/* do the packet data uncompression and load it into the dst buffer */
|
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
proto_tree *cd_tree, *sub_tree;
|
|
|
|
proto_item *cd_item, *ti;
|
2001-03-23 19:22:02 +00:00
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
int len, i;
|
2001-03-23 19:22:02 +00:00
|
|
|
int cnt = tvb_reported_length( src_tvb)-1; /* don't include check byte */
|
|
|
|
|
2009-07-30 23:47:36 +00:00
|
|
|
guint8 *dst, *src, *buf_start, *buf_end, comp_flag_bits = 0;
|
2001-03-23 19:22:02 +00:00
|
|
|
guint8 src_buf[ MAX_WCP_BUF_LEN];
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
tvbuff_t *tvb;
|
2001-03-23 19:22:02 +00:00
|
|
|
wcp_window_t *buf_ptr = 0;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
wcp_pdata_t *pdata_ptr;
|
2011-10-12 16:31:41 +00:00
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
buf_ptr = get_wcp_window_ptr( pinfo);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
buf_start = buf_ptr->buffer;
|
|
|
|
buf_end = buf_start + MAX_WIN_BUF_LEN;
|
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
cd_item = proto_tree_add_item(tree, hf_wcp_compressed_data,
|
|
|
|
src_tvb, offset, cnt - offset, ENC_NA);
|
|
|
|
cd_tree = proto_item_add_subtree(cd_item, ett_wcp_comp_data);
|
2002-06-06 22:42:27 +00:00
|
|
|
if (cnt - offset > MAX_WCP_BUF_LEN) {
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
expert_add_info_format(pinfo, cd_item, PI_MALFORMED, PI_ERROR,
|
|
|
|
"Compressed data exceeds maximum buffer length (%d > %d)",
|
|
|
|
cnt - offset, MAX_WCP_BUF_LEN);
|
2002-06-06 22:42:27 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-04 07:25:57 +00:00
|
|
|
src = (guint8 *)tvb_memcpy(src_tvb, src_buf, offset, cnt - offset);
|
2001-03-23 19:22:02 +00:00
|
|
|
dst = buf_ptr->buf_cur;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
len = 0;
|
|
|
|
i = -1;
|
2001-03-23 19:22:02 +00:00
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
while( offset < cnt){
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
if ( --i >= 0){
|
|
|
|
if ( comp_flag_bits & 0x80){ /* if this is a compressed entry */
|
|
|
|
|
|
|
|
if ( !pinfo->fd->flags.visited){ /* if first pass */
|
|
|
|
dst = decompressed_entry( src, dst, &len, buf_start, buf_end);
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
if (dst == NULL){
|
|
|
|
expert_add_info_format(pinfo, cd_item, PI_MALFORMED, PI_ERROR,
|
|
|
|
"Uncompressed data exceeds maximum buffer length (%d > %d)",
|
|
|
|
len, MAX_WCP_BUF_LEN);
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
|
|
|
if ((*src & 0xf0) == 0x10){
|
2001-03-23 20:47:17 +00:00
|
|
|
if ( tree) {
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
ti = proto_tree_add_item( cd_tree, hf_wcp_long_run, src_tvb,
|
|
|
|
offset, 3, ENC_NA);
|
2001-03-23 20:47:17 +00:00
|
|
|
sub_tree = proto_item_add_subtree(ti, ett_wcp_field);
|
|
|
|
proto_tree_add_uint(sub_tree, hf_wcp_offset, src_tvb,
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset, 2, pntohs(src));
|
2001-03-23 19:22:02 +00:00
|
|
|
|
2001-03-23 20:47:17 +00:00
|
|
|
proto_tree_add_item( sub_tree, hf_wcp_long_len, src_tvb,
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset+2, 1, ENC_BIG_ENDIAN);
|
2001-03-23 20:47:17 +00:00
|
|
|
}
|
2001-03-23 19:22:02 +00:00
|
|
|
src += 3;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset += 3;
|
2001-03-23 19:22:02 +00:00
|
|
|
}else{
|
2001-03-23 20:47:17 +00:00
|
|
|
if ( tree) {
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
ti = proto_tree_add_item( cd_tree, hf_wcp_short_run, src_tvb,
|
|
|
|
offset, 2, ENC_NA);
|
2001-03-23 20:47:17 +00:00
|
|
|
sub_tree = proto_item_add_subtree(ti, ett_wcp_field);
|
2011-10-12 16:31:41 +00:00
|
|
|
proto_tree_add_uint( sub_tree, hf_wcp_short_len, src_tvb,
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset, 1, *src);
|
2001-03-23 20:47:17 +00:00
|
|
|
proto_tree_add_uint(sub_tree, hf_wcp_offset, src_tvb,
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset, 2, pntohs(src));
|
2001-03-23 20:47:17 +00:00
|
|
|
}
|
2001-03-23 19:22:02 +00:00
|
|
|
src += 2;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset += 2;
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
|
|
|
}else {
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
if ( ++len >MAX_WCP_BUF_LEN){
|
|
|
|
expert_add_info_format(pinfo, cd_item, PI_MALFORMED, PI_ERROR,
|
|
|
|
"Uncompressed data exceeds maximum buffer length (%d > %d)",
|
|
|
|
len, MAX_WCP_BUF_LEN);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
if ( !pinfo->fd->flags.visited){ /* if first pass */
|
|
|
|
*dst = *src;
|
|
|
|
if ( dst++ == buf_end)
|
|
|
|
dst = buf_start;
|
|
|
|
}
|
|
|
|
++src;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
++offset;
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
comp_flag_bits <<= 1;
|
|
|
|
|
|
|
|
}else { /* compressed data flag */
|
|
|
|
|
|
|
|
comp_flag_bits = *src++;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
if (cd_tree)
|
|
|
|
proto_tree_add_uint(cd_tree, hf_wcp_comp_bits, src_tvb, offset, 1,
|
2001-03-23 20:47:17 +00:00
|
|
|
comp_flag_bits);
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
offset++;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
i = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pinfo->fd->flags.visited){ /* if not first pass */
|
|
|
|
/* get uncompressed data */
|
2013-03-04 07:25:57 +00:00
|
|
|
pdata_ptr = (wcp_pdata_t *)p_get_proto_data( pinfo->fd, proto_wcp);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
if ( !pdata_ptr) { /* exit if no data */
|
|
|
|
REPORT_DISSECTOR_BUG("Can't find uncompressed data");
|
2001-03-23 19:22:02 +00:00
|
|
|
return NULL;
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
len = pdata_ptr->len;
|
2001-03-23 19:22:02 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
/* save the new data as per packet data */
|
2013-03-04 07:25:57 +00:00
|
|
|
pdata_ptr = se_new(wcp_pdata_t);
|
2001-03-23 19:22:02 +00:00
|
|
|
memcpy( &pdata_ptr->buffer, buf_ptr->buf_cur, len);
|
|
|
|
pdata_ptr->len = len;
|
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
p_add_proto_data( pinfo->fd, proto_wcp, (void*)pdata_ptr);
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
buf_ptr->buf_cur = dst;
|
|
|
|
}
|
|
|
|
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
tvb = tvb_new_child_real_data(src_tvb, pdata_ptr->buffer, pdata_ptr->len, pdata_ptr->len);
|
2011-10-12 16:31:41 +00:00
|
|
|
|
2001-03-23 19:22:02 +00:00
|
|
|
/* Add new data to the data source list */
|
2002-06-04 07:03:57 +00:00
|
|
|
add_new_data_source( pinfo, tvb, "Uncompressed WCP");
|
2001-03-23 19:22:02 +00:00
|
|
|
return tvb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_wcp(void)
|
|
|
|
{
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_wcp_cmd,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Command", "wcp.cmd", FT_UINT8, BASE_HEX, VALS(cmd_string), WCP_CMD,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Compression Command", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_ext_cmd,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Extended Command", "wcp.ext_cmd", FT_UINT8, BASE_HEX, VALS(ext_cmd_string), WCP_EXT_CMD,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Extended Compression Command", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_seq,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "SEQ", "wcp.seq", FT_UINT16, BASE_HEX, NULL, WCP_SEQ,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Sequence Number", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_chksum,
|
|
|
|
{ "Checksum", "wcp.checksum", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Packet Checksum", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_tid,
|
|
|
|
{ "TID", "wcp.tid", FT_UINT16, BASE_DEC, NULL, 0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_rev,
|
|
|
|
{ "Revision", "wcp.rev", FT_UINT8, BASE_DEC, NULL, 0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_init,
|
|
|
|
{ "Initiator", "wcp.init", FT_UINT8, BASE_DEC, NULL, 0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_seq_size,
|
|
|
|
{ "Seq Size", "wcp.seq_size", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Sequence Size", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg_cnt,
|
|
|
|
{ "Alg Count", "wcp.alg_cnt", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm Count", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg_a,
|
|
|
|
{ "Alg 1", "wcp.alg1", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm #1", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg_b,
|
|
|
|
{ "Alg 2", "wcp.alg2", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm #2", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg_c,
|
|
|
|
{ "Alg 3", "wcp.alg3", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm #3", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg_d,
|
|
|
|
{ "Alg 4", "wcp.alg4", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm #4", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_alg,
|
|
|
|
{ "Alg", "wcp.alg", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Algorithm", HFILL }},
|
2013-01-31 18:31:28 +00:00
|
|
|
#if 0
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_rexmit,
|
|
|
|
{ "Rexmit", "wcp.rexmit", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Retransmit", HFILL }},
|
2013-01-31 18:31:28 +00:00
|
|
|
#endif
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_hist_size,
|
|
|
|
{ "History", "wcp.hist", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"History Size", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_ppc,
|
|
|
|
{ "PerPackComp", "wcp.ppc", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Per Packet Compression", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_pib,
|
|
|
|
{ "PIB", "wcp.pib", FT_UINT8, BASE_DEC, NULL, 0,
|
From Kovarththanan Rajaratnam via bug 3548:
(1) Trailing/leading spaces are removed from 'name's/'blurb's
(2) Duplicate 'blurb's are replaced with NULL
(3) Empty ("") 'blurb's are replaced with NULL
(4) BASE_NONE, NULL, 0x0 are used for 'display', 'strings' and 'bitmask' fields
for FT_NONE, FT_BYTES, FT_IPv4, FT_IPv6, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME,
FT_PROTOCOL, FT_STRING and FT_STRINGZ field types
(5) Only allow non-zero value for 'display' if 'bitmask' is non-zero
svn path=/trunk/; revision=28770
2009-06-18 21:30:42 +00:00
|
|
|
NULL, HFILL }},
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
{ &hf_wcp_compressed_data,
|
|
|
|
{ "Compressed Data", "wcp.compressed_data", FT_NONE, BASE_NONE, NULL, 0,
|
|
|
|
"Raw compressed data", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_comp_bits,
|
|
|
|
{ "Compress Flag", "wcp.flag", FT_UINT8, BASE_HEX, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Compressed byte flag", HFILL }},
|
2013-01-31 18:31:28 +00:00
|
|
|
#if 0
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_comp_marker,
|
2003-01-31 03:17:56 +00:00
|
|
|
{ "Compress Marker", "wcp.mark", FT_UINT8, BASE_DEC, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Compressed marker", HFILL }},
|
2013-01-31 18:31:28 +00:00
|
|
|
#endif
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_offset,
|
|
|
|
{ "Source offset", "wcp.off", FT_UINT16, BASE_HEX, NULL, WCP_OFFSET_MASK,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Data source offset", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_short_len,
|
|
|
|
{ "Compress Length", "wcp.short_len", FT_UINT8, BASE_HEX, NULL, 0xf0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Compressed length", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_long_len,
|
|
|
|
{ "Compress Length", "wcp.long_len", FT_UINT8, BASE_HEX, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Compressed length", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_long_run,
|
2011-10-12 16:31:41 +00:00
|
|
|
{ "Long Compression", "wcp.long_comp", FT_BYTES, BASE_NONE, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Long Compression type", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
{ &hf_wcp_short_run,
|
2011-10-12 16:31:41 +00:00
|
|
|
{ "Short Compression", "wcp.short_comp", FT_BYTES, BASE_NONE, NULL, 0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"Short Compression type", HFILL }},
|
2001-03-23 19:22:02 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_wcp,
|
When decompressing, put an entry into the protocol tree that covers all
the compressed data, put the entries for particular parts of that data
under that entry, and, when we have a problem decompressing, add an
expert info item to that entry, rather than just adding text or using
proto_malformed. Do so for *all* decompression problems; in particular,
check for decompressed_entry() returning NULL, which it can do.
tvb_new_child_real_data() won't throw an exception, so don't bother
checking for that.
If, after the first pass, we can't find the uncompressed data for a
frame, report it as a dissector bug.
Check whether we have room for a byte in the uncompressed data buffer
*before* copying it.
Other cleanups.
svn path=/trunk/; revision=47922
2013-02-27 22:04:40 +00:00
|
|
|
&ett_wcp_comp_data,
|
2001-03-23 19:22:02 +00:00
|
|
|
&ett_wcp_field,
|
|
|
|
};
|
|
|
|
|
|
|
|
proto_wcp = proto_register_protocol ("Wellfleet Compression", "WCP", "wcp");
|
|
|
|
proto_register_field_array (proto_wcp, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_wcp(void) {
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t wcp_handle;
|
2001-03-23 19:22:02 +00:00
|
|
|
|
2001-11-27 07:13:32 +00:00
|
|
|
/*
|
|
|
|
* Get handle for the Frame Relay (uncompressed) dissector.
|
|
|
|
*/
|
2002-07-31 19:27:57 +00:00
|
|
|
fr_uncompressed_handle = find_dissector("fr_uncompressed");
|
2001-11-27 07:13:32 +00:00
|
|
|
|
2001-12-03 04:00:26 +00:00
|
|
|
wcp_handle = create_dissector_handle(dissect_wcp, proto_wcp);
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("fr.ietf", NLPID_COMPRESSED, wcp_handle);
|
|
|
|
dissector_add_uint("ethertype", ETHERTYPE_WCP, wcp_handle);
|
2001-03-23 19:22:02 +00:00
|
|
|
}
|