diff options
author | Evan Huus <eapache@gmail.com> | 2013-10-06 19:04:10 +0000 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2013-10-06 19:04:10 +0000 |
commit | 004c706715a9ec392175a5e629afb151dc6cff2a (patch) | |
tree | 44b4fe563cdf043fbd6acd16bdb76f43dfd2ae94 | |
parent | 62c230c7b1117e35b0ab1c739919b526b491c8b2 (diff) |
Remove packet-vj.c as it does not appear to be under a license we can use.
svn path=/trunk/; revision=52413
-rw-r--r-- | epan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-vj.c | 879 |
3 files changed, 0 insertions, 881 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index b7386e13c5..0104cda6da 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1238,7 +1238,6 @@ set(DISSECTOR_SRC dissectors/packet-vcdu.c dissectors/packet-vicp.c dissectors/packet-vines.c - dissectors/packet-vj.c dissectors/packet-vlan.c dissectors/packet-vmlab.c dissectors/packet-vnc.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 1d02ab46b1..1b6e631bf6 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -1172,7 +1172,6 @@ DISSECTOR_SRC = \ packet-vcdu.c \ packet-vicp.c \ packet-vines.c \ - packet-vj.c \ packet-vlan.c \ packet-vmlab.c \ packet-vnc.c \ diff --git a/epan/dissectors/packet-vj.c b/epan/dissectors/packet-vj.c deleted file mode 100644 index 5937c077a4..0000000000 --- a/epan/dissectors/packet-vj.c +++ /dev/null @@ -1,879 +0,0 @@ -/* packet-vj.c - * Routines for Van Jacobson header decompression. (See RFC 1144.) - * - * $Id$ - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * - * 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). - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - * - * - * modified for KA9Q Internet Software Package by - * Katie Stevens (dkstevens@ucdavis.edu) - * University of California, Davis - * Computing Services - * - 01-31-90 initial adaptation (from 1.19) - * PPP.05 02-15-90 [ks] - * PPP.08 05-02-90 [ks] use PPP protocol field to signal compression - * PPP.15 09-90 [ks] improve mbuf handling - * PPP.16 11-02 [karn] substantially rewritten to use NOS facilities - * - * - Feb 1991 Bill_Simpson@um.cc.umich.edu - * variable number of conversation slots - * allow zero or one slots - * separate routines - * status display - * - Jul 1994 Dmitry Gorodchanin - * Fixes for memory leaks. - * - Oct 1994 Dmitry Gorodchanin - * Modularization. - * - Jan 1995 Bjorn Ekwall - * Use ip_fast_csum from ip.h - * - July 1995 Christos A. Polyzols - * Spotted bug in tcp option checking - * - Sep 2001 Irfan Khan - * Rewrite to make the code work for wireshark. - */ - -#include "config.h" - -#include <glib.h> -#include <string.h> -#include <epan/packet.h> -#include <epan/prefs.h> -#include "packet-ppp.h" -#include <epan/ppptypes.h> -#include <epan/ipproto.h> -#include <epan/in_cksum.h> -#include <epan/wmem/wmem.h> - -/* Define relevant IP/TCP parameters */ -#define IP_FIELD_TOT_LEN 2 /* Total length field in IP hdr */ -#define IP_FIELD_PROTOCOL 9 /* Protocol field byte in IP hdr */ -#define IP_ADDR_SIZE 4 /* Size in bytes of IPv4 address */ -#define IP_FIELD_SRC 12 /* Byte 12 in IP hdr - src address */ -#define IP_FIELD_DST 16 /* Byte 16 in IP hdr - dst address */ -#define IP_HDR_LEN 20 /* Minimum IP header length */ -#define IP_HDR_LEN_MASK 0x0f /* Mask for header length field */ -#define IP_MAX_OPT_LEN 44 /* Max length of IP options */ -#define TCP_FIELD_HDR_LEN 12 /* Data offset field in TCP hdr */ -#define TCP_HDR_LEN 20 /* Minimum TCP header length */ -#define TCP_MAX_OPT_LEN 44 /* Max length of TCP options */ -#define TCP_SIMUL_CONV_MAX 256 /* Max number of simul. TCP conversations */ -#define TCP_PUSH_BIT 0x08 /* TCP push bit */ -#define TCP_URG_BIT 0x20 /* TCP urgent bit */ - -/* Bits in first octet of compressed packet */ -/* flag bits for what changed in a packet */ -#define NEW_C 0x40 /* Connection number changed */ -#define NEW_I 0x20 /* IP sequence number change by value != 1 */ -#define CHANGE_PUSH_BIT 0x10 /* TCP push bit set */ -#define NEW_S 0x08 /* Sequence number changed */ -#define NEW_A 0x04 /* Ack sequence number changed */ -#define NEW_W 0x02 /* Window changed */ -#define NEW_U 0x01 /* Urgent pointer present */ - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U)/* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -/* Function return values */ -#define VJ_OK 0 -#define VJ_ERROR -1 - -/* VJ Mem Chunk defines */ -#define VJ_DATA_SIZE 128 /* Max IP hdr(64)+Max TCP hdr(64) */ - -/* IP and TCP header types */ -typedef struct { - guint8 ihl_version; - guint8 tos; - guint16 tot_len; - guint16 id; - guint16 frag_off; - guint8 ttl; - guint8 proto; - guint16 cksum; - guint32 src; - guint32 dst; -} iphdr_type; - -typedef struct { - guint16 srcport; - guint16 dstport; - guint32 seq; - guint32 ack_seq; - guint8 off_x2; - guint8 flags; - guint16 window; - guint16 cksum; - guint16 urg_ptr; -} tcphdr_type; - -#define TCP_OFFSET(th) (((th)->off_x2 & 0xf0) >> 4) - -/* State per active tcp conversation */ -typedef struct cstate { - iphdr_type cs_ip; - tcphdr_type cs_tcp; - guint8 cs_ipopt[IP_MAX_OPT_LEN]; - guint8 cs_tcpopt[TCP_MAX_OPT_LEN]; - guint32 flags; -#define SLF_TOSS 0x00000001 /* tossing rcvd frames until id received */ -} cstate; - -/* All the state data for one serial line */ -typedef struct { - cstate rstate[TCP_SIMUL_CONV_MAX]; /* receive connection states (array) */ - guint8 recv_current; /* most recent rcvd id */ -} slcompress; - -/* Initialize the protocol and registered fields */ -static int proto_vj = -1; - -static int hf_vj_change_mask = -1; -static int hf_vj_change_mask_c = -1; -static int hf_vj_change_mask_i = -1; -static int hf_vj_change_mask_p = -1; -static int hf_vj_change_mask_s = -1; -static int hf_vj_change_mask_a = -1; -static int hf_vj_change_mask_w = -1; -static int hf_vj_change_mask_u = -1; -static int hf_vj_connection_number = -1; -static int hf_vj_tcp_cksum = -1; -static int hf_vj_urp = -1; -static int hf_vj_win_delta = -1; -static int hf_vj_ack_delta = -1; -static int hf_vj_seq_delta = -1; -static int hf_vj_ip_id_delta = -1; - -static gint ett_vj = -1; -static gint ett_vj_changes = -1; - -/* Protocol handles */ -static dissector_handle_t ip_handle; -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 */ -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); -static int get_signed_delta(tvbuff_t *tvb, int *offsetp, int hf, - proto_tree *tree); -static guint16 ip_csum(const guint8 *ptr, guint32 len); -static slcompress *slhc_init(void); -static gint vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree, - slcompress *comp); -static gint vjc_tvb_setup(tvbuff_t *src_tvb, tvbuff_t **dst_tvb, - packet_info *pinfo); - -/* Dissector for VJ Uncompressed packets */ -static void -dissect_vjuc(tvbuff_t *tvb, packet_info *pinfo, proto_tree * tree) -{ - proto_item *ti; - proto_tree *vj_tree = NULL; - slcompress *comp; - int i; - gint conn_index; - cstate *cs = NULL; - guint8 ihl; - guint8 thl; - guint8 *buffer; - tvbuff_t *next_tvb; - gint isize = tvb_length(tvb); - gint ipsize; - - col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP VJ"); - - if(tree != NULL) { - ti = proto_tree_add_protocol_format(tree, proto_vj, tvb, 0, -1, - "PPP VJ Compression: Uncompressed data"); - vj_tree = proto_item_add_subtree(ti, ett_vj); - } - - if(pinfo->p2p_dir == P2P_DIR_UNKNOWN) { - /* Direction of the traffic unknown - can't update state */ - comp = NULL; - } else { - /* Get state for that direction */ - comp = rx_tx_state[pinfo->p2p_dir]; - } - - /* - * Check to make sure we can fetch the connection index. - */ - if(!tvb_bytes_exist(tvb, IP_FIELD_PROTOCOL, 1)) { - /* - * We don't. We can't even mark a connection as non-decompressable, - * as we don't know which connection this is. Mark them all as - * non-decompressable. - */ - col_set_str(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (not enough data available)"); - if(tree != NULL) - call_dissector(data_handle, tvb, pinfo, tree); - if(comp != NULL) { - for(i = 0; i < TCP_SIMUL_CONV_MAX; i++) - comp->rstate[i].flags |= SLF_TOSS; - } - return; - } - - /* Get connection index */ - conn_index = tvb_get_guint8(tvb, IP_FIELD_PROTOCOL); - if(tree != NULL) - proto_tree_add_uint(vj_tree, hf_vj_connection_number, tvb, - IP_FIELD_PROTOCOL, 1, conn_index); - - /* - * Update the current connection, and get a pointer to its state. - */ - if(comp != NULL) { - comp->recv_current = conn_index; - cs = &comp->rstate[conn_index]; - } - - /* Get the IP header length */ - ihl = tvb_get_guint8(tvb, 0) & IP_HDR_LEN_MASK; - ihl <<= 2; - - /* Check IP header length */ - if(ihl < IP_HDR_LEN) { - col_add_fstr(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (IP header length (%u) < %u)", - ihl, IP_HDR_LEN); - if(cs != NULL) - cs->flags |= SLF_TOSS; - return; - } - - /* Make sure we have the full IP header */ - if(isize < ihl) { - col_set_str(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (not enough data available)"); - if(tree != NULL) - call_dissector(data_handle, tvb, pinfo, tree); - if(cs != NULL) - cs->flags |= SLF_TOSS; - return; - } - - col_set_str(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP"); - - /* - * 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 = (guint8 *)wmem_alloc(pinfo->pool, isize); - tvb_memcpy(tvb, buffer, 0, isize); - buffer[IP_FIELD_PROTOCOL] = IP_PROTO_TCP; - - /* Check IP checksum */ - if(ip_csum(buffer, ihl) != 0) { - /* - * Checksum invalid - don't update state, and don't decompress - * any subsequent compressed packets in this direction. - */ - if(cs != NULL) - cs->flags |= SLF_TOSS; - cs = NULL; /* disable state updates */ - } else { - /* Do we have the TCP header length in the tvbuff? */ - if(!tvb_bytes_exist(tvb, ihl + TCP_FIELD_HDR_LEN, 1)) { - /* We don't, so we can't provide enough data for decompression */ - col_set_str(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (not enough data available)"); - if(cs != NULL) - cs->flags |= SLF_TOSS; - cs = NULL; /* disable state updates */ - } else { - /* Get the TCP header length */ - thl = tvb_get_guint8(tvb, ihl + TCP_FIELD_HDR_LEN); - thl = ((thl & 0xf0) >> 4) * 4; - - /* Check TCP header length */ - if(thl < TCP_HDR_LEN) { - col_add_fstr(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (TCP header length (%u) < %u)", - thl, TCP_HDR_LEN); - if(cs != NULL) - cs->flags |= SLF_TOSS; - cs = NULL; /* disable state updates */ - } else { - /* Make sure we have the full TCP header */ - if(isize < thl) { - col_set_str(pinfo->cinfo, COL_INFO, "VJ uncompressed TCP (not enough data available)"); - if(cs != NULL) - cs->flags |= SLF_TOSS; - cs = NULL; /* disable state updates */ - } - } - } - } - - /* - * If packet seen for first time, update state if we have state and can - * update it. - */ - if(!pinfo->fd->flags.visited) { - if(cs != NULL) { - cs->flags &= ~SLF_TOSS; - memcpy(&cs->cs_ip, &buffer[0], IP_HDR_LEN); - memcpy(&cs->cs_tcp, &buffer[ihl], TCP_HDR_LEN); - if(ihl > IP_HDR_LEN) - memcpy(cs->cs_ipopt, &buffer[sizeof(iphdr_type)], ihl - IP_HDR_LEN); - if(TCP_OFFSET(&(cs->cs_tcp)) > 5) - memcpy(cs->cs_tcpopt, &buffer[ihl + sizeof(tcphdr_type)], - (TCP_OFFSET(&(cs->cs_tcp)) - 5) * 4); - } - } - - /* - * 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). - */ - ipsize = pntohs(&buffer[IP_FIELD_TOT_LEN]); - if (ipsize < isize) - isize = ipsize; - next_tvb = tvb_new_child_real_data(tvb, buffer, isize, ipsize); - add_new_data_source(pinfo, next_tvb, "VJ Uncompressed"); - - /* - * Call IP dissector. - */ - call_dissector(ip_handle, next_tvb, pinfo, tree); -} - -/* Dissector for VJ Compressed packets */ -static void -dissect_vjc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) -{ - proto_item *ti; - proto_tree *vj_tree = NULL; - tvbuff_t *next_tvb = NULL; - slcompress *comp = NULL; - gint err = VJ_ERROR; - - col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP VJ"); - - if(tree != NULL) { - ti = proto_tree_add_protocol_format(tree, proto_vj, tvb, 0, -1, - "PPP VJ Compression: Compressed data"); - vj_tree = proto_item_add_subtree(ti, ett_vj); - } - - if(!ppp_vj_decomp || pinfo->p2p_dir == P2P_DIR_UNKNOWN) { - /* - * VJ decompression turned off, so we shouldn't decompress, or - * direction of the traffic unknown, so we can't decompress. - */ - comp = NULL; - } else { - /* Get state for that direction */ - comp = rx_tx_state[pinfo->p2p_dir]; - } - - /* Process the compressed data header */ - if(vjc_process(tvb, pinfo, vj_tree, comp) == VJ_ERROR) - return; - - /* Decompression possible - set up tvb containing decompressed packet */ - err = vjc_tvb_setup(tvb, &next_tvb, pinfo); - if(err == VJ_ERROR) { - if(tree != NULL) - call_dissector(data_handle, tvb, pinfo, vj_tree); - return; - } - - /* No errors, so call IP dissector */ - call_dissector(ip_handle, next_tvb, pinfo, tree); -} - -/* Initialization function */ -static void -vj_init(void) -{ - gint i = 0; - - for(i = 0; i < RX_TX_STATE_COUNT; i++) { - rx_tx_state[i] = slhc_init(); - } - return; -} - -/* Initialization routine for VJ decompression */ -static slcompress * -slhc_init(void) -{ - slcompress *comp = wmem_new0(wmem_file_scope(), slcompress); - int i; - - /* - * Initialize the state; there is no current connection, and - * we have no header data for any of the connections, as we - * haven't yet seen an uncompressed frame. - */ - comp->recv_current = TCP_SIMUL_CONV_MAX - 1; - 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, - packet_info *pinfo) -{ - vj_header_t *hdr_buf; - guint8 offset; - guint8 *data_ptr; - gint hdr_len; - gint tot_len; - gint buf_len; - guint8 *pbuf; - - DISSECTOR_ASSERT(src_tvb); - - /* Get decompressed header stored in fd protocol area */ - hdr_buf = (vj_header_t *)p_get_proto_data(pinfo->fd, proto_vj, 0); - if(hdr_buf == NULL) { - col_set_str(pinfo->cinfo, COL_INFO, "VJ compressed TCP (previous data bad or missing)"); - return VJ_ERROR; - } - - col_set_str(pinfo->cinfo, COL_INFO, "VJ compressed TCP"); - - /* Get the data offset in the tvbuff */ - offset = hdr_buf->offset; - - /* Copy header and form tvb */ - data_ptr = hdr_buf->data; - hdr_len = lo_nibble(data_ptr[0]) * 4; - hdr_len += hi_nibble(data_ptr[hdr_len + 12]) * 4; - buf_len = tvb_length(src_tvb) + hdr_len - offset; - pbuf = (guint8 *)wmem_alloc(pinfo->pool, buf_len); - memcpy(pbuf, data_ptr, hdr_len); - tvb_memcpy(src_tvb, pbuf + hdr_len, offset, buf_len - hdr_len); - memcpy(&tot_len, data_ptr + 2, 2); - *dst_tvb = tvb_new_child_real_data(src_tvb, pbuf, buf_len, g_ntohs(tot_len)); - add_new_data_source(pinfo, *dst_tvb, "VJ Decompressed"); - return VJ_OK; -} - -/* - * For VJ compressed packet: - * - * check if it is malformed; - * dissect the relevant fields; - * update the decompressor state on the first pass. - */ -static gint -vjc_process(tvbuff_t *src_tvb, packet_info *pinfo, proto_tree *tree, - slcompress *comp) -{ - int offset = 0; - int i; - gint changes; - proto_item *ti; - proto_tree *changes_tree; - guint8 conn_index; - cstate *cs = NULL; - iphdr_type *ip = NULL; - tcphdr_type *thp = NULL; - guint16 tcp_cksum; - gint hdrlen = 0; - guint16 word; - int delta; - gint len; - vj_header_t *buf_hdr; - guint8 *data_ptr; - - if(tvb_length(src_tvb) < 3){ - /* - * We don't even have enough data for the change byte, so we can't - * determine which connection this is; mark all connections as - * non-decompressible. - */ - col_set_str(pinfo->cinfo, COL_INFO, "VJ compressed TCP (not enough data available)"); - if(tree != NULL) - call_dissector(data_handle, src_tvb, pinfo, tree); - if(comp != NULL) { - for(i = 0; i < TCP_SIMUL_CONV_MAX; i++) - comp->rstate[i].flags |= SLF_TOSS; - } - return VJ_ERROR; - } - - /* Read the change byte */ - changes = tvb_get_guint8(src_tvb, offset); - if(tree != NULL) { - switch (changes & SPECIALS_MASK) { - - case SPECIAL_I: - ti = proto_tree_add_uint_format_value(tree, hf_vj_change_mask, src_tvb, - offset, 1, changes, - "0x%02x (echoed interactive traffic)", - changes); - break; - - case SPECIAL_D: - ti = proto_tree_add_uint_format_value(tree, hf_vj_change_mask, src_tvb, - offset, 1, changes, - "0x%02x (unidirectional data)", - changes); - break; - - default: - /* - * XXX - summarize bits? - */ - ti = proto_tree_add_uint_format_value(tree, hf_vj_change_mask, src_tvb, - offset, 1, changes, - "0x%02x", changes); - break; - } - changes_tree = proto_item_add_subtree(ti, ett_vj_changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_c, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_i, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_p, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_s, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_a, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_w, src_tvb, - offset, 1, changes); - proto_tree_add_boolean(changes_tree, hf_vj_change_mask_u, src_tvb, - offset, 1, changes); - } - offset++; - - if(changes & NEW_C){ /* Read conn index */ - conn_index = tvb_get_guint8(src_tvb, offset); - if(tree != NULL) - proto_tree_add_uint(tree, hf_vj_connection_number, src_tvb, offset, 1, - conn_index); - offset++; - if(comp != NULL) - comp->recv_current = conn_index; - } - - if(!pinfo->fd->flags.visited) { - /* - * This is the first time this frame has been seen, so we need - * state information to decompress it. If that information isn't - * available, don't use the state information, and don't update it, - * either. - */ - if(comp != NULL && !(comp->rstate[comp->recv_current].flags & SLF_TOSS)) { - cs = &comp->rstate[comp->recv_current]; - thp = &cs->cs_tcp; - ip = &cs->cs_ip; - } - } - - /* Build TCP and IP headers */ - tcp_cksum = tvb_get_ntohs(src_tvb, offset); - if(tree != NULL) - 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 = g_htons(tcp_cksum); - } - offset += 2; - if(cs != NULL) { - if(changes & CHANGE_PUSH_BIT) - thp->flags |= TCP_PUSH_BIT; - else - thp->flags &= ~TCP_PUSH_BIT; - } - - /* Deal with special cases and normal deltas */ - switch(changes & SPECIALS_MASK){ - guint32 tmp; - case SPECIAL_I: /* Echoed terminal traffic */ - if(cs != NULL) { - word = g_ntohs(ip->tot_len) - hdrlen; - tmp = g_ntohl(thp->ack_seq) + word; - thp->ack_seq = g_htonl(tmp); - tmp = g_ntohl(thp->seq) + word; - thp->seq = g_htonl(tmp); - } - break; - case SPECIAL_D: /* Unidirectional data */ - if(cs != NULL) { - tmp = g_ntohl(thp->seq) + g_ntohs(ip->tot_len) - hdrlen; - thp->seq = g_htonl(tmp); - } - break; - default: - if(changes & NEW_U){ - delta = get_unsigned_delta(src_tvb, &offset, hf_vj_urp, tree); - if(cs != NULL) { - thp->urg_ptr = delta; - thp->flags |= TCP_URG_BIT; - } - } else { - if(cs != NULL) - thp->flags &= ~TCP_URG_BIT; - } - if(changes & NEW_W) { - delta = get_signed_delta(src_tvb, &offset, hf_vj_win_delta, tree); - if(cs != NULL) { - tmp = g_ntohs(thp->window) + delta; - thp->window = g_htons(tmp); - } - } - if(changes & NEW_A) { - delta = get_unsigned_delta(src_tvb, &offset, hf_vj_ack_delta, tree); - if(cs != NULL) { - tmp = g_ntohl(thp->ack_seq) + delta; - thp->ack_seq = g_htonl(tmp); - } - } - if(changes & NEW_S) { - delta = get_unsigned_delta(src_tvb, &offset, hf_vj_seq_delta, tree); - if(cs != NULL) { - tmp = g_ntohl(thp->seq) + delta; - thp->seq = g_htonl(tmp); - } - } - break; - } - if(changes & NEW_I) - delta = get_unsigned_delta(src_tvb, &offset, hf_vj_ip_id_delta, tree); - else - delta = 1; - if(cs != NULL) { - guint32 tmp; - tmp = g_ntohs(ip->id) + delta; - ip->id = g_htons(tmp); - } - - /* Compute IP packet length and the buffer length needed */ - len = tvb_reported_length_remaining(src_tvb, offset); - if(len < 0) { - /* - * This shouldn't happen, as we *were* able to fetch stuff right before - * offset. - */ - col_set_str(pinfo->cinfo, COL_INFO, "VJ compressed TCP (not enough data available)"); - if(cs != NULL) - cs->flags |= SLF_TOSS; - return VJ_ERROR; - } - - /* Show the TCP payload */ - if(tree != NULL && tvb_offset_exists(src_tvb, offset)) - proto_tree_add_text(tree, src_tvb, offset, -1, "TCP payload"); - - /* Nothing more to do if we don't have any compression state */ - if(comp == NULL) { - /* Direction of the traffic unknown - can't decompress */ - col_set_str(pinfo->cinfo, COL_INFO, "VJ compressed TCP (direction unknown)"); - return VJ_ERROR; - } - - if((cs != NULL) && (!pinfo->fd->flags.visited)) { - len += hdrlen; - ip->tot_len = g_htons(len); - /* Compute IP check sum */ - ip->cksum = 0; - ip->cksum = ip_csum((guint8 *)ip, lo_nibble(ip->ihl_version) * 4); - - /* Store the reconstructed header in frame data area */ - buf_hdr = wmem_new(wmem_file_scope(), vj_header_t); - buf_hdr->offset = offset; /* Offset in tvbuff is also stored */ - data_ptr = buf_hdr->data; - memcpy(data_ptr, ip, IP_HDR_LEN); - data_ptr += IP_HDR_LEN; - if(lo_nibble(ip->ihl_version) > 5) { - memcpy(data_ptr, cs->cs_ipopt, (lo_nibble(ip->ihl_version) - 5) * 4); - data_ptr += (lo_nibble(ip->ihl_version) - 5) * 4; - } - memcpy(data_ptr, thp, TCP_HDR_LEN); - data_ptr += TCP_HDR_LEN; - if(TCP_OFFSET(thp) > 5) - memcpy(data_ptr, cs->cs_tcpopt, (TCP_OFFSET(thp) - 5) * 4); - p_add_proto_data(pinfo->fd, proto_vj, 0, buf_hdr); - } - - return VJ_OK; -} - -/* - * Get an unsigned delta for a field, and put it into the protocol tree if - * we're building a protocol tree. - */ -static int -get_unsigned_delta(tvbuff_t *tvb, int *offsetp, int hf, proto_tree *tree) -{ - int offset = *offsetp; - int len; - guint16 del; - - len = 1; - del = tvb_get_guint8(tvb, offset++); - if(del == 0){ - del = tvb_get_ntohs(tvb, offset); - offset += 2; - len += 2; - } - if(tree != NULL) - proto_tree_add_uint(tree, hf, tvb, *offsetp, len, del); - *offsetp = offset; - return del; -} - -/* - * Get a signed delta for a field, and put it into the protocol tree if - * we're building a protocol tree. - */ -static int -get_signed_delta(tvbuff_t *tvb, int *offsetp, int hf, proto_tree *tree) -{ - int offset = *offsetp; - int len; - gint16 del; - - len = 1; - del = tvb_get_guint8(tvb, offset++); - if(del == 0){ - del = tvb_get_ntohs(tvb, offset); - offset += 2; - len += 2; - } - if(tree != NULL) - proto_tree_add_int(tree, hf, tvb, *offsetp, len, del); - *offsetp = offset; - return del; -} - -/* Wrapper for in_cksum function */ -static guint16 -ip_csum(const guint8 * ptr, guint32 len) -{ - vec_t cksum_vec[1]; - - cksum_vec[0].ptr = ptr; - cksum_vec[0].len = len; - return in_cksum(&cksum_vec[0], 1); -} - -/* Registration functions for dissectors */ -void -proto_register_vj(void) -{ - static hf_register_info hf[] = { - { &hf_vj_change_mask, - { "Change mask", "vj.change_mask", FT_UINT8, BASE_HEX, - NULL, 0x0, NULL, HFILL }}, - { &hf_vj_change_mask_c, - { "Connection changed", "vj.change_mask_c", FT_BOOLEAN, 8, - NULL, NEW_C, "Connection number changed", HFILL }}, - { &hf_vj_change_mask_i, - { "IP ID change != 1", "vj.change_mask_i", FT_BOOLEAN, 8, - NULL, NEW_I, "IP ID changed by a value other than 1", HFILL }}, - { &hf_vj_change_mask_p, - { "Push bit set", "vj.change_mask_p", FT_BOOLEAN, 8, - NULL, CHANGE_PUSH_BIT, "TCP PSH flag set", HFILL }}, - { &hf_vj_change_mask_s, - { "Sequence number changed", "vj.change_mask_s", FT_BOOLEAN, 8, - NULL, NEW_S, NULL, HFILL }}, - { &hf_vj_change_mask_a, - { "Ack number changed", "vj.change_mask_a", FT_BOOLEAN, 8, - NULL, NEW_A, "Acknowledgement sequence number changed", HFILL }}, - { &hf_vj_change_mask_w, - { "Window changed", "vj.change_mask_w", FT_BOOLEAN, 8, - NULL, NEW_W, "TCP window changed", HFILL }}, - { &hf_vj_change_mask_u, - { "Urgent pointer set", "vj.change_mask_u", FT_BOOLEAN, 8, - NULL, NEW_U, NULL, HFILL }}, - { &hf_vj_connection_number, - { "Connection number", "vj.connection_number", FT_UINT8, BASE_DEC, - NULL, 0x0, NULL, HFILL }}, - { &hf_vj_tcp_cksum, - { "TCP checksum", "vj.tcp_cksum", FT_UINT16, BASE_HEX, - NULL, 0x0, NULL, HFILL }}, - { &hf_vj_urp, - { "Urgent pointer", "vj.urp", FT_UINT16, BASE_DEC, - NULL, 0x0, NULL, HFILL }}, - { &hf_vj_win_delta, - { "Window delta", "vj.win_delta", FT_INT16, BASE_DEC, - NULL, 0x0, "Delta for window", HFILL }}, - { &hf_vj_ack_delta, - { "Ack delta", "vj.ack_delta", FT_UINT16, BASE_DEC, - NULL, 0x0, "Delta for acknowledgment sequence number", HFILL }}, - { &hf_vj_seq_delta, - { "Sequence delta", "vj.seq_delta", FT_UINT16, BASE_DEC, - NULL, 0x0, "Delta for sequence number", HFILL }}, - { &hf_vj_ip_id_delta, - { "IP ID delta", "vj.ip_id_delta", FT_UINT16, BASE_DEC, - NULL, 0x0, "Delta for IP ID", HFILL }}, - }; - static gint *ett[] = { - &ett_vj, - &ett_vj_changes, - }; - - proto_vj = proto_register_protocol("PPP VJ Compression", "PPP VJ", "vj"); - proto_register_field_array(proto_vj, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); - register_init_routine(&vj_init); -} - -void -proto_reg_handoff_vj(void) -{ - dissector_handle_t vjc_handle; - dissector_handle_t vjuc_handle; - - vjc_handle = create_dissector_handle(dissect_vjc, proto_vj); - dissector_add_uint("ppp.protocol", PPP_VJC_COMP, vjc_handle); - - vjuc_handle = create_dissector_handle(dissect_vjuc, proto_vj); - dissector_add_uint("ppp.protocol", PPP_VJC_UNCOMP, vjuc_handle); - - ip_handle = find_dissector("ip"); - data_handle = find_dissector("data"); -} - |