Set the svn:eol-style property on all text files to "native", so that
[obnox/wireshark/wip.git] / packet-vj.c
index c7b525fded35c5f8f4130a216a1a096b17c75e31..30bbe0cbcaef35ded7758209a773842312a34eba 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-vj.c
- * Routines for Van Jacobson header decompression. 
+ * Routines for Van Jacobson header decompression.
  *
- * $Id: packet-vj.c,v 1.11 2002/05/22 10:15:28 guy Exp $
+ * $Id$
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -9,7 +9,7 @@
  * This file created by Irfan Khan <ikhan@qualcomm.com>
  * Copyright (c) 2001  by QUALCOMM, Incorporated.
  * All Rights reserved.
- * 
+ *
  * Routines to compress and uncompress TCP packets (for transmission
  * over low speed serial lines).
  *
@@ -55,7 +55,7 @@
  *                      Use ip_fast_csum from ip.h
  *      - July 1995     Christos A. Polyzols
  *                      Spotted bug in tcp option checking
- *      - Sep 2001      Irfan Khan 
+ *      - Sep 2001      Irfan Khan
  *                      Rewrite to make the code work for ethereal.
  */
 
 # include "config.h"
 #endif
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
 #include <glib.h>
 #include <string.h>
 #include <epan/packet.h>
+#include "prefs.h"
 #include "packet-ppp.h"
 #include "ppptypes.h"
 #include "ipproto.h"
 
 /* VJ Mem Chunk defines */
 #define VJ_DATA_SIZE  128 /* Max IP hdr(64)+Max TCP hdr(64) */
-#define VJ_ATOM_COUNT 250 /* Number of Atoms per block      */ 
+#define VJ_ATOM_COUNT 250 /* Number of Atoms per block      */
 
 /* IP and TCP header types */
 typedef struct {
@@ -147,7 +144,7 @@ typedef struct {
 
 /* State per active tcp conversation */
 typedef struct cstate {
-  iphdr_type cs_ip; 
+  iphdr_type cs_ip;
   tcphdr_type cs_tcp;
   guint8 cs_ipopt[IP_MAX_OPT_LEN];
   guint8 cs_tcpopt[TCP_MAX_OPT_LEN];
@@ -190,14 +187,14 @@ static dissector_handle_t data_handle;
 /* State repository (Full Duplex) */
 #define RX_TX_STATE_COUNT 2
 static slcompress *rx_tx_state[RX_TX_STATE_COUNT] = {NULL, NULL};
+
 /* Mem Chunks for storing decompressed headers */
 static GMemChunk *vj_header_memchunk = NULL;
 typedef struct {
        int     offset;                 /* uppermost bit is "can't dissect" flag */
        guint8  data[VJ_DATA_SIZE];
 } vj_header_t;
-       
+
 /* Function prototypes */
 static int get_unsigned_delta(tvbuff_t *tvb, int *offsetp, int hf,
                         proto_tree *tree);
@@ -226,6 +223,7 @@ dissect_vjuc(tvbuff_t *tvb, packet_info *pinfo, proto_tree * tree)
   guint8     *buffer;
   tvbuff_t   *next_tvb;
   gint        isize       = tvb_length(tvb);
+  gint        ipsize;
 
   if(check_col(pinfo->cinfo, COL_PROTOCOL))
     col_set_str(pinfo->cinfo, COL_INFO, "PPP VJ");
@@ -311,8 +309,7 @@ dissect_vjuc(tvbuff_t *tvb, packet_info *pinfo, proto_tree * tree)
    * Copy packet data to a buffer, and replace the connection index with
    * the protocol type (which is always TCP), to give the actual IP header.
    */
-  buffer = g_malloc(isize);
-  tvb_memcpy(tvb, buffer, 0, isize);
+  buffer = tvb_memdup(tvb, 0, isize);
   buffer[IP_FIELD_PROTOCOL] = IP_PROTO_TCP;
 
   /* Check IP checksum */
@@ -377,13 +374,22 @@ dissect_vjuc(tvbuff_t *tvb, packet_info *pinfo, proto_tree * tree)
     }
   }
 
-  /* 
+  /*
    * Set up tvbuff containing packet with protocol type.
    * Neither header checksum is recalculated.
+   *
+   * Use the length field from the IP header as the reported length;
+   * use the minimum of that and the number of bytes we got from
+   * the tvbuff as the actual length, just in case the tvbuff we were
+   * handed includes part or all of the FCS (because the FCS preference
+   * for the PPP dissector doesn't match the FCS size in this session).
    */
-  next_tvb = tvb_new_real_data(buffer, isize, pntohs(&buffer[IP_FIELD_TOT_LEN]));
+  ipsize = pntohs(&buffer[IP_FIELD_TOT_LEN]);
+  if (ipsize < isize)
+    isize = ipsize;
+  next_tvb = tvb_new_real_data(buffer, isize, ipsize);
   tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-  add_new_data_source(pinfo->fd, next_tvb, "VJ Uncompressed");
+  add_new_data_source(pinfo, next_tvb, "VJ Uncompressed");
 
   /*
    * Call IP dissector.
@@ -488,7 +494,7 @@ proto_register_vj(void)
       { "IP ID delta",                 "vj.ip_id_delta",       FT_UINT16, BASE_DEC,
         NULL, 0x0, "Delta for IP ID", HFILL }},
   };
-  static gint *ett[] = { 
+  static gint *ett[] = {
     &ett_vj,
     &ett_vj_changes,
   };
@@ -516,7 +522,7 @@ proto_reg_handoff_vj(void)
 }
 
 /* Initialization function */
-static void 
+static void
 vj_init(void)
 {
   gint i           = ZERO;
@@ -524,7 +530,7 @@ vj_init(void)
 
   if(vj_header_memchunk != NULL)
     g_mem_chunk_destroy(vj_header_memchunk);
-  vj_header_memchunk = g_mem_chunk_new("vj header store", sizeof (vj_header_t), 
+  vj_header_memchunk = g_mem_chunk_new("vj header store", sizeof (vj_header_t),
                                        sizeof (vj_header_t) * VJ_ATOM_COUNT,
                                        G_ALLOC_ONLY);
   for(i = 0; i < RX_TX_STATE_COUNT; i++) {
@@ -553,12 +559,12 @@ slhc_init(void)
   for (i = 0; i < TCP_SIMUL_CONV_MAX; i++)
     comp->rstate[i].flags |= SLF_TOSS;
   return comp;
-} 
+}
 
 /* Setup the decompressed packet tvb for VJ compressed packets */
-static gint 
-vjc_tvb_setup(tvbuff_t *src_tvb, 
-              tvbuff_t **dst_tvb, 
+static gint
+vjc_tvb_setup(tvbuff_t *src_tvb,
+              tvbuff_t **dst_tvb,
               packet_info *pinfo)
 {
   vj_header_t *hdr_buf;
@@ -596,11 +602,11 @@ vjc_tvb_setup(tvbuff_t *src_tvb,
   pbuf     = g_malloc(buf_len);
   memcpy(pbuf, data_ptr, hdr_len);
   tvb_memcpy(src_tvb, pbuf + hdr_len, offset, buf_len - hdr_len);
-  *dst_tvb = tvb_new_real_data(pbuf, buf_len, ntohs(ip->tot_len));
+  *dst_tvb = tvb_new_real_data(pbuf, buf_len, g_ntohs(ip->tot_len));
   tvb_set_child_real_data_tvbuff(src_tvb, *dst_tvb);
-  add_new_data_source(pinfo->fd, *dst_tvb, "VJ Decompressed");
+  add_new_data_source(pinfo, *dst_tvb, "VJ Decompressed");
   return VJ_OK;
-} 
+}
 
 /*
  * For VJ compressed packet:
@@ -609,7 +615,7 @@ vjc_tvb_setup(tvbuff_t *src_tvb,
  *     dissect the relevant fields;
  *     update the decompressor state on the first pass.
  */
-static gint 
+static gint
 vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
             slcompress *comp)
 {
@@ -701,7 +707,7 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
     offset++;
     if(comp != NULL)
       comp->recv_current = conn_index;
-  } 
+  }
 
   if(!pinfo->fd->flags.visited) {
     /*
@@ -723,7 +729,7 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
     proto_tree_add_uint(tree, hf_vj_tcp_cksum, src_tvb, offset, 2, tcp_cksum);
   if(cs != NULL) {
     hdrlen = lo_nibble(ip->ihl_version) * 4 + TCP_OFFSET(thp) * 4;
-    thp->cksum = htons(tcp_cksum);
+    thp->cksum = g_htons(tcp_cksum);
   }
   offset += 2;
   if(cs != NULL) {
@@ -737,14 +743,14 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
   switch(changes & SPECIALS_MASK){
     case SPECIAL_I:                   /* Echoed terminal traffic */
       if(cs != NULL) {
-        word = ntohs(ip->tot_len) - hdrlen;
-        thp->ack_seq = htonl(ntohl(thp->ack_seq) + word);
-        thp->seq = htonl(ntohl(thp->seq) + word);
+        word = g_ntohs(ip->tot_len) - hdrlen;
+        thp->ack_seq = g_htonl(g_ntohl(thp->ack_seq) + word);
+        thp->seq = g_htonl(g_ntohl(thp->seq) + word);
       }
       break;
     case SPECIAL_D:                   /* Unidirectional data */
       if(cs != NULL)
-        thp->seq = htonl(ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen);
+        thp->seq = g_htonl(g_ntohl(thp->seq) + g_ntohs(ip->tot_len) - hdrlen);
       break;
     default:
       if(changes & NEW_U){
@@ -760,17 +766,17 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
       if(changes & NEW_W) {
         delta = get_signed_delta(src_tvb, &offset, hf_vj_win_delta, tree);
         if(cs != NULL)
-          thp->window = htons(ntohs(thp->window) + delta);
+          thp->window = g_htons(g_ntohs(thp->window) + delta);
       }
       if(changes & NEW_A) {
         delta = get_unsigned_delta(src_tvb, &offset, hf_vj_ack_delta, tree);
         if(cs != NULL)
-          thp->ack_seq = htonl(ntohl(thp->ack_seq) + delta);
+          thp->ack_seq = g_htonl(g_ntohl(thp->ack_seq) + delta);
       }
       if(changes & NEW_S) {
        delta = get_unsigned_delta(src_tvb, &offset, hf_vj_seq_delta, tree);
         if(cs != NULL)
-          thp->seq = htonl(ntohl(thp->seq) + delta);
+          thp->seq = g_htonl(g_ntohl(thp->seq) + delta);
       }
       break;
   }
@@ -779,7 +785,7 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
   else
     delta = 1;
   if(cs != NULL)
-    ip->id = htons(ntohs(ip->id) + delta);
+    ip->id = g_htons(g_ntohs(ip->id) + delta);
 
   /* Compute IP packet length and the buffer length needed */
   len = tvb_reported_length_remaining(src_tvb, offset);
@@ -809,7 +815,7 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
 
   if(cs != NULL) {
     len += hdrlen;
-    ip->tot_len = htons(len);
+    ip->tot_len = g_htons(len);
     /* Compute IP check sum */
     ip->cksum = ZERO;
     ip->cksum = ip_csum((guint8 *)ip, lo_nibble(ip->ihl_version) * 4);
@@ -832,7 +838,7 @@ vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree,
   }
 
   return VJ_OK;
-} 
+}
 
 /*
  * Get an unsigned delta for a field, and put it into the protocol tree if
@@ -883,7 +889,7 @@ get_signed_delta(tvbuff_t *tvb, int *offsetp, int hf, proto_tree *tree)
 }
 
 /* Wrapper for in_cksum function */
-static guint16 
+static guint16
 ip_csum(const guint8 * ptr, guint32 len)
 {
   vec_t cksum_vec[1];