* Routines for Wellfleet Compression frame disassembly
* Copyright 2001, Jeffrey C. Foster <jfoste@woodward.com>
*
- * $Id: packet-wcp.c,v 1.5 2001/03/26 18:55:27 jfoster Exp $
+ * $Id: packet-wcp.c,v 1.27 2002/08/02 23:36:04 jmayer Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998
- *
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
# include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
#include <stdio.h>
#include <glib.h>
#include <string.h>
-#include "packet.h"
+#include <epan/packet.h>
#include "packet-frame.h"
-#include "packet-osi.h"
-#include "conversation.h"
+#include <epan/conversation.h>
+#include "etypes.h"
#include "nlpid.h"
-#include "oui.h"
-#include "packet-llc.h"
#define MAX_WIN_BUF_LEN 0x7fff /* storage size for decompressed data */
#define MAX_WCP_BUF_LEN 2048 /* storage size for decompressed data */
static GMemChunk *wcp_window = NULL;
static GMemChunk *wcp_pdata = NULL;
-extern dissector_table_t fr_subdissector_table;
-
static int proto_wcp = -1;
static int hf_wcp_cmd = -1;
static int hf_wcp_ext_cmd = -1;
static int hf_wcp_long_run = -1;
static int hf_wcp_offset = -1;
-/*$$ are these needed or should the Frame relay stuff be used (call a decoder in frame relay)?? */
-static int hf_wcp_oui = -1;
-static int hf_wcp_pid = -1;
-static int hf_wcp_type = -1;
-
static gint ett_wcp = -1;
static gint ett_wcp_field = -1;
-#define ETHERTYPE_WCP 0x80ff /* ether snap value for WCP */
+static dissector_handle_t fr_uncompressed_handle;
/*
* Bits in the address field.
static wcp_window_t *get_wcp_window_ptr( packet_info *pinfo);
static void
-dissect_wcp_con_req(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+dissect_wcp_con_req(tvbuff_t *tvb, int offset, proto_tree *tree) {
/* WCP connector request message */
}
static void
-dissect_wcp_con_ack( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree){
+dissect_wcp_con_ack( tvbuff_t *tvb, int offset, proto_tree *tree){
/* WCP connector ack message */
}
static void
-dissect_wcp_init( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree){
+dissect_wcp_init( tvbuff_t *tvb, int offset, proto_tree *tree){
/* WCP Initiate Request/Ack message */
static void
-dissect_wcp_reset( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree){
+dissect_wcp_reset( tvbuff_t *tvb, int offset, proto_tree *tree){
/* Process WCP Reset Request/Ack message */
}
-void wcp_save_data( tvbuff_t *tvb, packet_info *pinfo){
+static void wcp_save_data( tvbuff_t *tvb, packet_info *pinfo){
wcp_window_t *buf_ptr = 0;
int len;
}
-void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+static void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
proto_tree *wcp_tree;
proto_item *ti;
int wcp_header_len;
guint16 temp, cmd, ext_cmd, seq;
tvbuff_t *next_tvb;
- guint8 protocol_id;
-
- temp = tvb_get_guint8(tvb, 0);
- if (!proto_is_protocol_enabled(proto_wcp))
- return;
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WCP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
temp =tvb_get_ntohs(tvb, 0);
- pinfo->current_proto = "WCP";
-
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_set_str(pinfo->fd, COL_PROTOCOL, "WCP");
-
cmd = (temp & 0xf000) >> 12;
ext_cmd = (temp & 0x0f00) >> 8;
/*XXX should test seq to be sure it the last + 1 !! */
- if (check_col(pinfo->fd, COL_INFO)){
- col_add_str(pinfo->fd, COL_INFO, val_to_str(cmd, cmd_string, "Unknown"));
+ if (check_col(pinfo->cinfo, COL_INFO)){
+ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, cmd_string, "Unknown"));
if ( cmd == 0xf)
- col_append_fstr(pinfo->fd, COL_INFO, ", %s",
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
val_to_str(ext_cmd, ext_cmd_string, "Unknown"));
}
tvb_get_guint8( tvb, 0));
switch (ext_cmd){
case CONNECT_REQ:
- dissect_wcp_con_req( tvb, 1, pinfo, wcp_tree);
+ dissect_wcp_con_req( tvb, 1, wcp_tree);
break;
case CONNECT_ACK:
- dissect_wcp_con_ack( tvb, 1, pinfo, wcp_tree);
+ dissect_wcp_con_ack( tvb, 1, wcp_tree);
break;
case INIT_REQ:
case INIT_ACK:
- dissect_wcp_init( tvb, 1, pinfo, wcp_tree);
+ dissect_wcp_init( tvb, 1, wcp_tree);
break;
case RESET_REQ:
case RESET_ACK:
- dissect_wcp_reset( tvb, 1, pinfo, wcp_tree);
+ dissect_wcp_reset( tvb, 1, wcp_tree);
break;
default:
break;
tvb_reported_length( tvb)-1, 1,
tvb_get_guint8( tvb, tvb_reported_length(tvb)-1));
- protocol_id = tvb_get_guint8( next_tvb, 0);
-
-/*XXX This isn't really what we want to do !! Should be able to call a decoder */
-/* routine in the frame relay code or PPP (if that is added). */
-
- if (!dissector_try_port(fr_subdissector_table, protocol_id,
- tvb_new_subset(next_tvb, 1,-1,-1), pinfo, tree))
- dissect_snap(next_tvb, 0, pinfo, tree, wcp_tree, 0,
- hf_wcp_oui, hf_wcp_type, hf_wcp_pid, 0);
+ call_dissector(fr_uncompressed_handle, next_tvb, pinfo, tree);
return;
}
-guint8 *decompressed_entry( guint8 *src, guint8 *dst, int *len, guint8 * buf_start, guint8 *buf_end){
+static guint8 *decompressed_entry( guint8 *src, guint8 *dst, int *len, guint8 * buf_start, guint8 *buf_end){
/* do the decompression for one field */
/* find the conversation for this side of the DLCI, create one if needed */
/* and return the wcp_window data structure pointer */
- conversation_t *conv = find_conversation( &pinfo->dl_src, &pinfo->dl_src, PT_NONE,
+ conversation_t *conv;
+ wcp_window_t *wcp_win_data;
+
+ conv = find_conversation( &pinfo->dl_src, &pinfo->dl_src, PT_NONE,
((pinfo->pseudo_header->x25.flags & FROM_DCE)? 1:0),
((pinfo->pseudo_header->x25.flags & FROM_DCE)? 1:0), 0);
-
if ( !conv){
-
conv = conversation_new( &pinfo->dl_src, &pinfo->dl_src, PT_NONE,
((pinfo->pseudo_header->x25.flags & FROM_DCE)? 1:0),
((pinfo->pseudo_header->x25.flags & FROM_DCE)? 1:0),
- g_mem_chunk_alloc( wcp_window), 0);
-
- ((wcp_window_t*)conv->data)->buf_cur = ((wcp_window_t*)conv->data)->buffer;
+ 0);
+ }
+ wcp_win_data = conversation_get_proto_data(conv, proto_wcp);
+ if ( !wcp_win_data){
+ wcp_win_data = g_mem_chunk_alloc( wcp_window);
+ wcp_win_data->buf_cur = wcp_win_data->buffer;
+ conversation_add_proto_data(conv, proto_wcp, wcp_win_data);
}
- return (wcp_window_t*)conv->data;
+ return wcp_win_data;
}
buf_end = buf_start + MAX_WIN_BUF_LEN;
tmp = buf_ptr->buf_cur;
+ if (cnt - offset > MAX_WCP_BUF_LEN) {
+ if (tree)
+ proto_tree_add_text( tree, src_tvb, offset, -1,
+ "Compressed data exceeds maximum buffer length (%d > %d)",
+ cnt - offset, MAX_WCP_BUF_LEN);
+ return NULL;
+ }
+
src = tvb_memcpy(src_tvb, src_buf, offset, cnt - offset);
dst = buf_ptr->buf_cur;
TRY {
- tvb = tvb_new_real_data( pdata_ptr->buffer, pdata_ptr->len, pdata_ptr->len, "uncompressed");
+ tvb = tvb_new_real_data( pdata_ptr->buffer, pdata_ptr->len, pdata_ptr->len);
}
CATCH(BoundsError) {
- g_assert_not_reached();
+ g_assert_not_reached();
g_free(buf);
return NULL;
}
CATCH(ReportedBoundsError) {
- g_free(buf);
- return NULL;
+ g_free(buf);
+ return NULL;
}
ENDTRY;
tvb_set_child_real_data_tvbuff( src_tvb, tvb);
/* Add new data to the data source list */
- pinfo->fd->data_src = g_slist_append( pinfo->fd->data_src, tvb);
+ add_new_data_source( pinfo, tvb, "Uncompressed WCP");
return tvb;
}
static hf_register_info hf[] = {
{ &hf_wcp_cmd,
{ "Command", "wcp.cmd", FT_UINT8, BASE_HEX, VALS(cmd_string), WCP_CMD,
- "Compression Command" }},
+ "Compression Command", HFILL }},
{ &hf_wcp_ext_cmd,
{ "Extended Command", "wcp.ext_cmd", FT_UINT8, BASE_HEX, VALS(ext_cmd_string), WCP_EXT_CMD,
- "Extended Compression Command" }},
+ "Extended Compression Command", HFILL }},
{ &hf_wcp_seq,
{ "SEQ", "wcp.seq", FT_UINT16, BASE_HEX, NULL, WCP_SEQ,
- "Sequence Number" }},
+ "Sequence Number", HFILL }},
{ &hf_wcp_chksum,
{ "Checksum", "wcp.checksum", FT_UINT8, BASE_DEC, NULL, 0,
- "Packet Checksum" }},
+ "Packet Checksum", HFILL }},
{ &hf_wcp_tid,
{ "TID", "wcp.tid", FT_UINT16, BASE_DEC, NULL, 0,
- "TID" }},
+ "TID", HFILL }},
{ &hf_wcp_rev,
{ "Revision", "wcp.rev", FT_UINT8, BASE_DEC, NULL, 0,
- "Revision" }},
+ "Revision", HFILL }},
{ &hf_wcp_init,
{ "Initiator", "wcp.init", FT_UINT8, BASE_DEC, NULL, 0,
- "Initiator" }},
+ "Initiator", HFILL }},
{ &hf_wcp_seq_size,
{ "Seq Size", "wcp.seq_size", FT_UINT8, BASE_DEC, NULL, 0,
- "Sequence Size"}},
+ "Sequence Size", HFILL }},
{ &hf_wcp_alg_cnt,
{ "Alg Count", "wcp.alg_cnt", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm Count"}},
+ "Algorithm Count", HFILL }},
{ &hf_wcp_alg_a,
{ "Alg 1", "wcp.alg1", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm #1"}},
+ "Algorithm #1", HFILL }},
{ &hf_wcp_alg_b,
{ "Alg 2", "wcp.alg2", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm #2"}},
+ "Algorithm #2", HFILL }},
{ &hf_wcp_alg_c,
{ "Alg 3", "wcp.alg3", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm #3"}},
+ "Algorithm #3", HFILL }},
{ &hf_wcp_alg_d,
{ "Alg 4", "wcp.alg4", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm #4"}},
+ "Algorithm #4", HFILL }},
{ &hf_wcp_alg,
{ "Alg", "wcp.alg", FT_UINT8, BASE_DEC, NULL, 0,
- "Algorithm"}},
+ "Algorithm", HFILL }},
{ &hf_wcp_rexmit,
{ "Rexmit", "wcp.rexmit", FT_UINT8, BASE_DEC, NULL, 0,
- "Retransmit"}},
+ "Retransmit", HFILL }},
{ &hf_wcp_hist_size,
{ "History", "wcp.hist", FT_UINT8, BASE_DEC, NULL, 0,
- "History Size"}},
+ "History Size", HFILL }},
{ &hf_wcp_ppc,
{ "PerPackComp", "wcp.ppc", FT_UINT8, BASE_DEC, NULL, 0,
- "Per Packet Compression"}},
+ "Per Packet Compression", HFILL }},
{ &hf_wcp_pib,
{ "PIB", "wcp.pib", FT_UINT8, BASE_DEC, NULL, 0,
- "PIB"}},
+ "PIB", HFILL }},
{ &hf_wcp_comp_bits,
{ "Compress Flag", "wcp.flag", FT_UINT8, BASE_HEX, NULL, 0,
- "Compressed byte flag"}},
+ "Compressed byte flag", HFILL }},
{ &hf_wcp_comp_marker,
{ "Compress Marker", "wcp.mark", FT_UINT8, BASE_BIN, NULL, 0,
- "Compressed marker"}},
+ "Compressed marker", HFILL }},
{ &hf_wcp_offset,
{ "Source offset", "wcp.off", FT_UINT16, BASE_HEX, NULL, WCP_OFFSET_MASK,
- "Data source offset"}},
+ "Data source offset", HFILL }},
{ &hf_wcp_short_len,
{ "Compress Length", "wcp.short_len", FT_UINT8, BASE_HEX, NULL, 0xf0,
- "Compressed length"}},
+ "Compressed length", HFILL }},
{ &hf_wcp_long_len,
{ "Compress Length", "wcp.long_len", FT_UINT8, BASE_HEX, NULL, 0,
- "Compressed length"}},
+ "Compressed length", HFILL }},
{ &hf_wcp_long_run,
{ "Long Compression", "wcp.long_comp", FT_UINT16, BASE_HEX, NULL, 0,
- "Long Compression type"}},
+ "Long Compression type", HFILL }},
{ &hf_wcp_short_run,
{ "Short Compression", "wcp.short_comp", FT_UINT8, BASE_HEX, NULL, 0,
- "Short Compression type"}},
- { &hf_wcp_oui, {
- "Organization Code", "wcp.snap.oui", FT_UINT24, BASE_HEX,
- VALS(oui_vals), 0x0, ""}},
- { &hf_wcp_pid, {
- "Protocol ID", "wcp.snap.pid", FT_UINT16, BASE_HEX,
- NULL, 0x0, ""}},
- { &hf_wcp_type, {
- "Type", "wcp.type", FT_UINT16, BASE_HEX,
- NULL, 0x0, "WCP SNAP Encapsulated Protocol" }},
+ "Short Compression type", HFILL }},
};
void
proto_reg_handoff_wcp(void) {
+ dissector_handle_t wcp_handle;
- dissector_add("fr.ietf", NLPID_WCP, dissect_wcp, proto_wcp);
- dissector_add("ethertype", ETHERTYPE_WCP, dissect_wcp, proto_wcp);
-}
-
-
+ /*
+ * Get handle for the Frame Relay (uncompressed) dissector.
+ */
+ fr_uncompressed_handle = find_dissector("fr_uncompressed");
+ wcp_handle = create_dissector_handle(dissect_wcp, proto_wcp);
+ dissector_add("fr.ietf", NLPID_COMPRESSED, wcp_handle);
+ dissector_add("ethertype", ETHERTYPE_WCP, wcp_handle);
+}