From Ulf Lamping: extend the progress dialog box to give more progress
[obnox/wireshark/wip.git] / packet-wcp.c
index f8490021fe7ade7067d23b5b1380e91bab40cb14..8527b2b2934c38d6865806665c9154aadee58768 100644 (file)
@@ -2,12 +2,11 @@
  * Routines for Wellfleet Compression frame disassembly
  * Copyright 2001, Jeffrey C. Foster <jfoste@woodward.com>
  *
- * $Id: packet-wcp.c,v 1.10 2001/06/18 02:17:54 guy 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-fr.h"
-#include "conversation.h"
+#include <epan/conversation.h>
 #include "etypes.h"
 #include "nlpid.h"
 
@@ -144,8 +138,6 @@ typedef struct {
 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;
@@ -178,6 +170,8 @@ static int hf_wcp_offset = -1;
 static gint ett_wcp = -1;
 static gint ett_wcp_field = -1;
 
+static dissector_handle_t fr_uncompressed_handle;
+
 /*
  * Bits in the address field.
  */
@@ -225,7 +219,7 @@ static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pin
 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 */
 
@@ -246,7 +240,7 @@ dissect_wcp_con_req(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t
 }
 
 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 */
 
@@ -257,7 +251,7 @@ dissect_wcp_con_ack( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *
 }
 
 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 */
 
@@ -270,7 +264,7 @@ dissect_wcp_init( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tre
 
 
 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 */
 
@@ -278,7 +272,7 @@ dissect_wcp_reset( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tr
 }
 
 
-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; 
@@ -302,22 +296,18 @@ void wcp_save_data( tvbuff_t *tvb, packet_info *pinfo){
 }
 
 
-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;
-       packet_info     save_pi;
-       gboolean        must_restore_pi = FALSE;
 
-       pinfo->current_proto = "WCP";
-
-       if (check_col(pinfo->fd, COL_PROTOCOL))
-               col_set_str(pinfo->fd, COL_PROTOCOL, "WCP");
-       if (check_col(pinfo->fd, COL_INFO))
-               col_clear(pinfo->fd, COL_INFO);
+       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); 
 
@@ -333,10 +323,10 @@ void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
 
 /*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"));
        }       
 
@@ -351,19 +341,19 @@ void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
                                        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;
@@ -396,14 +386,6 @@ void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
                                        "[Malformed Frame: Bad WCP compressed data]" );
                        return;
                }
-
-               /* Save the current value of "pi", and adjust certain fields to
-                  reflect the new tvbuff. */
-               save_pi = pi;
-               pi.compat_top_tvb = next_tvb;
-               pi.len = tvb_reported_length(next_tvb);
-               pi.captured_len = tvb_length(next_tvb);
-               must_restore_pi = TRUE;
        }
 
        if ( tree)                      /* add the check byte */
@@ -411,16 +393,13 @@ void dissect_wcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
                        tvb_reported_length( tvb)-1, 1,
                        tvb_get_guint8( tvb, tvb_reported_length(tvb)-1));
 
-       dissect_fr_uncompressed(next_tvb, pinfo, tree);
-
-       if (must_restore_pi)
-               pi = save_pi;
+       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 */
 
@@ -470,21 +449,26 @@ wcp_window_t *get_wcp_window_ptr( packet_info *pinfo){
 /* 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;
 }
 
 
@@ -510,6 +494,14 @@ static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pin
        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;
 
@@ -596,17 +588,17 @@ static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pin
 
 
         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; 
 
@@ -614,7 +606,7 @@ static tvbuff_t *wcp_uncompress( tvbuff_t *src_tvb, int offset, packet_info *pin
         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;
 
 }
@@ -739,7 +731,14 @@ proto_register_wcp(void)
 
 void
 proto_reg_handoff_wcp(void) {
+    dissector_handle_t wcp_handle;
+
+    /*
+     * Get handle for the Frame Relay (uncompressed) dissector.
+     */
+    fr_uncompressed_handle = find_dissector("fr_uncompressed");
 
-    dissector_add("fr.ietf", NLPID_COMPRESSED, dissect_wcp, proto_wcp);
-    dissector_add("ethertype",  ETHERTYPE_WCP, dissect_wcp, proto_wcp);
+    wcp_handle = create_dissector_handle(dissect_wcp, proto_wcp);
+    dissector_add("fr.ietf", NLPID_COMPRESSED, wcp_handle);
+    dissector_add("ethertype",  ETHERTYPE_WCP, wcp_handle);
 }