Ethereal-dev: [Ethereal-dev] Van Jacobson dissector.
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Irfan Khan <ikhan@xxxxxxxxxxxx>
Date: Tue, 18 Dec 2001 14:01:48 -0700
Hello,Attached is the Van Jacobson dissector for ppp packets. The dissector consists of four patches
and one dissector file.* Moved ppp option ppp_fcs_decode to the ppp header file to allow the vj dissector to access it.
* Added a new option ppp_vj_decomp to turn on or off VJ decompression.* Added function tvb_orig to tvbuff.c to allow reading of bytes preceding the VJ header in the
ppp tvbuff.* The file packet-vj.c contains the VJ dissector. Most of the stuff is taken from
Van Jacobson's implementation hence the BSD license.I compiled, tested and ran this with the nightly build 12/17. Can this be checked in please.
happy holidays everyone, Irfan
Attachment:
tvbuff_h.patch
Description: Binary data
Attachment:
packet-ppp_h.patch
Description: Binary data
/* packet-vj.c * Routines for Van Jacobson header decompression. * * $Id: packet-vj.c,v 1.68 2001/06/18 02:17:50 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxxxx> * * This file created by Irfan Khan <ikhan@xxxxxxxxxxxx> * 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@xxxxxxxxxxxxxxxxx), Dec 31, 1989: * - Initial distribution. * * * modified for KA9Q Internet Software Package by * Katie Stevens (dkstevens@xxxxxxxxxxx) * 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@xxxxxxxxxxxxxxx * 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 ethereal. */ #define VJ_TVBUFF_ACCESS 0 #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #include <glib.h> #include <string.h> #include "packet.h" #include "packet-ppp.h" #include "ppptypes.h" #include "in_cksum.h" #include "epan/tvbuff.h" /* Define relevant IP/TCP parameters */ #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_ADDR_SIZE 4 /* Size in bytes of IPv4 address */ #define IP_FIELD_PROTOCOL 9 /* Protocol field byte in IP hdr */ #define IP_PROTOCOL_TCP 0x06 /* Protocol field value for TCP */ #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_HDR_LEN 20 /* Minimum TCP header length */ #define TCP_PUSH_BIT 0x10 /* TCP push bit */ #define TCP_MAX_OPT_LEN 44 /* Max length of TCP options */ #define TCP_SIMUL_CONV 256 /* Number of simul. TCP conversations */ #define TCP_SIMUL_CONV_MAX 256 /* Max number of simul. TCP conversations */ /* Bits in first octet of compressed packet */ /* flag bits for what changed in a packet */ #define NEW_C 0x40 #define NEW_I 0x20 #define NEW_S 0x08 #define NEW_A 0x04 #define NEW_W 0x02 #define NEW_U 0x01 /* 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 /* Define for 0 */ #define ZERO 0 /* Two byte CRC */ #define CRC_LEN sizeof(guint16) /* VJ Mem Chunk defines */ #define VJ_ATOM_SIZE 129 /* Max IP hdr(64)+Max TCP hdr(64)+offset byte */ #define VJ_ATOM_COUNT 250 /* Number of Atoms per block */ /* IP and TCP header types */ typedef struct { #if BYTE_ORDER == LITTLE_ENDIAN guint8 ihl:4, version:4; #else guint8 version:4, ihl:4; #endif 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; #if BYTE_ORDER == LITTLE_ENDIAN guint16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #else guint16 doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #endif guint16 window; guint16 cksum; guint16 urg_ptr; } tcphdr_type; /* State per active tcp conversation */ typedef struct cstate { struct cstate *next; /* next in ring (xmit) */ iphdr_type cs_ip; tcphdr_type cs_tcp; guint8 cs_ipopt[IP_MAX_OPT_LEN]; guint8 cs_tcpopt[TCP_MAX_OPT_LEN]; } cstate; /* All the state data for one serial line */ typedef struct { cstate *rstate; /* receive connection states (array)*/ guint8 rslot_limit; /* highest receive slot id */ guint8 recv_current; /* most recent rcvd id */ guint8 flags; #define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ } slcompress; /* Initialize the protocol and registered fields */ static int proto_vj = -1; /* Protocol handles */ static dissector_handle_t vjc_handle; static dissector_handle_t vjuc_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 */ static GMemChunk *vj_header_memchunk = NULL; /* Function prototypes */ static void decodes(tvbuff_t *tvb, guint32 *offset, gint16 *val); static void decodel(tvbuff_t *tvb, guint32 *offset, gint32 *val); static guint16 ip_csum(const guint8 *ptr, guint32 len); static slcompress *slhc_init(gint rslots); static void vj_init(void); static void vj_display_pkt(tvbuff_t *parent_tvb, tvbuff_t *child_tvb, tvbuff_t *sub_tvb, packet_info *pinfo, proto_tree *tree); static gint vjuc_check(tvbuff_t *tvb, slcompress *comp); static void vjuc_update_state(tvbuff_t *tvb, slcompress *comp, guint8 index); static gint vjuc_tvb_setup(tvbuff_t *tvb, tvbuff_t **dst_tvb, tvbuff_t **sub_tvb, slcompress *comp); static gint vjc_check(tvbuff_t *src_tvb, slcompress *comp); static gint vjc_update_state(tvbuff_t *src_tvb, slcompress *comp, frame_data *fd); static gint vjc_tvb_setup(tvbuff_t *src_tvb, tvbuff_t **dst_tvb, tvbuff_t **sub_tvb, frame_data *fd); /* Dissector for VJ Uncompressed packets */ static void dissect_vjuc(tvbuff_t *tvb, packet_info *pinfo, proto_tree * tree) { tvbuff_t *next_tvb = NULL; tvbuff_t *sub_tvb = NULL; tvbuff_t *data_tvb = NULL; slcompress *comp = NULL; gint conn_index = ZERO; gint err = VJ_OK; /* Return if VJ is off or direction is not known */ if(ppp_vj_decomp == FALSE || pinfo->p2p_dir == P2P_DIR_UNKNOWN) err = VJ_ERROR; if((comp = rx_tx_state[pinfo->p2p_dir]) == NULL) err = VJ_ERROR; /* Check if packet malformed. */ if(err == VJ_OK) err = conn_index = vjuc_check(tvb, comp); /* Set up tvb containing decompressed packet */ if(err != VJ_ERROR) err = vjuc_tvb_setup(tvb, &next_tvb, &sub_tvb, comp); /* If packet seen for first time update state */ if(pinfo->fd->flags.visited != 1 && err == VJ_OK) vjuc_update_state(sub_tvb, comp, conn_index); /* If no errors call IP dissector else dissect as data. */ if(err == VJ_OK) vj_display_pkt(tvb, next_tvb, sub_tvb, pinfo, tree); else { data_tvb = tvb_new_subset(tvb, 0, -1, -1); call_dissector(data_handle, data_tvb, pinfo, tree); } } /* Dissector for VJ Compressed packets */ static void dissect_vjc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb = NULL; tvbuff_t *sub_tvb = NULL; tvbuff_t *data_tvb = NULL; slcompress *comp = NULL; gint err = VJ_OK; /* Return if VJ is off or direction is not known */ if(ppp_vj_decomp == FALSE || pinfo->p2p_dir == P2P_DIR_UNKNOWN) err = VJ_ERROR; if((comp = rx_tx_state[pinfo->p2p_dir]) == NULL) err = VJ_ERROR; /* Check if packet malformed. */ if(err != VJ_ERROR) err = vjc_check(tvb, comp); /* If packet seen for first time update state */ if(pinfo->fd->flags.visited != 1 && err == VJ_OK) { err = vjc_update_state(tvb, comp, pinfo->fd); } /* Set up tvb containing decompressed packet */ if(err == VJ_OK) err = vjc_tvb_setup(tvb, &next_tvb, &sub_tvb, pinfo->fd); /* If no errors call IP dissector else dissect as data */ if(err == VJ_OK) vj_display_pkt(tvb, next_tvb, sub_tvb, pinfo, tree); else { data_tvb = tvb_new_subset(tvb, 0, -1, -1); call_dissector(data_handle, data_tvb, pinfo, tree); } } /* Registeration functions for dissectors */ void proto_register_vj(void) { proto_vj = proto_register_protocol("PPP VJ Compression", "PPP VJ", "vj"); register_init_routine(&vj_init); vjc_handle = create_dissector_handle(dissect_vjc, proto_vj); vjuc_handle = create_dissector_handle(dissect_vjuc, proto_vj); } void proto_reg_handoff_vj(void) { dissector_add("ppp.protocol", PPP_VJC_COMP, vjc_handle); dissector_add("ppp.protocol", PPP_VJC_UNCOMP, vjuc_handle); data_handle = find_dissector("data"); } /* Function to setup decompressed packet display */ static void vj_display_pkt(tvbuff_t *parent_tvb, tvbuff_t *child_tvb, tvbuff_t *sub_tvb, packet_info *pinfo, proto_tree *tree) { dissector_handle_t ip_handle = find_dissector("ip"); frame_data *fd = pinfo->fd; tvbuff_t *data_tvb = NULL; g_assert(parent_tvb); g_assert(child_tvb); g_assert(fd); if (ip_handle == NULL) { data_tvb = tvb_new_subset(sub_tvb, 0, -1, -1); call_dissector(data_handle, data_tvb, pinfo, tree); } else { tvb_set_child_real_data_tvbuff(parent_tvb, child_tvb); fd->data_src = g_slist_append(fd->data_src, child_tvb); SET_ADDRESS(&pinfo->net_src, AT_IPv4, IP_ADDR_SIZE, tvb_get_ptr(sub_tvb, IP_FIELD_SRC, IP_ADDR_SIZE)); SET_ADDRESS(&pinfo->src, AT_IPv4, IP_ADDR_SIZE, tvb_get_ptr(sub_tvb, IP_FIELD_SRC, IP_ADDR_SIZE)); SET_ADDRESS(&pinfo->net_dst, AT_IPv4, IP_ADDR_SIZE, tvb_get_ptr(sub_tvb, IP_FIELD_DST, IP_ADDR_SIZE)); SET_ADDRESS(&pinfo->dst, AT_IPv4, IP_ADDR_SIZE, tvb_get_ptr(sub_tvb, IP_FIELD_DST, IP_ADDR_SIZE)); call_dissector(ip_handle, sub_tvb, pinfo, tree); } return; } /* Initialization function */ static void vj_init(void) { gint i = ZERO; slcompress *pslc = NULL; cstate *pstate = NULL; if(vj_header_memchunk != NULL) g_mem_chunk_destroy(vj_header_memchunk); vj_header_memchunk = g_mem_chunk_new("vj header store", VJ_ATOM_SIZE, VJ_ATOM_SIZE * VJ_ATOM_COUNT, G_ALLOC_AND_FREE); for(i=0; i< RX_TX_STATE_COUNT; i++){ if((pslc = rx_tx_state[i]) != NULL){ if((pstate = pslc->rstate) != NULL) g_free(pstate); g_free(pslc); } rx_tx_state[i] = slhc_init(TCP_SIMUL_CONV); } return; } /* Initialization routine for VJ decompression */ static slcompress * slhc_init(gint rslots) { size_t rsize = rslots * sizeof(cstate); slcompress *comp = g_malloc(sizeof(slcompress)); if(rslots < ZERO || rslots > TCP_SIMUL_CONV_MAX) return NULL; if (comp != NULL) { memset(comp, ZERO, sizeof(slcompress)); if ((comp->rstate = g_malloc(rsize)) == NULL) { g_free(comp); comp = NULL; } else { memset(comp->rstate, ZERO, rsize); comp->rslot_limit = rslots - 1; comp->recv_current = TCP_SIMUL_CONV_MAX - 1; comp->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, tvbuff_t **sub_tvb, frame_data * fd) { tvbuff_t *orig_tvb = NULL; guint8 *hdr_buf = NULL; guint8 *pbuf = NULL; gint hdr_len = ZERO; gint buf_len = ZERO; gint orig_offset = ZERO; guint8 offset = ZERO; g_assert(src_tvb); /* Get decompressed header stored in fd protocol area */ hdr_buf = p_get_proto_data(fd, proto_vj); if(hdr_buf == NULL) return VJ_ERROR; /* First byte contains data offset in the tvbuff */ offset = *hdr_buf++; /* Copy header and form tvb */ hdr_len = ((iphdr_type *)hdr_buf)->ihl * 4; hdr_len += ((tcphdr_type *)(hdr_buf + hdr_len))->doff * 4; buf_len = tvb_length(src_tvb) + hdr_len - offset; orig_tvb = tvb_orig(src_tvb, &orig_offset); pbuf = g_malloc(buf_len + orig_offset); tvb_memcpy(orig_tvb, pbuf, 0, orig_offset); memcpy(pbuf + orig_offset, hdr_buf, hdr_len); tvb_memcpy(src_tvb, pbuf + hdr_len + orig_offset,offset, buf_len - hdr_len); *dst_tvb = tvb_new_real_data(pbuf, buf_len + orig_offset, buf_len + orig_offset, "VJ Decompressed"); if(orig_offset > 0) *sub_tvb = tvb_new_subset(*dst_tvb, orig_offset, -1, -1); else *sub_tvb = *dst_tvb; return VJ_OK; } /* For VJ compressed packets update the decompressor state */ static gint vjc_update_state(tvbuff_t *src_tvb, slcompress *comp, frame_data *fd) { guint8 *buf_hdr = NULL; cstate *cs = &comp->rstate[comp->recv_current]; tcphdr_type *thp = &cs->cs_tcp; iphdr_type *ip = &cs->cs_ip; gint changes = ZERO; gint len = ZERO; gint hdrlen = ZERO; guint32 offset = ZERO; guint16 word = ZERO; g_assert(src_tvb); g_assert(comp); g_assert(fd); /* Read the change byte */ changes = tvb_get_guint8(src_tvb, offset++); if(changes & NEW_C) offset++; /* Build TCP and IP headers */ hdrlen = ip->ihl * 4 + thp->doff * 4; thp->cksum = htons((tvb_get_guint8(src_tvb, offset++) << 8) | tvb_get_guint8(src_tvb, offset++)); thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0; /* Deal with special cases and normal deltas */ switch(changes & SPECIALS_MASK){ case SPECIAL_I: /* Echoed terminal traffic */ word = ntohs(ip->tot_len) - hdrlen; thp->ack_seq = htonl( ntohl(thp->ack_seq) + word); thp->seq = htonl( ntohl(thp->seq) + word); break; case SPECIAL_D: /* Unidirectional data */ thp->seq = htonl( ntohl(thp->seq) + ntohs(ip->tot_len) - hdrlen); break; default: if(changes & NEW_U){ thp->urg_ptr = ZERO; decodes(src_tvb, &offset, &thp->urg_ptr); thp->urg = 1; } else thp->urg = 0; if(changes & NEW_W) decodes(src_tvb, &offset, &thp->window); if(changes & NEW_A) decodel(src_tvb, &offset, &thp->ack_seq); if(changes & NEW_S) decodel(src_tvb, &offset, &thp->seq); break; } if(changes & NEW_I) decodes(src_tvb, &offset, &ip->id); else ip->id = htons (ntohs (ip->id) + 1); /* Compute ip packet length and the buffer length needed */ if((len = tvb_length(src_tvb) - offset - CRC_LEN) < ZERO) { comp->flags |= SLF_TOSS; return VJ_ERROR; } len += hdrlen; ip->tot_len = htons(len); ip->cksum = ZERO; /* Store the reconstructed header in frame data area */ buf_hdr = g_mem_chunk_alloc(vj_header_memchunk); buf_hdr[0] = offset; /* Offset in tvbuff is also stored */ memcpy((buf_hdr + sizeof(guint8)), ip, IP_HDR_LEN); /* Compute IP check sum */ ((iphdr_type *)(buf_hdr + sizeof(guint8)))->cksum = ip_csum((buf_hdr + sizeof(guint8)), ip->ihl * 4); if(ip->ihl > 5) memcpy((buf_hdr + sizeof(guint8) + IP_HDR_LEN), cs->cs_ipopt, (ip->ihl - 5) * 4); memcpy((buf_hdr + sizeof(guint8) + (ip->ihl * 4)), thp, TCP_HDR_LEN); if(thp->doff > 5) memcpy((buf_hdr + sizeof(guint8) + (ip->ihl *4) + TCP_HDR_LEN), cs->cs_tcpopt, (thp->doff - 5) * 4); p_add_proto_data(fd, proto_vj, buf_hdr); return VJ_OK; } /* For VJ compressed packet check if it is malformed */ static gint vjc_check(tvbuff_t *src_tvb, slcompress *comp) { guint8 conn_index = ZERO; guint8 offset = ZERO; gint changes = ZERO; g_assert(src_tvb); g_assert(comp); if(tvb_length(src_tvb) < 3){ comp->flags |= SLF_TOSS; return VJ_ERROR; } /* Read the change byte */ changes = tvb_get_guint8(src_tvb, offset++); if(changes & NEW_C){ /* Read conn index */ conn_index = tvb_get_guint8(src_tvb, offset++); if(conn_index > comp->rslot_limit) { comp->flags |= SLF_TOSS; return VJ_ERROR; } comp->flags &= ~SLF_TOSS; comp->recv_current = conn_index; } else { if(comp->flags & SLF_TOSS) return VJ_ERROR; } return VJ_OK; } /* Decode the delta of a 32 bit header field */ static void decodel(tvbuff_t *tvb, guint32* offset, gint32 *val) { gint del = tvb_get_guint8(tvb, (*offset)++); if(del == ZERO){ del = tvb_get_ntohs(tvb, *offset); *offset= *offset + 2; } *val = htonl(ntohl(*val) + del); return; } /* Decode the delta of a 16 bit header field */ static void decodes(tvbuff_t *tvb, guint32* offset, gint16 *val) { gint del = tvb_get_guint8(tvb, (*offset)++); if(del == ZERO){ del = tvb_get_ntohs(tvb, *offset); *offset= *offset + 2; } *val = htons(ntohs(*val) + del); return; } /* For VJ uncompressed packet check if it is malformed */ static gint vjuc_check(tvbuff_t *tvb, slcompress *comp) { guint8 ihl = ZERO; gint index = ZERO; g_assert(comp); g_assert(tvb); if(tvb_length(tvb) < IP_HDR_LEN) { comp->flags |= SLF_TOSS; index = VJ_ERROR; } else { /* Get the IP header length */ ihl = tvb_get_guint8(tvb, 0) & IP_HDR_LEN_MASK; ihl <<= 2; /* Get connection index */ index = tvb_get_guint8(tvb, IP_FIELD_PROTOCOL); /* Check connection number and IP header length field */ if(ihl < IP_HDR_LEN || index > comp->rslot_limit) { comp->flags |= SLF_TOSS; index = VJ_ERROR; } } return index; } /* Setup the decompressed packet tvb for VJ uncompressed packets */ static gint vjuc_tvb_setup(tvbuff_t *tvb, tvbuff_t **dst_tvb, tvbuff_t **sub_tvb, slcompress *comp) { guint8 ihl = ZERO; guint8 index = ZERO; gint isize = tvb_length(tvb); guint8 *buffer = NULL; tvbuff_t *orig_tvb = NULL; gint orig_offset = 0; g_assert(comp); g_assert(tvb); /* Get the IP header length */ ihl = tvb_get_guint8(tvb, 0) & IP_HDR_LEN_MASK; ihl <<= 2; /* Copy packet data to a buffer */ orig_tvb = tvb_orig(tvb, &orig_offset); isize += orig_offset; buffer = g_malloc(isize); tvb_memcpy(orig_tvb, buffer, 0, isize); buffer[IP_FIELD_PROTOCOL + orig_offset] = IP_PROTOCOL_TCP; /* Compute checksum */ if (ip_csum(buffer + orig_offset, ihl) != ZERO) { g_free(buffer); comp->flags |= SLF_TOSS; return VJ_ERROR; } /* * Form the new tvbuff. * Neither header checksum is recalculated */ *dst_tvb = tvb_new_real_data(buffer, isize, isize, "VJ Uncompressed"); if (orig_offset > 0) *sub_tvb = tvb_new_subset(*dst_tvb, orig_offset, -1, -1); else *sub_tvb = *dst_tvb; return VJ_OK; } /* For VJ uncompressed packets update the decompressor state */ static void vjuc_update_state(tvbuff_t *tvb, slcompress *comp, guint8 index) { cstate *cs = NULL; guint8 ihl = ZERO; gint isize = tvb_length(tvb); g_assert(comp); g_assert(tvb); /* Get the IP header length */ ihl = tvb_get_guint8(tvb, 0) & IP_HDR_LEN_MASK; ihl <<= 2; /* Update local state */ cs = &comp->rstate[comp->recv_current = index]; comp->flags &= ~SLF_TOSS; tvb_memcpy(tvb, (guint8 *)&cs->cs_ip, 0, IP_HDR_LEN); tvb_memcpy(tvb, (guint8 *)&cs->cs_tcp, ihl, TCP_HDR_LEN); if (ihl > IP_HDR_LEN) tvb_memcpy(tvb, cs->cs_ipopt, sizeof(iphdr_type), ihl - IP_HDR_LEN); if (cs->cs_tcp.doff > 5) tvb_memcpy(tvb, cs->cs_tcpopt, ihl + sizeof(tcphdr_type), (cs->cs_tcp.doff - 5) * 4); return; } /* Wraper 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); }
Attachment:
tvbuff_c.patch
Description: Binary data
Attachment:
packet-ppp_c.patch
Description: Binary data
- Follow-Ups:
- Re: [Ethereal-dev] Van Jacobson dissector.
- From: Guy Harris
- Re: [Ethereal-dev] Van Jacobson dissector.
- From: Guy Harris
- Re: [Ethereal-dev] Van Jacobson dissector.
- From: Gilbert Ramirez
- Re: [Ethereal-dev] Van Jacobson dissector.
- Prev by Date: Re: [Ethereal-dev] Searching for packets with incorrect checksums
- Next by Date: Re: [Ethereal-dev] Searching for packets with incorrect checksums
- Previous by thread: Re: [Ethereal-dev] TOS (aka QoS) 0-F
- Next by thread: Re: [Ethereal-dev] Van Jacobson dissector.
- Index(es):