diff options
-rw-r--r-- | epan/packet.h | 4 | ||||
-rw-r--r-- | epan/tvbuff.c | 17 | ||||
-rw-r--r-- | epan/tvbuff.h | 10 | ||||
-rw-r--r-- | packet-clip.c | 18 | ||||
-rw-r--r-- | packet-clnp.c | 861 | ||||
-rw-r--r-- | packet-clnp.h | 4 | ||||
-rw-r--r-- | packet-esis.c | 228 | ||||
-rw-r--r-- | packet-esis.h | 8 | ||||
-rw-r--r-- | packet-eth.c | 75 | ||||
-rw-r--r-- | packet-ethertype.c | 10 | ||||
-rw-r--r-- | packet-gre.c | 13 | ||||
-rw-r--r-- | packet-ip.c | 457 | ||||
-rw-r--r-- | packet-ip.h | 8 | ||||
-rw-r--r-- | packet-mpls.c | 12 | ||||
-rw-r--r-- | packet-msproxy.c | 8 | ||||
-rw-r--r-- | packet-osi-options.c | 114 | ||||
-rw-r--r-- | packet-osi-options.h | 6 | ||||
-rw-r--r-- | packet-osi.c | 59 | ||||
-rw-r--r-- | packet-osi.h | 6 | ||||
-rw-r--r-- | packet-pim.c | 14 | ||||
-rw-r--r-- | packet-ppp.c | 195 | ||||
-rw-r--r-- | packet-raw.c | 23 | ||||
-rw-r--r-- | packet-socks.c | 10 | ||||
-rw-r--r-- | packet-tcp.c | 208 | ||||
-rw-r--r-- | packet-tcp.h | 4 | ||||
-rw-r--r-- | packet-udp.c | 77 | ||||
-rw-r--r-- | packet-udp.h | 4 | ||||
-rw-r--r-- | packet-vlan.c | 48 | ||||
-rw-r--r-- | packet-x25.c | 31 |
29 files changed, 1350 insertions, 1182 deletions
diff --git a/epan/packet.h b/epan/packet.h index e73245a79c..59fe569b95 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.6 2000/11/16 07:35:42 guy Exp $ + * $Id: packet.h,v 1.7 2000/11/18 10:38:33 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -333,7 +333,7 @@ void dissect_data(tvbuff_t *tvb, int, packet_info *pinfo, proto_tree *tree); /* These functions are in ethertype.c */ void capture_ethertype(guint16 etype, int offset, const u_char *pd, packet_counts *ld); -void ethertype(guint16 etype, tvbuff_t*, int offset_after_ethertype, +guint ethertype(guint16 etype, tvbuff_t*, int offset_after_ethertype, packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int item_id); extern const value_string etype_vals[]; diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 4b3ab60bd8..114ab545a1 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -9,7 +9,7 @@ * the data of a backing tvbuff, or can be a composite of * other tvbuffs. * - * $Id: tvbuff.c,v 1.9 2000/11/14 04:33:34 gram Exp $ + * $Id: tvbuff.c,v 1.10 2000/11/18 10:38:33 guy Exp $ * * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org> * @@ -632,7 +632,22 @@ tvb_reported_length(tvbuff_t* tvb) return tvb->reported_length; } +/* Set the reported length of a tvbuff to a given value; used for protocols + whose headers contain an explicit length and where the calling + dissector's payload may include padding as well as the packet for + this protocol. + Also adjusts the data length. */ +void +tvb_set_reported_length(tvbuff_t* tvb, guint reported_length) +{ + g_assert(tvb->initialized); + g_assert(reported_length <= tvb->reported_length); + + tvb->reported_length = reported_length; + if (reported_length < tvb->length) + tvb->length = reported_length; +} static guint8* diff --git a/epan/tvbuff.h b/epan/tvbuff.h index 3093ee3c43..ca24ee4bf4 100644 --- a/epan/tvbuff.h +++ b/epan/tvbuff.h @@ -9,7 +9,7 @@ * the data of a backing tvbuff, or can be a composite of * other tvbuffs. * - * $Id: tvbuff.h,v 1.7 2000/11/14 04:33:34 gram Exp $ + * $Id: tvbuff.h,v 1.8 2000/11/18 10:38:33 guy Exp $ * * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org> * @@ -201,6 +201,14 @@ gboolean tvb_offset_exists(tvbuff_t*, gint offset); /* Get reported length of buffer */ guint tvb_reported_length(tvbuff_t*); +/* Set the reported length of a tvbuff to a given value; used for protocols + whose headers contain an explicit length and where the calling + dissector's payload may include padding as well as the packet for + this protocol. + + Also adjusts the data length. */ +void tvb_set_reported_length(tvbuff_t*, guint); + /* Returns the offset from the first byte of real data. This is * the same value as 'offset' in tvb_compat() */ gint tvb_raw_offset(tvbuff_t*); diff --git a/packet-clip.c b/packet-clip.c index 7a86713a89..856342a90c 100644 --- a/packet-clip.c +++ b/packet-clip.c @@ -1,7 +1,7 @@ /* packet-clip.c * Routines for clip packet disassembly * - * $Id: packet-clip.c,v 1.10 2000/05/25 18:32:06 oabad Exp $ + * $Id: packet-clip.c,v 1.11 2000/11/18 10:38:23 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -40,6 +40,8 @@ static gint ett_clip = -1; +static dissector_handle_t ip_handle; + void capture_clip( const u_char *pd, packet_counts *ld ) { @@ -51,8 +53,6 @@ dissect_clip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *fh_tree; proto_item *ti; - const guint8 *this_pd; - int this_offset; pinfo->current_proto = "CLIP"; @@ -82,8 +82,7 @@ dissect_clip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) fh_tree = proto_item_add_subtree(ti, ett_clip); proto_tree_add_text(fh_tree, tvb, 0, 0, "No link information available"); } - tvb_compat(tvb, &this_pd, &this_offset); - dissect_ip(this_pd, this_offset, pinfo->fd, tree); + call_dissector(ip_handle, tvb, pinfo, tree); } void @@ -95,3 +94,12 @@ proto_register_clip(void) proto_register_subtree_array(ett, array_length(ett)); } + +void +proto_reg_handoff_clip(void) +{ + /* + * Get a handle for the IP dissector. + */ + ip_handle = find_dissector("ip"); +} diff --git a/packet-clnp.c b/packet-clnp.c index 27e452ef81..5153a18fb0 100644 --- a/packet-clnp.c +++ b/packet-clnp.c @@ -1,7 +1,7 @@ /* packet-clnp.c * Routines for ISO/OSI network and transport protocol packet disassembly * - * $Id: packet-clnp.c,v 1.13 2000/08/13 14:08:05 deniel Exp $ + * $Id: packet-clnp.c,v 1.14 2000/11/18 10:38:24 guy Exp $ * Laurent Deniel <deniel@worldnet.fr> * Ralf Schneider <Ralf.Schneider@t-online.de> * @@ -88,18 +88,6 @@ static int hf_clnp_src = -1; /* Fixed part */ -struct clnp_header { - u_char cnf_proto_id; /* network layer protocol identifier */ - u_char cnf_hdr_len; /* length indicator (octets) */ - u_char cnf_vers; /* version/protocol identifier extension */ - u_char cnf_ttl; /* lifetime (500 milliseconds) */ - u_char cnf_type; /* type code */ - u_char cnf_seglen_msb; /* pdu segment length (octets) high byte */ - u_char cnf_seglen_lsb; /* pdu segment length (octets) low byte */ - u_char cnf_cksum_msb; /* checksum high byte */ - u_char cnf_cksum_lsb; /* checksum low byte */ -}; - #define CNF_TYPE 0x1f #define CNF_ERR_OK 0x20 #define CNF_MORE_SEGS 0x40 @@ -122,7 +110,14 @@ static const value_string npdu_type_vals[] = { /* field position */ -#define P_ADDRESS_PART 9 +#define P_CLNP_PROTO_ID 0 +#define P_CLNP_HDR_LEN 1 +#define P_CLNP_VERS 2 +#define P_CLNP_TTL 3 +#define P_CLNP_TYPE 4 +#define P_CLNP_SEGLEN 5 +#define P_CLNP_CKSUM 7 +#define P_CLNP_ADDRESS_PART 9 /* Segmentation part */ @@ -314,7 +309,7 @@ static gchar *print_tsap(const u_char *tsap, int length) } /* print_tsap */ -static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, +static gboolean osi_decode_tp_var_part(tvbuff_t *tvb, int offset, int vp_length, int class_option, proto_tree *tree) { @@ -325,10 +320,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, guint32 pref_max_tpdu_size; while (vp_length != 0) { - if (!BYTES_ARE_IN_FRAME(offset, 1)) - return FALSE; - code = pd[offset]; - proto_tree_add_text(tree, NullTVB, offset, 1, + code = tvb_get_guint8(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 1, "Parameter code: 0x%02x (%s)", code, val_to_str(code, tp_vpart_type_vals, "Unknown")); @@ -337,10 +330,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, if (vp_length == 0) break; - if (!BYTES_ARE_IN_FRAME(offset, 1)) - return FALSE; - length = pd[offset]; - proto_tree_add_text(tree, NullTVB, offset, 1, + length = tvb_get_guint8(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 1, "Parameter length: %u", length); offset += 1; vp_length -= 1; @@ -348,29 +339,32 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, switch (code) { case VP_ACK_TIME: - s = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, length, + s = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, length, "Ack time (ms): %u", s); offset += length; vp_length -= length; break; case VP_RES_ERROR: - proto_tree_add_text(tree, NullTVB, offset, 1, - "Residual error rate, target value: 10^%u", pd[offset]); + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, target value: 10^%u", + tvb_get_guint8(tvb, offset)); offset += 1; length -= 1; vp_length -= 1; - proto_tree_add_text(tree, NullTVB, offset, 1, - "Residual error rate, minimum acceptable: 10^%u", pd[offset]); + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, minimum acceptable: 10^%u", + tvb_get_guint8(tvb, offset)); offset += 1; length -= 1; vp_length -= 1; - proto_tree_add_text(tree, NullTVB, offset, 1, - "Residual error rate, TSDU size of interest: %u", 1<<pd[offset]); + proto_tree_add_text(tree, tvb, offset, 1, + "Residual error rate, TSDU size of interest: %u", + 1<<tvb_get_guint8(tvb, offset)); offset += 1; length -= 1; vp_length -= 1; @@ -378,37 +372,37 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, break; case VP_PRIORITY: - s = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, length, + s = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, length, "Priority: %u", s); offset += length; vp_length -= length; break; case VP_TRANSIT_DEL: - s1 = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, 2, + s1 = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 2, "Transit delay, target value, calling-called: %u ms", s1); offset += 2; length -= 2; vp_length -= 2; - s2 = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, 2, + s2 = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 2, "Transit delay, maximum acceptable, calling-called: %u ms", s2); offset += 2; length -= 2; vp_length -= 2; - s3 = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, 2, + s3 = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 2, "Transit delay, target value, called-calling: %u ms", s3); offset += 2; length -= 2; vp_length -= 2; - s4 = EXTRACT_SHORT(&pd[offset]); - proto_tree_add_text(tree, NullTVB, offset, 2, + s4 = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 2, "Transit delay, maximum acceptable, called-calling: %u ms", s4); offset += 2; length -= 2; @@ -416,58 +410,58 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, break; case VP_THROUGHPUT: - t1 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t1 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Maximum throughput, target value, calling-called: %u o/s", t1); offset += 3; length -= 3; vp_length -= 3; - t2 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t2 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Maximum throughput, minimum acceptable, calling-called: %u o/s", t2); offset += 3; length -= 3; vp_length -= 3; - t3 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t3 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Maximum throughput, target value, called-calling: %u o/s", t3); offset += 3; length -= 3; vp_length -= 3; - t4 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t4 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Maximum throughput, minimum acceptable, called-calling: %u o/s", t4); offset += 3; length -= 3; vp_length -= 3; if (length != 0) { /* XXX - should be 0 or 12 */ - t1 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t1 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Average throughput, target value, calling-called: %u o/s", t1); offset += 3; length -= 3; vp_length -= 3; - t2 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t2 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Average throughput, minimum acceptable, calling-called: %u o/s", t2); offset += 3; length -= 3; vp_length -= 3; - t3 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t3 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Average throughput, target value, called-calling: %u o/s", t3); offset += 3; length -= 3; vp_length -= 3; - t4 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; - proto_tree_add_text(tree, NullTVB, offset, 3, + t4 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_text(tree, tvb, offset, 3, "Average throughput, minimum acceptable, called-calling: %u o/s", t4); offset += 3; length -= 3; @@ -476,34 +470,34 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, break; case VP_SEQ_NR: - proto_tree_add_text(tree, NullTVB, offset, 2, - "Sequence number: 0x%04x", EXTRACT_SHORT(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, 2, + "Sequence number: 0x%04x", tvb_get_ntohs(tvb, offset)); offset += length; vp_length -= length; break; case VP_REASSIGNMENT: - proto_tree_add_text(tree, NullTVB, offset, 2, - "Reassignment time: %u secs", EXTRACT_SHORT(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, 2, + "Reassignment time: %u secs", tvb_get_ntohs(tvb, offset)); offset += length; vp_length -= length; break; case VP_FLOW_CNTL: - proto_tree_add_text(tree, NullTVB, offset, 4, - "Lower window edge: 0x%08x", EXTRACT_LONG(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, 4, + "Lower window edge: 0x%08x", tvb_get_ntohl(tvb, offset)); offset += 4; length -= 4; vp_length -= 4; - proto_tree_add_text(tree, NullTVB, offset, 2, - "Sequence number: 0x%04x", EXTRACT_SHORT(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, 2, + "Sequence number: 0x%04x", tvb_get_ntohs(tvb, offset)); offset += 2; length -= 2; vp_length -= 2; - proto_tree_add_text(tree, NullTVB, offset, 2, - "Credit: 0x%04x", EXTRACT_SHORT(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, 2, + "Credit: 0x%04x", tvb_get_ntohs(tvb, offset)); offset += 2; length -= 2; vp_length -= 2; @@ -511,75 +505,77 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, break; case VP_TPDU_SIZE: - c1 = pd[offset] & 0x0F; - proto_tree_add_text(tree, NullTVB, offset, length, + c1 = tvb_get_guint8(tvb, offset) & 0x0F; + proto_tree_add_text(tree, tvb, offset, length, "TPDU size: %u", 2 << c1); offset += length; vp_length -= length; break; case VP_SRC_TSAP: - proto_tree_add_text(tree, NullTVB, offset, length, - "Calling TSAP: %s", print_tsap(&pd[offset], length)); + proto_tree_add_text(tree, tvb, offset, length, + "Calling TSAP: %s", + print_tsap(tvb_get_ptr(tvb, offset, length), length)); offset += length; vp_length -= length; break; case VP_DST_TSAP: - proto_tree_add_text(tree, NullTVB, offset, length, - "Called TSAP: %s", print_tsap(&pd[offset], length)); + proto_tree_add_text(tree, tvb, offset, length, + "Called TSAP: %s", + print_tsap(tvb_get_ptr(tvb, offset, length), length)); offset += length; vp_length -= length; break; case VP_CHECKSUM: - proto_tree_add_text(tree, NullTVB, offset, length, - "Checksum: 0x%04x", EXTRACT_SHORT(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, length, + "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset)); offset += length; vp_length -= length; break; case VP_VERSION_NR: - c1 = pd[offset]; - proto_tree_add_text(tree, NullTVB, offset, length, + c1 = tvb_get_guint8(tvb, offset); + proto_tree_add_text(tree, tvb, offset, length, "Version: %u", c1); offset += length; vp_length -= length; break; case VP_OPT_SEL: - c1 = pd[offset] & 0x0F; + c1 = tvb_get_guint8(tvb, offset) & 0x0F; switch (class_option) { case 1: if (c1 & 0x8) - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Use of network expedited data"); else - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Non use of network expedited data"); if (c1 & 0x4) - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Use of Receipt confirmation"); else - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Use of explicit AK variant"); break; case 4: if (c1 & 0x2) - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Non-use 16 bit checksum in class 4"); else - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Use 16 bit checksum "); break; } if (c1 & 0x1) - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Use of transport expedited data transfer\n"); else - proto_tree_add_text(tree, NullTVB, offset, 1, + proto_tree_add_text(tree, tvb, offset, 1, "Non-use of transport expedited data transfer"); offset += length; vp_length -= length; @@ -589,36 +585,36 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, switch (length) { case 1: - pref_max_tpdu_size = pd[offset]; + pref_max_tpdu_size = tvb_get_guint8(tvb, offset); break; case 2: - pref_max_tpdu_size = EXTRACT_SHORT(&pd[offset]); + pref_max_tpdu_size = tvb_get_ntohs(tvb, offset); break; case 3: - pref_max_tpdu_size = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2]; + pref_max_tpdu_size = tvb_get_ntoh24(tvb, offset); break; case 4: - pref_max_tpdu_size = EXTRACT_LONG(&pd[offset]); + pref_max_tpdu_size = tvb_get_ntohl(tvb, offset); break; default: - proto_tree_add_text(tree, NullTVB, offset, length, + proto_tree_add_text(tree, tvb, offset, length, "Preferred maximum TPDU size: bogus length %u (not 1, 2, 3, or 4)", length); return FALSE; } - proto_tree_add_text(tree, NullTVB, offset, length, + proto_tree_add_text(tree, tvb, offset, length, "Preferred maximum TPDU size: %u", pref_max_tpdu_size*128); offset += length; vp_length -= length; break; case VP_INACTIVITY_TIMER: - proto_tree_add_text(tree, NullTVB, offset, length, - "Inactivity timer: %u ms", EXTRACT_LONG(&pd[offset])); + proto_tree_add_text(tree, tvb, offset, length, + "Inactivity timer: %u ms", tvb_get_ntohl(tvb, offset)); offset += length; vp_length -= length; break; @@ -626,7 +622,7 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, case VP_PROTECTION: /* user-defined */ case VP_PROTO_CLASS: /* todo */ default: /* unknown, no decoding */ - proto_tree_add_text(tree, NullTVB, offset, length, + proto_tree_add_text(tree, tvb, offset, length, "Parameter value: <not shown>"); offset += length; vp_length -= length; @@ -637,8 +633,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset, return TRUE; } -static int osi_decode_DR(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_DR(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree; proto_item *ti; @@ -649,8 +645,8 @@ static int osi_decode_DR(const u_char *pd, int offset, if (li < LI_MIN_DR) return -1; - src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]); - reason = pd[offset + P_REASON_IN_DR]; + src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF); + reason = tvb_get_guint8(tvb, offset + P_REASON_IN_DR); switch(reason) { case (128+0): str = "Normal Disconnect"; break; @@ -671,36 +667,41 @@ static int osi_decode_DR(const u_char *pd, int offset, break; } - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "DR TPDU src-ref: 0x%04x dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, + "DR TPDU src-ref: 0x%04x dst-ref: 0x%04x", src_ref, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); - proto_tree_add_text(cotp_tree, NullTVB, offset + 1, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 1, 1, "TPDU code: 0x%x (DR)", tpdu); - proto_tree_add_text(cotp_tree, NullTVB, offset + 2, 2, + proto_tree_add_text(cotp_tree, tvb, offset + 2, 2, "Destination reference: 0x%04x", dst_ref); - proto_tree_add_text(cotp_tree, NullTVB, offset + 4, 2, + proto_tree_add_text(cotp_tree, tvb, offset + 4, 2, "Source reference: 0x%04x", src_ref); - proto_tree_add_text(cotp_tree, NullTVB, offset + 6, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 6, 1, "Cause: %s", str); } offset += li + 1; - old_dissect_data(pd, offset, fd, tree); - return pi.captured_len; /* we dissected all of the containing PDU */ + /* User data */ + dissect_data(tvb, offset, pinfo, tree); + offset += tvb_length_remaining(tvb, offset); + /* we dissected all of the containing PDU */ + + return offset; } /* osi_decode_DR */ -/* Returns TRUE if we called a sub-dissector, FALSE if not. */ -static gboolean osi_decode_DT(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree, - gboolean uses_inactive_subset) +static int osi_decode_DT(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + gboolean uses_inactive_subset, + gboolean *subdissector_found) { proto_tree *cotp_tree = NULL; proto_item *ti; @@ -708,6 +709,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, gboolean is_class_234; u_int tpdu_nr ; u_int fragment = 0; + tvbuff_t *next_tvb; /* VP_CHECKSUM is the only parameter allowed in the variable part. (This means we may misdissect this if the packet is bad and @@ -715,12 +717,12 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, switch (li) { case LI_NORMAL_DT_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM) return -1; /* FALLTHROUGH */ case LI_NORMAL_DT_WITHOUT_CHECKSUM : - tpdu_nr = pd[offset + P_TPDU_NR_234]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); if ( tpdu_nr & 0x80 ) tpdu_nr = tpdu_nr & 0x7F; else @@ -730,12 +732,12 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, break; case LI_EXTENDED_DT_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM) return -1; /* FALLTHROUGH */ case LI_EXTENDED_DT_WITHOUT_CHECKSUM : - tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]); + tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234); if ( tpdu_nr & 0x80000000 ) tpdu_nr = tpdu_nr & 0x7FFFFFFF; else @@ -745,7 +747,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, break; case LI_NORMAL_DT_CLASS_01 : - tpdu_nr = pd[offset + P_TPDU_NR_0_1]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_0_1); if ( tpdu_nr & 0x80 ) tpdu_nr = tpdu_nr & 0x7F; else @@ -760,22 +762,22 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, break; } - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s", tpdu_nr, dst_ref, (fragment)? "(fragment)" : ""); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (DT)", tpdu); } @@ -784,7 +786,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, if (is_class_234) { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; @@ -793,7 +795,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, if (is_extended) { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 4, + proto_tree_add_text(cotp_tree, tvb, offset, 4, "TPDU number: 0x%08x (%s)", tpdu_nr, (fragment)? "fragment":"complete"); @@ -802,7 +804,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, li -= 4; } else { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU number: 0x%02x (%s)", tpdu_nr, (fragment)? "fragment":"complete"); @@ -812,31 +814,35 @@ static gboolean osi_decode_DT(const u_char *pd, int offset, } if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; + next_tvb = tvb_new_subset(tvb, offset, -1, -1); if (uses_inactive_subset){ - if (old_dissector_try_heuristic(cotp_is_heur_subdissector_list, pd, offset, - fd, tree)) { - return TRUE; - } - /* Fill in other Dissectors using inactive subset here */ - old_dissect_data(pd, offset, fd, tree); - return FALSE; - } - else { - old_dissect_data(pd, offset, fd, tree); - return FALSE; + if (dissector_try_heuristic(cotp_is_heur_subdissector_list, next_tvb, + pinfo, tree)) { + *subdissector_found = TRUE; + } else { + /* Fill in other Dissectors using inactive subset here */ + dissect_data(next_tvb, 0, pinfo, tree); } + } else + dissect_data(next_tvb, 0, pinfo, tree); + offset += tvb_length_remaining(tvb, offset); + /* we dissected all of the containing PDU */ + + return offset; + } /* osi_decode_DT */ -static int osi_decode_ED(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_ED(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree = NULL; proto_item *ti; gboolean is_extended; u_int tpdu_nr ; + tvbuff_t *next_tvb; /* ED TPDUs are never fragmented */ @@ -846,12 +852,12 @@ static int osi_decode_ED(const u_char *pd, int offset, switch (li) { case LI_NORMAL_DT_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM) return -1; /* FALLTHROUGH */ case LI_NORMAL_DT_WITHOUT_CHECKSUM : - tpdu_nr = pd[offset + P_TPDU_NR_234]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); if ( tpdu_nr & 0x80 ) tpdu_nr = tpdu_nr & 0x7F; else @@ -860,12 +866,12 @@ static int osi_decode_ED(const u_char *pd, int offset, break; case LI_EXTENDED_DT_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM) return -1; /* FALLTHROUGH */ case LI_EXTENDED_DT_WITHOUT_CHECKSUM : - tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]); + tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234); if ( tpdu_nr & 0x80000000 ) tpdu_nr = tpdu_nr & 0x7FFFFFFF; else @@ -879,27 +885,27 @@ static int osi_decode_ED(const u_char *pd, int offset, break; } /* li */ - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (ED)", tpdu); } offset += 1; li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; @@ -907,14 +913,14 @@ static int osi_decode_ED(const u_char *pd, int offset, if (is_extended) { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 4, + proto_tree_add_text(cotp_tree, tvb, offset, 4, "TPDU number: 0x%02x", tpdu_nr); } offset += 4; li -= 4; } else { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU number: 0x%02x", tpdu_nr); } offset += 1; @@ -922,17 +928,21 @@ static int osi_decode_ED(const u_char *pd, int offset, } if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; - old_dissect_data(pd, offset, fd, tree); + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + dissect_data(next_tvb, 0, pinfo, tree); + + offset += tvb_length_remaining(tvb, offset); + /* we dissected all of the containing PDU */ - return pi.captured_len; /* we dissected all of the containing PDU */ + return offset; } /* osi_decode_ED */ -static int osi_decode_RJ(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_RJ(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree; proto_item *ti; @@ -941,11 +951,11 @@ static int osi_decode_RJ(const u_char *pd, int offset, switch(li) { case LI_NORMAL_RJ : - tpdu_nr = pd[offset + P_TPDU_NR_234]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); break; case LI_EXTENDED_RJ : - tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]); - credit = EXTRACT_SHORT(&pd[offset + P_CDT_IN_RJ]); + tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234); + credit = tvb_get_ntohs(tvb, offset + P_CDT_IN_RJ); break; default : return -1; @@ -953,29 +963,29 @@ static int osi_decode_RJ(const u_char *pd, int offset, break; } - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); - proto_tree_add_text(cotp_tree, NullTVB, offset + 1, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 1, 1, "TPDU code: 0x%x (RJ)", tpdu); if (li == LI_NORMAL_RJ) - proto_tree_add_text(cotp_tree, NullTVB, offset + 1, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 1, 1, "Credit: %u", cdt); - proto_tree_add_text(cotp_tree, NullTVB, offset + 2, 2, + proto_tree_add_text(cotp_tree, tvb, offset + 2, 2, "Destination reference: 0x%04x", dst_ref); if (li == LI_NORMAL_RJ) - proto_tree_add_text(cotp_tree, NullTVB, offset + 4, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 4, 1, "Your TPDU number: 0x%02x", tpdu_nr); else { - proto_tree_add_text(cotp_tree, NullTVB, offset + 4, 4, + proto_tree_add_text(cotp_tree, tvb, offset + 4, 4, "Your TPDU number: 0x%02x", tpdu_nr); - proto_tree_add_text(cotp_tree, NullTVB, offset + 8, 2, + proto_tree_add_text(cotp_tree, tvb, offset + 8, 2, "Credit: 0x%02x", credit); } } @@ -986,8 +996,8 @@ static int osi_decode_RJ(const u_char *pd, int offset, } /* osi_decode_RJ */ -static int osi_decode_CC(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_CC(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { /* CC & CR decoding in the same function */ @@ -997,27 +1007,28 @@ static int osi_decode_CC(const u_char *pd, int offset, u_short src_ref; u_char class_option; - src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]); - class_option = (pd[offset + P_CLASS_OPTION] >> 4 ) & 0x0F; + src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF); + class_option = (tvb_get_guint8(tvb, offset + P_CLASS_OPTION) >> 4 ) & 0x0F; if (class_option > 4) return -1; - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, + "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x", (tpdu == CR_TPDU) ? "CR" : "CC", src_ref, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (%s)", tpdu, (tpdu == CR_TPDU) ? "CR" : "CC"); } @@ -1025,38 +1036,41 @@ static int osi_decode_CC(const u_char *pd, int offset, li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; li -= 2; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Source reference: 0x%04x", src_ref); } offset += 2; li -= 2; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Class option: 0x%02x", class_option); } offset += 1; li -= 1; if (tree) - osi_decode_tp_var_part(pd, offset, li, class_option, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, class_option, cotp_tree); offset += li; - old_dissect_data(pd, offset, fd, tree); + /* User data */ + dissect_data(tvb, offset, pinfo, tree); + offset += tvb_length_remaining(tvb, offset); + /* we dissected all of the containing PDU */ - return pi.captured_len; /* we dissected all of the containing PDU */ + return offset; } /* osi_decode_CC */ -static int osi_decode_DC(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_DC(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree = NULL; proto_item *ti; @@ -1065,52 +1079,53 @@ static int osi_decode_DC(const u_char *pd, int offset, if (li > LI_MAX_DC) return -1; - src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]); + src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF); - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, + "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", src_ref, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (DC)", tpdu); } offset += 1; li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; li -= 2; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Source reference: 0x%04x", src_ref); } offset += 2; li -= 2; if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; return offset; } /* osi_decode_DC */ -static int osi_decode_AK(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_AK(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree = NULL; proto_item *ti; @@ -1122,94 +1137,94 @@ static int osi_decode_AK(const u_char *pd, int offset, if (is_LI_NORMAL_AK(li)) { - tpdu_nr = pd[offset + P_TPDU_NR_234]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (AK)", tpdu); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Credit: %u", cdt); } offset += 1; li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; li -= 2; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Your TPDU number: 0x%02x", tpdu_nr); } offset += 1; li -= 1; if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; } else { /* extended format */ - tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]); - cdt_in_ak = EXTRACT_SHORT(&pd[offset + P_CDT_IN_AK]); + tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234); + cdt_in_ak = tvb_get_ntohs(tvb, offset + P_CDT_IN_AK); - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (AK)", tpdu); } offset += 1; li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; li -= 2; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 4, + proto_tree_add_text(cotp_tree, tvb, offset, 4, "Your TPDU number: 0x%08x", tpdu_nr); } offset += 4; li -= 4; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Credit: 0x%04x", cdt_in_ak); } offset += 2; li -= 2; if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; } /* is_LI_NORMAL_AK */ @@ -1218,8 +1233,8 @@ static int osi_decode_AK(const u_char *pd, int offset, } /* osi_decode_AK */ -static int osi_decode_EA(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_EA(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree = NULL; proto_item *ti; @@ -1235,24 +1250,24 @@ static int osi_decode_EA(const u_char *pd, int offset, switch (li) { case LI_NORMAL_EA_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM || - pd[offset + P_VAR_PART_NDT + 1] != 2) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM || + tvb_get_guint8(tvb, offset + P_VAR_PART_NDT + 1) != 2) return -1; /* FALLTHROUGH */ case LI_NORMAL_EA_WITHOUT_CHECKSUM : - tpdu_nr = pd[offset + P_TPDU_NR_234]; + tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); is_extended = FALSE; break; case LI_EXTENDED_EA_WITH_CHECKSUM : - if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM || - pd[offset + P_VAR_PART_EDT + 1] != 2) + if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM || + tvb_get_guint8(tvb, offset + P_VAR_PART_EDT + 1) != 2) return -1; /* FALLTHROUGH */ case LI_EXTENDED_EA_WITHOUT_CHECKSUM : - tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]); + tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234); is_extended = TRUE; break; @@ -1262,27 +1277,27 @@ static int osi_decode_EA(const u_char *pd, int offset, break; } /* li */ - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "EA TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "TPDU code: 0x%x (EA)", tpdu); } offset += 1; li -= 1; if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 2, + proto_tree_add_text(cotp_tree, tvb, offset, 2, "Destination reference: 0x%04x", dst_ref); } offset += 2; @@ -1290,14 +1305,14 @@ static int osi_decode_EA(const u_char *pd, int offset, if (is_extended) { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 4, + proto_tree_add_text(cotp_tree, tvb, offset, 4, "Your TPDU number: 0x%08x", tpdu_nr); } offset += 4; li -= 4; } else { if (tree) { - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Your TPDU number: 0x%02x", tpdu_nr); } offset += 1; @@ -1305,15 +1320,15 @@ static int osi_decode_EA(const u_char *pd, int offset, } if (tree) - osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree); + osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree); offset += li; return offset; } /* osi_decode_EA */ -static int osi_decode_ER(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_ER(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree) { proto_tree *cotp_tree; proto_item *ti; @@ -1322,7 +1337,7 @@ static int osi_decode_ER(const u_char *pd, int offset, if (li > LI_MAX_ER) return -1; - switch(pd[offset + P_REJECT_ER]) { + switch(tvb_get_guint8(tvb, offset + P_REJECT_ER)) { case 0 : str = "Reason not specified"; break; @@ -1341,19 +1356,19 @@ static int osi_decode_ER(const u_char *pd, int offset, break; } - if (check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref); + if (check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref); if (tree) { - ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE); cotp_tree = proto_item_add_subtree(ti, ett_cotp); - proto_tree_add_text(cotp_tree, NullTVB, offset, 1, + proto_tree_add_text(cotp_tree, tvb, offset, 1, "Length indicator: %u", li); - proto_tree_add_text(cotp_tree, NullTVB, offset + 1, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 1, 1, "TPDU code: 0x%x (ER)", tpdu); - proto_tree_add_text(cotp_tree, NullTVB, offset + 2, 2, + proto_tree_add_text(cotp_tree, tvb, offset + 2, 2, "Destination reference: 0x%04x", dst_ref); - proto_tree_add_text(cotp_tree, NullTVB, offset + 4, 1, + proto_tree_add_text(cotp_tree, tvb, offset + 4, 1, "Reject cause: %s", str); } @@ -1363,37 +1378,43 @@ static int osi_decode_ER(const u_char *pd, int offset, } /* osi_decode_ER */ -/* Returns TRUE if we called a sub-dissector, FALSE if not. */ -static gboolean osi_decode_UD(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) +static int osi_decode_UD(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + gboolean *subdissector_found) { proto_item *ti; proto_tree *cltp_tree = NULL; + tvbuff_t *next_tvb; - if (check_col(fd, COL_INFO)) - col_append_str(fd, COL_INFO, "UD TPDU"); + if (check_col(pinfo->fd, COL_INFO)) + col_append_str(pinfo->fd, COL_INFO, "UD TPDU"); if (tree) { - ti = proto_tree_add_item(tree, proto_cltp, NullTVB, offset, li + 1, FALSE); + ti = proto_tree_add_item(tree, proto_cltp, tvb, offset, li + 1, FALSE); cltp_tree = proto_item_add_subtree(ti, ett_cltp); - proto_tree_add_text(cltp_tree, NullTVB, offset, 1, + proto_tree_add_text(cltp_tree, tvb, offset, 1, "Length indicator: %u", li); } offset += 1; if (tree) { - proto_tree_add_text(cltp_tree, NullTVB, offset, 1, + proto_tree_add_text(cltp_tree, tvb, offset, 1, "TPDU code: 0x%x (UD)", tpdu); } offset += 1; li -= 1; if (tree) - osi_decode_tp_var_part(pd, offset, li, 0, cltp_tree); + osi_decode_tp_var_part(tvb, offset, li, 0, cltp_tree); offset += li; - old_dissect_data(pd, offset, fd, tree); - return FALSE; + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + dissect_data(next_tvb, 0, pinfo, tree); + offset += tvb_length_remaining(tvb, offset); + /* we dissected all of the containing PDU */ + + return offset; + } /* osi_decode_UD */ /* Returns TRUE if we found at least one valid COTP or CLTP PDU, FALSE @@ -1404,100 +1425,99 @@ static gboolean osi_decode_UD(const u_char *pd, int offset, protocols' headers mean the same thing - length and PDU type - and the only valid CLTP PDU type is not a valid COTP PDU type, so we'll handle both of them here. */ -static gboolean dissect_ositp_internal(const u_char *pd, int offset, - frame_data *fd, proto_tree *tree, - gboolean uses_inactive_subset) +static gboolean dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, gboolean uses_inactive_subset) { + int offset = 0; gboolean first_tpdu = TRUE; int new_offset; gboolean found_ositp = FALSE; gboolean is_cltp = FALSE; gboolean subdissector_found = FALSE; + if (!proto_is_protocol_enabled(proto_cotp)) + return FALSE; /* COTP has been disabled */ + /* XXX - what about CLTP? */ + + pinfo->current_proto = "COTP"; + /* Initialize the COL_INFO field; each of the TPDUs will have its information appended. */ - if (check_col(fd, COL_INFO)) - col_add_str(fd, COL_INFO, ""); + if (check_col(pinfo->fd, COL_INFO)) + col_add_str(pinfo->fd, COL_INFO, ""); - while (IS_DATA_IN_FRAME(offset)) { + while (tvb_offset_exists(tvb, offset)) { if (!first_tpdu) { - if (check_col(fd, COL_INFO)) - col_append_str(fd, COL_INFO, ", "); + if (check_col(pinfo->fd, COL_INFO)) + col_append_str(pinfo->fd, COL_INFO, ", "); } - if ((li = pd[offset + P_LI]) == 0) { - if (check_col(fd, COL_INFO)) - col_append_str(fd, COL_INFO, "Length indicator is zero"); + if ((li = tvb_get_guint8(tvb, offset + P_LI)) == 0) { + if (check_col(pinfo->fd, COL_INFO)) + col_append_str(pinfo->fd, COL_INFO, "Length indicator is zero"); if (!first_tpdu) - old_dissect_data(pd, offset, fd, tree); - return found_ositp; - } - if (!BYTES_ARE_IN_FRAME(offset, P_LI + li + 1)) { - if (check_col(fd, COL_INFO)) - col_append_str(fd, COL_INFO, "Captured data in frame doesn't include entire frame"); - if (!first_tpdu) - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, offset, pinfo, tree); return found_ositp; } - tpdu = (pd[offset + P_TPDU] >> 4) & 0x0F; - cdt = pd[offset + P_CDT] & 0x0F; - dst_ref = EXTRACT_SHORT(&pd[offset + P_DST_REF]); + tpdu = (tvb_get_guint8(tvb, offset + P_TPDU) >> 4) & 0x0F; + if (tpdu == UD_TPDU) + pinfo->current_proto = "CLTP"; /* connectionless transport */ + cdt = tvb_get_guint8(tvb, offset + P_CDT) & 0x0F; + dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); switch (tpdu) { case CC_TPDU : case CR_TPDU : - new_offset = osi_decode_CC(pd, offset, fd, tree); + new_offset = osi_decode_CC(tvb, offset, pinfo, tree); break; case DR_TPDU : - new_offset = osi_decode_DR(pd, offset, fd, tree); + new_offset = osi_decode_DR(tvb, offset, pinfo, tree); break; case DT_TPDU : - if (osi_decode_DT(pd, offset, fd, tree, uses_inactive_subset)) - subdissector_found = TRUE; - new_offset = pi.captured_len; /* DT PDUs run to the end of the packet */ + new_offset = osi_decode_DT(tvb, offset, pinfo, tree, + uses_inactive_subset, &subdissector_found); break; case ED_TPDU : - new_offset = osi_decode_ED(pd, offset, fd, tree); + new_offset = osi_decode_ED(tvb, offset, pinfo, tree); break; case RJ_TPDU : - new_offset = osi_decode_RJ(pd, offset, fd, tree); + new_offset = osi_decode_RJ(tvb, offset, pinfo, tree); break; case DC_TPDU : - new_offset = osi_decode_DC(pd, offset, fd, tree); + new_offset = osi_decode_DC(tvb, offset, pinfo, tree); break; case AK_TPDU : - new_offset = osi_decode_AK(pd, offset, fd, tree); + new_offset = osi_decode_AK(tvb, offset, pinfo, tree); break; case EA_TPDU : - new_offset = osi_decode_EA(pd, offset, fd, tree); + new_offset = osi_decode_EA(tvb, offset, pinfo, tree); break; case ER_TPDU : - new_offset = osi_decode_ER(pd, offset, fd, tree); + new_offset = osi_decode_ER(tvb, offset, pinfo, tree); break; case UD_TPDU : - if (osi_decode_UD(pd, offset, fd, tree)) - subdissector_found = TRUE; - new_offset = pi.captured_len; /* UD PDUs run to the end of the packet */ + new_offset = osi_decode_UD(tvb, offset, pinfo, tree, + &subdissector_found); is_cltp = TRUE; break; default : - if (first_tpdu && check_col(fd, COL_INFO)) - col_append_fstr(fd, COL_INFO, "Unknown TPDU type (0x%x)", tpdu); + if (first_tpdu && check_col(pinfo->fd, COL_INFO)) + col_append_fstr(pinfo->fd, COL_INFO, "Unknown TPDU type (0x%x)", tpdu); new_offset = -1; /* bad PDU type */ break; } if (new_offset == -1) { /* incorrect TPDU */ if (!first_tpdu) - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, offset, pinfo, tree); break; } if (first_tpdu) { /* Well, we found at least one valid COTP or CLTP PDU, so I guess this is either COTP or CLTP. */ - if (!subdissector_found && check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP"); + if (!subdissector_found && check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP"); found_ositp = TRUE; } @@ -1507,12 +1527,10 @@ static gboolean dissect_ositp_internal(const u_char *pd, int offset, return found_ositp; } /* dissect_ositp_internal */ -void dissect_ositp(const u_char *pd, int offset, frame_data *fd, - proto_tree *tree) +void dissect_ositp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - OLD_CHECK_DISPLAY_AS_DATA(proto_cotp, pd, offset, fd, tree); - if (!dissect_ositp_internal(pd, offset, fd, tree, FALSE)) - old_dissect_data(pd, offset, fd, tree); + if (!dissect_ositp_internal(tvb, pinfo, tree, FALSE)) + dissect_data(tvb, 0, pinfo, tree); } @@ -1520,155 +1538,168 @@ void dissect_ositp(const u_char *pd, int offset, frame_data *fd, * CLNP part / main entry point */ -static void dissect_clnp(const u_char *pd, int offset, frame_data *fd, - proto_tree *tree) +static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - - struct clnp_header clnp; proto_tree *clnp_tree = NULL; proto_item *ti; + guint8 cnf_proto_id; + guint8 cnf_hdr_len; + guint8 cnf_vers; + guint8 cnf_ttl; + guint8 cnf_type; + char flag_string[6+1]; + char *pdu_type_string; + guint16 segment_length; + guint16 segment_offset = 0; + guint16 cnf_cksum; + int offset; u_char src_len, dst_len, nsel, opt_len = 0; - u_int first_offset = offset; - char flag_string[6+1]; - char *pdu_type_string; - guint16 segment_length; - guint16 segment_offset = 0; - guint len; + guint8 *dst_addr, *src_addr; + guint len; + tvbuff_t *next_tvb; - OLD_CHECK_DISPLAY_AS_DATA(proto_clnp, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_clnp, tvb, pinfo, tree); - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "CLNP"); + pinfo->current_proto = "CLNP"; - /* avoid alignment problem */ - memcpy(&clnp, &pd[offset], sizeof(clnp)); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "CLNP"); - if (clnp.cnf_proto_id == NLPID_NULL) { - if (check_col(fd, COL_INFO)) - col_add_str(fd, COL_INFO, "Inactive subset"); + cnf_proto_id = tvb_get_guint8(tvb, P_CLNP_PROTO_ID); + if (cnf_proto_id == NLPID_NULL) { + if (check_col(pinfo->fd, COL_INFO)) + col_add_str(pinfo->fd, COL_INFO, "Inactive subset"); if (tree) { - ti = proto_tree_add_item(tree, proto_clnp, NullTVB, offset, 1, FALSE); + ti = proto_tree_add_item(tree, proto_clnp, tvb, P_CLNP_PROTO_ID, 1, FALSE); clnp_tree = proto_item_add_subtree(ti, ett_clnp); - proto_tree_add_uint_format(clnp_tree, hf_clnp_id, NullTVB, offset, 1, - clnp.cnf_proto_id, + proto_tree_add_uint_format(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1, + cnf_proto_id, "Inactive subset"); } - dissect_ositp_internal(pd, offset+1, fd, tree, TRUE); + next_tvb = tvb_new_subset(tvb, 1, -1, -1); + dissect_ositp_internal(next_tvb, pinfo, tree, TRUE); return; } - if (!BYTES_ARE_IN_FRAME(offset, sizeof(clnp))) { - old_dissect_data(pd, offset, fd, tree); - return; - } - /* return if version not known */ - if (clnp.cnf_vers != ISO8473_V1) { - old_dissect_data(pd, offset, fd, tree); + cnf_vers = tvb_get_guint8(tvb, P_CLNP_VERS); + if (cnf_vers != ISO8473_V1) { + dissect_data(tvb, 0, pinfo, tree); return; } /* fixed part decoding */ - opt_len = clnp.cnf_hdr_len; + cnf_hdr_len = tvb_get_guint8(tvb, P_CLNP_HDR_LEN); + opt_len = cnf_hdr_len; - segment_length = EXTRACT_SHORT(&clnp.cnf_seglen_msb); + if (tree) { + ti = proto_tree_add_item(tree, proto_clnp, tvb, 0, cnf_hdr_len, FALSE); + clnp_tree = proto_item_add_subtree(ti, ett_clnp); + proto_tree_add_uint(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1, + cnf_proto_id); + proto_tree_add_uint(clnp_tree, hf_clnp_length, tvb, P_CLNP_HDR_LEN, 1, + cnf_hdr_len); + proto_tree_add_uint(clnp_tree, hf_clnp_version, tvb, P_CLNP_VERS, 1, + cnf_vers); + cnf_ttl = tvb_get_guint8(tvb, P_CLNP_TTL); + proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, tvb, P_CLNP_TTL, 1, + cnf_ttl, + "Holding Time : %u (%u secs)", + cnf_ttl, cnf_ttl / 2); + } + + cnf_type = tvb_get_guint8(tvb, P_CLNP_TYPE); + pdu_type_string = val_to_str(cnf_type & CNF_TYPE, npdu_type_vals, + "Unknown (0x%02x)"); flag_string[0] = '\0'; - if (clnp.cnf_type & CNF_SEG_OK) + if (cnf_type & CNF_SEG_OK) strcat(flag_string, "S "); - if (clnp.cnf_type & CNF_MORE_SEGS) + if (cnf_type & CNF_MORE_SEGS) strcat(flag_string, "M "); - if (clnp.cnf_type & CNF_ERR_OK) + if (cnf_type & CNF_ERR_OK) strcat(flag_string, "E "); - pdu_type_string = val_to_str(clnp.cnf_type & CNF_TYPE, npdu_type_vals, - "Unknown (0x%02x)"); if (tree) { - ti = proto_tree_add_item(tree, proto_clnp, NullTVB, offset, clnp.cnf_hdr_len, FALSE); - clnp_tree = proto_item_add_subtree(ti, ett_clnp); - proto_tree_add_uint(clnp_tree, hf_clnp_id, NullTVB, offset, 1, - clnp.cnf_proto_id); - proto_tree_add_uint(clnp_tree, hf_clnp_length, NullTVB, offset + 1, 1, - clnp.cnf_hdr_len); - proto_tree_add_uint(clnp_tree, hf_clnp_version, NullTVB, offset + 2, 1, - clnp.cnf_vers); - proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, NullTVB, offset + 3, 1, - clnp.cnf_ttl, - "Holding Time : %u (%u secs)", - clnp.cnf_ttl, clnp.cnf_ttl / 2); - proto_tree_add_uint_format(clnp_tree, hf_clnp_type, NullTVB, offset + 4, 1, - clnp.cnf_type, + proto_tree_add_uint_format(clnp_tree, hf_clnp_type, tvb, P_CLNP_TYPE, 1, + cnf_type, "PDU Type : 0x%02x (%s%s)", - clnp.cnf_type, + cnf_type, flag_string, pdu_type_string); - proto_tree_add_uint(clnp_tree, hf_clnp_pdu_length, NullTVB, offset + 5, 2, + } + + /* If we don't have the full header - i.e., not enough to see the + segmentation part and determine whether this datagram is segmented + or not - set the Info column now; we'll get an exception before + we set it otherwise. */ + + if (!tvb_bytes_exist(tvb, 0, cnf_hdr_len)) { + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string); + } + + segment_length = tvb_get_ntohs(tvb, P_CLNP_SEGLEN); + if (tree) { + proto_tree_add_uint(clnp_tree, hf_clnp_pdu_length, tvb, P_CLNP_SEGLEN, 2, segment_length); - proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, NullTVB, offset + 7, 2, - EXTRACT_SHORT(&clnp.cnf_cksum_msb), + cnf_cksum = tvb_get_ntohs(tvb, P_CLNP_CKSUM); + proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, tvb, P_CLNP_CKSUM, 2, + cnf_cksum, "Checksum : 0x%04x", - EXTRACT_SHORT(&clnp.cnf_cksum_msb)); + cnf_cksum); opt_len -= 9; /* Fixed part of Hesder */ } /* tree */ - /* stop here if header is not complete */ - - if (!BYTES_ARE_IN_FRAME(offset, clnp.cnf_hdr_len)) { - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string); - old_dissect_data(pd, offset, fd, tree); - return; - } - /* address part */ - offset += P_ADDRESS_PART; - dst_len = pd[offset]; - nsel = pd[offset + dst_len]; - src_len = pd[offset + dst_len + 1]; + offset = P_CLNP_ADDRESS_PART; + dst_len = tvb_get_guint8(tvb, offset); + dst_addr = tvb_get_ptr(tvb, offset + 1, dst_len); + nsel = tvb_get_guint8(tvb, offset + dst_len); + src_len = tvb_get_guint8(tvb, offset + dst_len + 1); + src_addr = tvb_get_ptr(tvb, offset + dst_len + 2, src_len); if (tree) { - proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, NullTVB, offset, 1, + proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, tvb, offset, 1, dst_len); - proto_tree_add_bytes_format(clnp_tree, hf_clnp_dest, NullTVB, offset + 1 , dst_len, - &pd[offset + 1], + proto_tree_add_bytes_format(clnp_tree, hf_clnp_dest, tvb, offset + 1 , dst_len, + dst_addr, " DA : %s", - print_nsap_net(&pd[offset + 1], dst_len)); - proto_tree_add_uint(clnp_tree, hf_clnp_src_length, NullTVB, + print_nsap_net(dst_addr, dst_len)); + proto_tree_add_uint(clnp_tree, hf_clnp_src_length, tvb, offset + 1 + dst_len, 1, src_len); - proto_tree_add_bytes_format(clnp_tree, hf_clnp_src, NullTVB, + proto_tree_add_bytes_format(clnp_tree, hf_clnp_src, tvb, offset + dst_len + 2, src_len, - &pd[offset + dst_len + 2], + src_addr, " SA : %s", - print_nsap_net(&pd[offset + dst_len + 2], src_len)); + print_nsap_net(src_addr, src_len)); opt_len -= dst_len + src_len +2; } - if (check_col(fd, COL_RES_NET_SRC)) - col_add_fstr(fd, COL_RES_NET_SRC, "%s", - print_nsap_net(&pd[offset + dst_len + 2], src_len)); - if (check_col(fd, COL_RES_NET_DST)) - col_add_fstr(fd, COL_RES_NET_DST, "%s", - print_nsap_net(&pd[offset + 1], dst_len)); + if (check_col(pinfo->fd, COL_RES_NET_SRC)) + col_add_fstr(pinfo->fd, COL_RES_NET_SRC, "%s", print_nsap_net(src_addr, src_len)); + if (check_col(pinfo->fd, COL_RES_NET_DST)) + col_add_fstr(pinfo->fd, COL_RES_NET_DST, "%s", print_nsap_net(dst_addr, dst_len)); /* Segmentation Part */ offset += dst_len + src_len + 2; - if (clnp.cnf_type & CNF_SEG_OK) { + if (cnf_type & CNF_SEG_OK) { struct clnp_segment seg; /* XXX - not used */ - memcpy(&seg, &pd[offset], sizeof(seg)); /* XXX - not used */ + tvb_memcpy(tvb, (guint8 *)&seg, offset, sizeof(seg)); /* XXX - not used */ - segment_offset = EXTRACT_SHORT(&pd[offset + 2]); + segment_offset = tvb_get_ntohs(tvb, offset + 2); if (tree) { - proto_tree_add_text(clnp_tree, NullTVB, offset, 2, + proto_tree_add_text(clnp_tree, tvb, offset, 2, "Data unit identifier: %06u", - EXTRACT_SHORT(&pd[offset])); - proto_tree_add_text(clnp_tree, NullTVB, offset + 2 , 2, + tvb_get_ntohs(tvb, offset)); + proto_tree_add_text(clnp_tree, tvb, offset + 2 , 2, "Segment offset : %6u", segment_offset); - proto_tree_add_text(clnp_tree, NullTVB, offset + 4 , 2, + proto_tree_add_text(clnp_tree, tvb, offset + 4 , 2, "Total length : %6u", - EXTRACT_SHORT(&pd[offset + 4])); + tvb_get_ntohs(tvb, offset + 4)); } offset += 6; @@ -1678,29 +1709,29 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd, if (tree) { /* To do : decode options */ /* - proto_tree_add_text(clnp_tree, NullTVB, offset, - clnp.cnf_hdr_len + first_offset - offset, + proto_tree_add_text(clnp_tree, tvb, offset, + cnf_hdr_len - offset, "Options/Data: <not shown>"); */ /* QUICK HACK Option Len:= PDU_Hd_length-( FixedPart+AddresPart+SegmentPart )*/ dissect_osi_options( 0xff, opt_len, - pd, offset, fd, clnp_tree ); + tvb, offset, pinfo, clnp_tree ); } /* Length of CLNP datagram plus headers above it. */ - len = segment_length + first_offset; + len = segment_length; /* Set the payload and captured-payload lengths to the minima of (the datagram length plus the length of the headers above it) and the frame lengths. */ - if (pi.len > len) - pi.len = len; - if (pi.captured_len > len) - pi.captured_len = len; + if (pinfo->len > len) + pinfo->len = len; + if (pinfo->captured_len > len) + pinfo->captured_len = len; - offset = first_offset + clnp.cnf_hdr_len; + offset = cnf_hdr_len; /* For now, dissect the payload of segments other than the initial segment as data, rather than handing them off to the transport @@ -1708,16 +1739,16 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd, fragment in a fragmented IP datagram; in the future, we will probably reassemble fragments for IP, and may reassemble segments for CLNP. */ - if ((clnp.cnf_type & CNF_SEG_OK) && segment_offset != 0) { - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Fragmented %s NPDU %s(off=%u)", + if ((cnf_type & CNF_SEG_OK) && segment_offset != 0) { + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "Fragmented %s NPDU %s(off=%u)", pdu_type_string, flag_string, segment_offset); - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, offset, pinfo, tree); return; } - if (IS_DATA_IN_FRAME(offset)) { - switch (clnp.cnf_type & CNF_TYPE) { + if (tvb_offset_exists(tvb, offset)) { + switch (cnf_type & CNF_TYPE) { case DT_NPDU: case MD_NPDU: @@ -1726,7 +1757,8 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd, PDU, skip that? */ if (nsel == (char)tp_nsap_selector || always_decode_transport) { - if (dissect_ositp_internal(pd, offset, fd, tree, FALSE)) + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + if (dissect_ositp_internal(next_tvb, pinfo, tree, FALSE)) return; /* yes, it appears to be COTP or CLTP */ } break; @@ -1745,9 +1777,10 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd, break; } } - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string); - old_dissect_data(pd, offset, fd, tree); + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string); + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + dissect_data(next_tvb, 0, pinfo, tree); } /* dissect_clnp */ @@ -1847,6 +1880,6 @@ void proto_register_cltp(void) void proto_reg_handoff_clnp(void) { - old_dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp); - old_dissector_add("osinl", NLPID_NULL, dissect_clnp); /* Inactive subset */ + dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp); + dissector_add("osinl", NLPID_NULL, dissect_clnp); /* Inactive subset */ } diff --git a/packet-clnp.h b/packet-clnp.h index 2aee4c4569..f468828611 100644 --- a/packet-clnp.h +++ b/packet-clnp.h @@ -1,7 +1,7 @@ /* packet-clnp.h * Defines and such for CLNP (and COTP) protocol decode. * - * $Id: packet-clnp.h,v 1.3 2000/07/01 08:55:27 guy Exp $ + * $Id: packet-clnp.h,v 1.4 2000/11/18 10:38:24 guy Exp $ * Ralf Schneider <Ralf.Schneider@t-online.de> * * Ethereal - Network traffic analyzer @@ -34,6 +34,6 @@ */ extern -void dissect_ositp(const u_char *, int, frame_data *, proto_tree *); +void dissect_ositp(tvbuff_t *, packet_info *, proto_tree *); #endif /* _PACKET_CLNP_H */ diff --git a/packet-esis.c b/packet-esis.c index b38450313c..f6d47733ad 100644 --- a/packet-esis.c +++ b/packet-esis.c @@ -2,7 +2,7 @@ * Routines for ISO/OSI End System to Intermediate System * Routeing Exchange Protocol ISO 9542. * - * $Id: packet-esis.c,v 1.7 2000/08/13 14:08:09 deniel Exp $ + * $Id: packet-esis.c,v 1.8 2000/11/18 10:38:24 guy Exp $ * Ralf Schneider <Ralf.Schneider@t-online.de> * * Ethereal - Network traffic analyzer @@ -67,12 +67,12 @@ static const value_string esis_vals[] = { /* internal prototypes */ -void esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *treepd); -void esis_dissect_ish_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *tree); -void esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *tree); +static void esis_dissect_esh_pdu( u_char len, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *treepd); +static void esis_dissect_ish_pdu( u_char len, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree); +static void esis_dissect_redirect_pdu( u_char len, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree); /* ################## Descriptions ###########################################*/ /* Parameters for the ESH PDU @@ -146,35 +146,22 @@ void esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset, * Output: * void (may modify proto tree) */ -void -esis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd, - char *fmat, ...){ +static void +esis_dissect_unknown( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + char *fmat, ...){ va_list ap; - if ( !IS_DATA_IN_FRAME(offset) ) { - /* - * big oops They were off the end of the packet already. - * Just ignore this one. - */ - return; - } - if ( !BYTES_ARE_IN_FRAME(offset, length) ) { - /* - * length will take us past eop. Truncate length. - */ - length = END_OF_FRAME; - } - va_start(ap, fmat); - proto_tree_add_text_valist(tree, NullTVB, offset, length, fmat, ap); + proto_tree_add_text_valist(tree, tvb, 0, tvb_length(tvb), fmat, ap); va_end(ap); } -void -esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) { +static void +esis_dissect_esh_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree) { proto_tree *esis_area_tree; + int offset = 0; int no_sa = 0; int sal = 0; @@ -183,91 +170,100 @@ esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset, if (tree) { offset += ESIS_HDR_FIXED_LENGTH; - no_sa = pd[offset]; + no_sa = tvb_get_guint8(tvb, offset); len -= 1; - ti = proto_tree_add_text( tree, NullTVB, offset++, END_OF_FRAME, + ti = proto_tree_add_text( tree, tvb, offset, tvb_length_remaining(tvb, offset), "Number of Source Addresses (SA, Format: NSAP) : %u", no_sa ); + offset++; esis_area_tree = proto_item_add_subtree( ti, ett_esis_area_addr ); while ( no_sa-- > 0 ) { - sal = (int) pd[offset++]; - proto_tree_add_text(esis_area_tree, NullTVB, offset, 1, "SAL: %2u Octets", sal); - proto_tree_add_text(esis_area_tree, NullTVB, offset + 1, sal, - " SA: %s", print_nsap_net( &pd[offset], sal ) ); + sal = (int) tvb_get_guint8(tvb, offset); + offset++; + proto_tree_add_text(esis_area_tree, tvb, offset, 1, "SAL: %2u Octets", sal); + proto_tree_add_text(esis_area_tree, tvb, offset + 1, sal, + " SA: %s", + print_nsap_net( tvb_get_ptr(tvb, offset, sal), sal ) ); offset += sal; len -= ( sal + 1 ); } - dissect_osi_options( PDU_TYPE_ESIS_ESH, len, pd, offset, fd, tree ); + dissect_osi_options( PDU_TYPE_ESIS_ESH, len, tvb, offset, pinfo, tree ); } } /* esis_dissect_esh_pdu */ ; -void -esis_dissect_ish_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) { +static void +esis_dissect_ish_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree) { + int offset = 0; int netl = 0; if (tree) { offset += ESIS_HDR_FIXED_LENGTH; - netl = (int) pd[ offset ]; - proto_tree_add_text( tree, NullTVB, offset, netl + 1, + netl = (int) tvb_get_guint8(tvb, offset); + proto_tree_add_text( tree, tvb, offset, netl + 1, "### Network Entity Titel Section ###"); - proto_tree_add_text( tree, NullTVB, offset++, 1, "NETL: %2u Octets", netl); - proto_tree_add_text( tree, NullTVB, offset, netl, - " NET: %s", print_nsap_net( &pd[offset], netl ) ); + proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", netl); + proto_tree_add_text( tree, tvb, offset, netl, + " NET: %s", + print_nsap_net( tvb_get_ptr(tvb, offset, netl), netl ) ); offset += netl; len -= ( netl + 1 ); - dissect_osi_options( PDU_TYPE_ESIS_ISH, len, pd, offset, fd, tree ); + dissect_osi_options( PDU_TYPE_ESIS_ISH, len, tvb, offset, pinfo, tree ); } }; -void -esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset, - frame_data *fd, proto_tree *tree) { +static void +esis_dissect_redirect_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree) { + int offset = 0; int tmpl = 0; if (tree) { offset += ESIS_HDR_FIXED_LENGTH; - tmpl = (int) pd[ offset ]; - proto_tree_add_text( tree, NullTVB, offset, tmpl + 1, + tmpl = (int) tvb_get_guint8(tvb, offset); + proto_tree_add_text( tree, tvb, offset, tmpl + 1, "### Destination Address Section ###" ); - proto_tree_add_text( tree, NullTVB, offset++, 1, "DAL: %2u Octets", tmpl); - proto_tree_add_text( tree, NullTVB, offset, tmpl, - " DA : %s", print_nsap_net( &pd[offset], tmpl ) ); + proto_tree_add_text( tree, tvb, offset++, 1, "DAL: %2u Octets", tmpl); + proto_tree_add_text( tree, tvb, offset, tmpl, + " DA : %s", + print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); - tmpl = (int) pd[ offset ]; + tmpl = (int) tvb_get_guint8(tvb, offset); - proto_tree_add_text( tree, NullTVB, offset, tmpl + 1, + proto_tree_add_text( tree, tvb, offset, tmpl + 1, "### Subnetwork Address Section ###"); - proto_tree_add_text( tree, NullTVB, offset++, 1, "BSNPAL: %2u Octets", tmpl); - proto_tree_add_text( tree, NullTVB, offset, tmpl, - " BSNPA: %s", print_system_id( &pd[offset], tmpl ) ); + proto_tree_add_text( tree, tvb, offset++, 1, "BSNPAL: %2u Octets", tmpl); + proto_tree_add_text( tree, tvb, offset, tmpl, + " BSNPA: %s", + print_system_id( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); - tmpl = (int) pd[ offset ]; + tmpl = (int) tvb_get_guint8(tvb, offset); if ( 0 == tmpl ) { - proto_tree_add_text( tree, NullTVB, offset, 1, + proto_tree_add_text( tree, tvb, offset, 1, "### No Network Entity Title Section ###" ); offset++; len--; } else { - proto_tree_add_text( tree, NullTVB, offset, 1, + proto_tree_add_text( tree, tvb, offset, 1, "### Network Entity Title Section ###" ); - proto_tree_add_text( tree, NullTVB, offset++, 1, "NETL: %2u Octets", tmpl ); - proto_tree_add_text( tree, NullTVB, offset, tmpl, - " NET: %s", print_nsap_net( &pd[offset], tmpl ) ); + proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", tmpl ); + proto_tree_add_text( tree, tvb, offset, tmpl, + " NET: %s", + print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); } - dissect_osi_options( PDU_TYPE_ESIS_RD, len, pd, offset, fd, tree ); + dissect_osi_options( PDU_TYPE_ESIS_RD, len, tvb, offset, pinfo, tree ); } } @@ -280,9 +276,7 @@ esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset, * main esis tree data and call the sub-protocols as needed. * * Input: - * u_char * : packet data - * int : offset into packet where we are (packet_data[offset]== start - * of what we care about) + * tvbuff * : tvbuff referring to packet data * frame_data * : frame data (whole packet with extra info) * proto_tree * : tree of display data. May be NULL. * @@ -290,70 +284,65 @@ esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset, * void, but we will add to the proto_tree if it is not NULL. */ static void -dissect_esis(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { +dissect_esis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char *pdu_type_string = NULL; char *pdu_type_format_string = "PDU Type : %s (R:%s%s%s)"; - esis_hdr_t *ehdr; + esis_hdr_t ehdr; proto_item *ti; proto_tree *esis_tree = NULL; int variable_len = 0; u_int tmp_uint = 0; - OLD_CHECK_DISPLAY_AS_DATA(proto_esis, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_esis, tvb, pinfo, tree); - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "ESIS"); + pinfo->current_proto = "ESIS"; - if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ehdr))) { - esis_dissect_unknown(offset, sizeof(*ehdr), tree, fd, - "Not enough capture data for header (%d vs %d)", - sizeof(*ehdr), END_OF_FRAME); - return; - } + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "ESIS"); - ehdr = (esis_hdr_t *) &pd[offset]; + tvb_memcpy(tvb, (guint8 *)&ehdr, 0, sizeof ehdr); - if (ehdr->esis_version != ESIS_REQUIRED_VERSION){ - esis_dissect_unknown(offset, END_OF_FRAME, tree, fd, - "Unknown ESIS version (%d vs %d)", - ehdr->esis_version, ESIS_REQUIRED_VERSION ); - return; - } - if (tree) { - ti = proto_tree_add_item(tree, proto_esis, NullTVB, offset, END_OF_FRAME, FALSE); + ti = proto_tree_add_item(tree, proto_esis, tvb, 0, tvb_length(tvb), FALSE); esis_tree = proto_item_add_subtree(ti, ett_esis); - proto_tree_add_uint( esis_tree, hf_esis_nlpi, NullTVB, offset, 1, ehdr->esis_nlpi ); - proto_tree_add_uint( esis_tree, hf_esis_length, NullTVB, - offset + 1, 1, ehdr->esis_length ); - proto_tree_add_uint( esis_tree, hf_esis_version, NullTVB, offset + 2, 1, - ehdr->esis_version ); - proto_tree_add_uint( esis_tree, hf_esis_reserved, NullTVB, offset + 3, 1, - ehdr->esis_reserved ); - - pdu_type_string = val_to_str(ehdr->esis_type&OSI_PDU_TYPE_MASK, + if (ehdr.esis_version != ESIS_REQUIRED_VERSION){ + esis_dissect_unknown(tvb, pinfo, esis_tree, + "Unknown ESIS version (%u vs %u)", + ehdr.esis_version, ESIS_REQUIRED_VERSION ); + return; + } + + proto_tree_add_uint( esis_tree, hf_esis_nlpi, tvb, 0, 1, ehdr.esis_nlpi ); + proto_tree_add_uint( esis_tree, hf_esis_length, tvb, + 1, 1, ehdr.esis_length ); + proto_tree_add_uint( esis_tree, hf_esis_version, tvb, 2, 1, + ehdr.esis_version ); + proto_tree_add_uint( esis_tree, hf_esis_reserved, tvb, 3, 1, + ehdr.esis_reserved ); + + pdu_type_string = val_to_str(ehdr.esis_type&OSI_PDU_TYPE_MASK, esis_vals, "Unknown (0x%x)"); - proto_tree_add_uint_format( esis_tree, hf_esis_type, NullTVB, offset + 4, 1, - ehdr->esis_type, + proto_tree_add_uint_format( esis_tree, hf_esis_type, tvb, 4, 1, + ehdr.esis_type, pdu_type_format_string, pdu_type_string, - (ehdr->esis_type&BIT_8) ? "1" : "0", - (ehdr->esis_type&BIT_7) ? "1" : "0", - (ehdr->esis_type&BIT_6) ? "1" : "0"); + (ehdr.esis_type&BIT_8) ? "1" : "0", + (ehdr.esis_type&BIT_7) ? "1" : "0", + (ehdr.esis_type&BIT_6) ? "1" : "0"); - tmp_uint = pntohs( ehdr->esis_holdtime ); - proto_tree_add_uint_format(esis_tree, hf_esis_holdtime, NullTVB, offset + 5, 2, + tmp_uint = pntohs( ehdr.esis_holdtime ); + proto_tree_add_uint_format(esis_tree, hf_esis_holdtime, tvb, 5, 2, tmp_uint, "Holding Time : %u seconds", tmp_uint ); - tmp_uint = pntohs( ehdr->esis_checksum ); + tmp_uint = pntohs( ehdr.esis_checksum ); - proto_tree_add_uint_format( esis_tree, hf_esis_checksum, NullTVB, offset + 7, 2, + proto_tree_add_uint_format( esis_tree, hf_esis_checksum, tvb, 7, 2, tmp_uint, "Checksum : 0x%x ( %s )", - tmp_uint, calc_checksum( &pd[offset], - ehdr->esis_length , + tmp_uint, calc_checksum( tvb, 0, + ehdr.esis_length , tmp_uint ) ); } @@ -363,34 +352,35 @@ dissect_esis(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { * here. First, dump the name into info column, and THEN * dispatch the sub-type. */ - if (check_col(fd, COL_INFO)) { - col_add_str(fd, COL_INFO, - val_to_str( ehdr->esis_type&OSI_PDU_TYPE_MASK, esis_vals, + if (check_col(pinfo->fd, COL_INFO)) { + col_add_str(pinfo->fd, COL_INFO, + val_to_str( ehdr.esis_type&OSI_PDU_TYPE_MASK, esis_vals, "Unknown (0x%x)" ) ); } - variable_len = ehdr->esis_length - ESIS_HDR_FIXED_LENGTH; + variable_len = ehdr.esis_length - ESIS_HDR_FIXED_LENGTH; - switch (ehdr->esis_type) { + switch (ehdr.esis_type & OSI_PDU_TYPE_MASK) { case ESIS_ESH_PDU: - esis_dissect_esh_pdu( variable_len, pd, offset, fd, esis_tree); + esis_dissect_esh_pdu( variable_len, tvb, pinfo, esis_tree); break; case ESIS_ISH_PDU: - esis_dissect_ish_pdu( variable_len, pd, offset, fd, esis_tree); + esis_dissect_ish_pdu( variable_len, tvb, pinfo, esis_tree); break; case ESIS_RD_PDU: - esis_dissect_redirect_pdu( variable_len, pd, offset, fd, + esis_dissect_redirect_pdu( variable_len, tvb, pinfo, esis_tree); break; default: - esis_dissect_unknown(offset, END_OF_FRAME, tree, fd, - "unknown esis packet type" ); + esis_dissect_unknown(tvb, pinfo, esis_tree, + "Unknown ESIS packet type 0x%x", + ehdr.esis_type & OSI_PDU_TYPE_MASK ); } } /* dissect_esis */ /* - * Name: proto_register_esisesis() + * Name: proto_register_esis() * * Description: * main register for esis protocol set. We register some display @@ -442,5 +432,5 @@ proto_register_esis(void) { void proto_reg_handoff_esis(void) { - old_dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis); + dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis); } diff --git a/packet-esis.h b/packet-esis.h index cc145b7d7b..e60276be92 100644 --- a/packet-esis.h +++ b/packet-esis.h @@ -1,7 +1,7 @@ /* packet-esis.h * Defines and such for ESIS protocol decode. * - * $Id: packet-esis.h,v 1.2 2000/04/17 01:36:30 guy Exp $ + * $Id: packet-esis.h,v 1.3 2000/11/18 10:38:24 guy Exp $ * Ralf Schneider <Ralf.Schneider@t-online.de> * * Ethereal - Network traffic analyzer @@ -57,10 +57,4 @@ typedef struct { guint8 esis_checksum[2]; /* Computed on whole PDU Header, 0 means ignore */ } esis_hdr_t; -/* - * published API functions - */ -extern void esis_dissect_unknown(int offset,guint length, proto_tree *tree, - frame_data *fd, char *fmat, ...); - #endif /* _PACKET_ESIS_H */ diff --git a/packet-eth.c b/packet-eth.c index 1f343ed732..1c0b1c0fcf 100644 --- a/packet-eth.c +++ b/packet-eth.c @@ -1,7 +1,7 @@ /* packet-eth.c * Routines for ethernet packet disassembly * - * $Id: packet-eth.c,v 1.46 2000/11/13 05:28:00 guy Exp $ + * $Id: packet-eth.c,v 1.47 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -153,6 +153,7 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvbuff_t *volatile next_tvb; tvbuff_t *volatile trailer_tvb; proto_tree *volatile fh_tree; + guint length_before; CHECK_DISPLAY_AS_DATA(proto_eth, tvb, pinfo, tree); @@ -235,10 +236,10 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) and set the payload and captured-payload lengths to the minima of the total length and the frame lengths. */ length += eth_offset + ETH_HEADER_SIZE; - if (pi.len > length) - pi.len = length; - if (pi.captured_len > length) - pi.captured_len = length; + if (pinfo->len > length) + pinfo->len = length; + if (pinfo->captured_len > length) + pinfo->captured_len = length; } else { ethhdr_type = ETHERNET_II; if (check_col(pinfo->fd, COL_INFO)) @@ -259,32 +260,32 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } eth_offset += ETH_HEADER_SIZE; - /* Give the next dissector only 'length' number of bytes */ if (etype <= IEEE_802_3_MAX_LEN) { + /* Give the next dissector only 'length' number of bytes */ TRY { - next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, etype, etype); - trailer_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE + etype, -1, -1); + next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, etype, etype); + trailer_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE + etype, -1, -1); } CATCH2(BoundsError, ReportedBoundsError) { - /* Either: + /* Either: - the packet doesn't have "etype" bytes worth of - captured data left in it - or it may not even have - "etype" bytes worth of data in it, period - - so the "tvb_new_subset()" creating "next_tvb" - threw an exception + the packet doesn't have "etype" bytes worth of + captured data left in it - or it may not even have + "etype" bytes worth of data in it, period - + so the "tvb_new_subset()" creating "next_tvb" + threw an exception - or + or - the packet has exactly "etype" bytes worth of - captured data left in it, so the "tvb_new_subset()" - creating "trailer_tvb" threw an exception. + the packet has exactly "etype" bytes worth of + captured data left in it, so the "tvb_new_subset()" + creating "trailer_tvb" threw an exception. - In either case, this means that all the data in the frame - is within the length value, so we give all the data to the - next protocol and have no trailer. */ - next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, etype); - trailer_tvb = NULL; + In either case, this means that all the data in the frame + is within the length value, so we give all the data to the + next protocol and have no trailer. */ + next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, etype); + trailer_tvb = NULL; } ENDTRY; } @@ -301,20 +302,34 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) dissect_llc(next_tvb, pinfo, tree); break; case ETHERNET_II: - ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type); + length_before = tvb_reported_length(tvb); + length = ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, + hf_eth_type) + ETH_HEADER_SIZE; + if (length < length_before) { + /* + * Create a tvbuff for the padding. + */ + TRY { + trailer_tvb = tvb_new_subset(tvb, length, -1, -1); + } + CATCH2(BoundsError, ReportedBoundsError) { + /* The packet doesn't have "length" bytes worth of captured + data left in it. No trailer to display. */ + trailer_tvb = NULL; + } + ENDTRY; + } break; } /* If there's some bytes left over, mark them. */ if (trailer_tvb && tree) { - int trailer_length; - const guint8 *ptr; + guint trailer_length; trailer_length = tvb_length(trailer_tvb); - if (trailer_length > 0) { - ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length); - proto_tree_add_bytes(fh_tree, hf_eth_trailer, tvb, ETH_HEADER_SIZE + etype, - trailer_length, ptr); + if (trailer_length != 0) { + proto_tree_add_item(fh_tree, hf_eth_trailer, trailer_tvb, 0, + trailer_length, FALSE); } } diff --git a/packet-ethertype.c b/packet-ethertype.c index 3ffcd0e2c3..454c58fbfa 100644 --- a/packet-ethertype.c +++ b/packet-ethertype.c @@ -1,7 +1,7 @@ /* ethertype.c * Routines for calling the right protocol for the ethertype. * - * $Id: packet-ethertype.c,v 1.8 2000/11/16 07:35:37 guy Exp $ + * $Id: packet-ethertype.c,v 1.9 2000/11/18 10:38:24 guy Exp $ * * Gilbert Ramirez <gram@xiexie.org> * @@ -95,7 +95,7 @@ capture_ethertype(guint16 etype, int offset, } } -void +guint ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int item_id) { @@ -107,6 +107,7 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pin proto_tree_add_uint(fh_tree, item_id, tvb, offset_after_etype - 2, 2, etype); } + /* Tvbuff for the payload after the Ethernet type. */ next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1); /* Look for sub-dissector */ @@ -137,6 +138,11 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pin } } } + + /* Return the length of that tvbuff; the subdissector may have + reduced the length to a value specified by a length field + in its header, meaning what remains is padding. */ + return tvb_reported_length(next_tvb); } diff --git a/packet-gre.c b/packet-gre.c index 2af23462a8..bcfc58b269 100644 --- a/packet-gre.c +++ b/packet-gre.c @@ -2,7 +2,7 @@ * Routines for the Generic Routing Encapsulation (GRE) protocol * Brad Robel-Forrest <brad.robel-forrest@watchguard.com> * - * $Id: packet-gre.c,v 1.26 2000/11/16 07:35:37 guy Exp $ + * $Id: packet-gre.c,v 1.27 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -74,6 +74,8 @@ static const value_string typevals[] = { { 0, NULL } }; +static dissector_handle_t ip_handle; + static void dissect_gre(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { @@ -212,14 +214,14 @@ dissect_gre(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { dissect_ppp(next_tvb, &pi, tree); break; case GRE_IP: - dissect_ip(pd, offset, fd, tree); + old_call_dissector(ip_handle, pd, offset, fd, tree); break; case GRE_WCCP: if (is_wccp2) { proto_tree_add_text(gre_tree, NullTVB, offset, sizeof(guint32), "WCCPv2 Data"); offset += 4; } - dissect_ip(pd, offset, fd, tree); + old_call_dissector(ip_handle, pd, offset, fd, tree); break; case GRE_IPX: next_tvb = tvb_create_from_top(offset); @@ -304,4 +306,9 @@ void proto_reg_handoff_gre(void) { old_dissector_add("ip.proto", IP_PROTO_GRE, dissect_gre); + + /* + * Get a handle for the IP dissector. + */ + ip_handle = find_dissector("ip"); } diff --git a/packet-ip.c b/packet-ip.c index 324c9b710c..20f3fed865 100644 --- a/packet-ip.c +++ b/packet-ip.c @@ -1,7 +1,7 @@ /* packet-ip.c * Routines for IP and miscellaneous IP protocol packet disassembly * - * $Id: packet-ip.c,v 1.105 2000/11/17 06:02:20 guy Exp $ + * $Id: packet-ip.c,v 1.106 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -53,7 +53,7 @@ #include "packet-ip.h" #include "packet-ipsec.h" -static void dissect_icmp(const u_char *, int, frame_data *, proto_tree *); +static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *); static void dissect_igmp(tvbuff_t *, packet_info *, proto_tree *); /* Decode the old IPv4 TOS field as the DiffServ DS Field */ @@ -113,27 +113,7 @@ static int hf_icmp_checksum = -1; static gint ett_icmp = -1; -/* ICMP structs and definitions */ -typedef struct _e_icmp { - guint8 icmp_type; - guint8 icmp_code; - guint16 icmp_cksum; - union { - struct { /* Address mask request/reply */ - guint16 id; - guint16 seq; - guint32 sn_mask; - } am; - struct { /* Timestap request/reply */ - guint16 id; - guint16 seq; - guint32 orig; - guint32 recv; - guint32 xmit; - } ts; - guint32 zero; /* Unreachable */ - } opt; -} e_icmp; +/* ICMP definitions */ #define ICMP_ECHOREPLY 0 #define ICMP_UNREACH 3 @@ -358,7 +338,7 @@ capture_ip(const u_char *pd, int offset, packet_counts *ld) { } static void -dissect_ipopt_security(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { proto_tree *field_tree = NULL; @@ -382,33 +362,35 @@ dissect_ipopt_security(const ip_tcp_opt *optp, const u_char *opd, int offset, {IPSEC_RESERVED8, "Reserved" }, {0, NULL } }; - tf = proto_tree_add_text(opt_tree, NullTVB, offset, optlen, "%s:", optp->name); + tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; - val = pntohs(opd); - proto_tree_add_text(field_tree, NullTVB, offset, 2, + val = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 2, "Security: %s", val_to_str(val, secl_vals, "Unknown (0x%x)")); offset += 2; - opd += 2; - val = pntohs(opd); - proto_tree_add_text(field_tree, NullTVB, offset, 2, + val = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 2, "Compartments: %u", val); offset += 2; - opd += 2; - proto_tree_add_text(field_tree, NullTVB, offset, 2, - "Handling restrictions: %c%c", opd[0], opd[1]); + proto_tree_add_text(field_tree, tvb, offset, 2, + "Handling restrictions: %c%c", + tvb_get_guint8(tvb, offset), + tvb_get_guint8(tvb, offset + 1)); offset += 2; - opd += 2; - proto_tree_add_text(field_tree, NullTVB, offset, 3, - "Transmission control code: %c%c%c", opd[0], opd[1], opd[2]); + proto_tree_add_text(field_tree, tvb, offset, 3, + "Transmission control code: %c%c%c", + tvb_get_guint8(tvb, offset), + tvb_get_guint8(tvb, offset + 1), + tvb_get_guint8(tvb, offset + 2)); } static void -dissect_ipopt_route(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { proto_tree *field_tree = NULL; @@ -417,54 +399,52 @@ dissect_ipopt_route(const ip_tcp_opt *optp, const u_char *opd, int offset, int optoffset = 0; struct in_addr addr; - tf = proto_tree_add_text(opt_tree, NullTVB, offset, optlen, "%s (%u bytes)", + tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s (%u bytes)", optp->name, optlen); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); optoffset += 2; /* skip past type and length */ optlen -= 2; /* subtract size of type and length */ - ptr = *opd; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1, + ptr = tvb_get_guint8(tvb, offset + optoffset); + proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Pointer: %d%s", ptr, ((ptr < 4) ? " (points before first address)" : ((ptr & 3) ? " (points to middle of address)" : ""))); optoffset++; - opd++; optlen--; ptr--; /* ptr is 1-origin */ while (optlen > 0) { if (optlen < 4) { - proto_tree_add_text(field_tree, NullTVB, offset, optlen, + proto_tree_add_text(field_tree, tvb, offset, optlen, "(suboption would go past end of option)"); break; } /* Avoids alignment problems on many architectures. */ - memcpy((char *)&addr, (char *)opd, sizeof(addr)); + tvb_memcpy(tvb, (guint8 *)&addr, offset + optoffset, sizeof(addr)); - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 4, + proto_tree_add_text(field_tree, tvb, offset + optoffset, 4, "%s%s", ((addr.s_addr == 0) ? "-" : (char *)get_hostname(addr.s_addr)), ((optoffset == ptr) ? " <- (current)" : "")); optoffset += 4; - opd += 4; optlen -= 4; } } static void -dissect_ipopt_sid(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: %d", optp->name, pntohs(opd)); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: %u", optp->name, tvb_get_ntohs(tvb, offset + 2)); return; } static void -dissect_ipopt_timestamp(const ip_tcp_opt *optp, const u_char *opd, +dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { proto_tree *field_tree = NULL; @@ -480,61 +460,54 @@ dissect_ipopt_timestamp(const ip_tcp_opt *optp, const u_char *opd, struct in_addr addr; guint ts; - tf = proto_tree_add_text(opt_tree, NullTVB, offset, optlen, "%s:", optp->name); + tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); optoffset += 2; /* skip past type and length */ optlen -= 2; /* subtract size of type and length */ - ptr = *opd; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1, + ptr = tvb_get_guint8(tvb, offset + optoffset); + proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Pointer: %d%s", ptr, ((ptr < 5) ? " (points before first address)" : (((ptr - 1) & 3) ? " (points to middle of address)" : ""))); optoffset++; - opd++; optlen--; ptr--; /* ptr is 1-origin */ - flg = *opd; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1, - "Overflow: %d", flg >> 4); + flg = tvb_get_guint8(tvb, offset + optoffset); + proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, + "Overflow: %u", flg >> 4); flg &= 0xF; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1, + proto_tree_add_text(field_tree, tvb, offset + optoffset, 1, "Flag: %s", val_to_str(flg, flag_vals, "Unknown (0x%x)")); optoffset++; - opd++; optlen--; while (optlen > 0) { if (flg == IPOPT_TS_TSANDADDR) { - /* XXX - check whether it goes past end of packet */ if (optlen < 8) { - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, optlen, + proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen, "(suboption would go past end of option)"); break; } - memcpy((char *)&addr, (char *)opd, sizeof(addr)); - opd += 4; - ts = pntohl(opd); - opd += 4; + tvb_memcpy(tvb, (char *)&addr, offset + optoffset, sizeof(addr)); + ts = tvb_get_ntohl(tvb, offset + optoffset + 4); optlen -= 8; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 8, + proto_tree_add_text(field_tree, tvb, offset + optoffset, 8, "Address = %s, time stamp = %u", ((addr.s_addr == 0) ? "-" : (char *)get_hostname(addr.s_addr)), ts); optoffset += 8; } else { if (optlen < 4) { - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, optlen, + proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen, "(suboption would go past end of option)"); break; } - /* XXX - check whether it goes past end of packet */ - ts = pntohl(opd); - opd += 4; + ts = tvb_get_ntohl(tvb, offset + optoffset); optlen -= 4; - proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 4, + proto_tree_add_text(field_tree, tvb, offset + optoffset, 4, "Time stamp = %u", ts); optoffset += 4; } @@ -612,7 +585,7 @@ static const ip_tcp_opt ipopts[] = { /* Dissect the IP or TCP options in a packet. */ void -dissect_ip_tcp_options(const u_char *opd, int offset, guint length, +dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length, const ip_tcp_opt *opttab, int nopts, int eol, proto_tree *opt_tree) { @@ -622,12 +595,12 @@ dissect_ip_tcp_options(const u_char *opd, int offset, guint length, int optlen; char *name; char name_str[7+1+1+2+2+1+1]; /* "Unknown (0x%02x)" */ - void (*dissect)(const struct ip_tcp_opt *, const u_char *, + void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *, int, guint, proto_tree *); guint len; while (length > 0) { - opt = *opd++; + opt = tvb_get_guint8(tvb, offset); for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) { if (optp->optcode == opt) break; @@ -655,59 +628,58 @@ dissect_ip_tcp_options(const u_char *opd, int offset, guint length, if (length == 0) { /* Bogus - packet must at least include option code byte and length byte! */ - proto_tree_add_text(opt_tree, NullTVB, offset, 1, + proto_tree_add_text(opt_tree, tvb, offset, 1, "%s (length byte past end of options)", name); return; } - len = *opd++; /* total including type, len */ + len = tvb_get_guint8(tvb, offset + 1); /* total including type, len */ --length; /* account for length byte */ if (len < 2) { /* Bogus - option length is too short to include option code and option length. */ - proto_tree_add_text(opt_tree, NullTVB, offset, 2, + proto_tree_add_text(opt_tree, tvb, offset, 2, "%s (with too-short option length = %u byte%s)", name, len, plurality(len, "", "s")); return; } else if (len - 2 > length) { /* Bogus - option goes past the end of the header. */ - proto_tree_add_text(opt_tree, NullTVB, offset, length, + proto_tree_add_text(opt_tree, tvb, offset, length, "%s (option length = %u byte%s says option goes past end of options)", name, len, plurality(len, "", "s")); return; } else if (len_type == FIXED_LENGTH && len != optlen) { /* Bogus - option length isn't what it's supposed to be for this option. */ - proto_tree_add_text(opt_tree, NullTVB, offset, len, + proto_tree_add_text(opt_tree, tvb, offset, len, "%s (with option length = %u byte%s; should be %u)", name, len, plurality(len, "", "s"), optlen); return; } else if (len_type == VARIABLE_LENGTH && len < optlen) { /* Bogus - option length is less than what it's supposed to be for this option. */ - proto_tree_add_text(opt_tree, NullTVB, offset, len, + proto_tree_add_text(opt_tree, tvb, offset, len, "%s (with option length = %u byte%s; should be >= %u)", name, len, plurality(len, "", "s"), optlen); return; } else { if (optp == NULL) { - proto_tree_add_text(opt_tree, NullTVB, offset, len, "%s (%u byte%s)", + proto_tree_add_text(opt_tree, tvb, offset, len, "%s (%u byte%s)", name, len, plurality(len, "", "s")); } else { if (dissect != NULL) { /* Option has a dissector. */ - (*dissect)(optp, opd, offset, len, opt_tree); + (*dissect)(optp, tvb, offset, len, opt_tree); } else { /* Option has no data, hence no dissector. */ - proto_tree_add_text(opt_tree, NullTVB, offset, len, "%s", name); + proto_tree_add_text(opt_tree, tvb, offset, len, "%s", name); } } len -= 2; /* subtract size of type and length */ offset += 2 + len; } - opd += len; length -= len; } else { - proto_tree_add_text(opt_tree, NullTVB, offset, 1, "%s", name); + proto_tree_add_text(opt_tree, tvb, offset, 1, "%s", name); offset += 1; } if (opt == eol) @@ -823,148 +795,171 @@ static guint16 ip_checksum_shouldbe(guint16 sum, guint16 computed_sum) } void -dissect_ip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { +dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ e_ip iph; proto_tree *ip_tree, *field_tree; proto_item *ti, *tf; - guint hlen, optlen, len; + int offset = 0; + guint hlen, optlen, len, payload_len, reported_payload_len, padding; guint16 flags; guint8 nxt; guint16 ipsum; + tvbuff_t *next_tvb; - OLD_CHECK_DISPLAY_AS_DATA(proto_ip, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_ip, tvb, pinfo, tree); - /* To do: check for errs, etc. */ - if (!BYTES_ARE_IN_FRAME(offset, IPH_MIN_LEN)) { - old_dissect_data(pd, offset, fd, tree); - return; - } + pinfo->current_proto = "IP"; /* Avoids alignment problems on many architectures. */ - memcpy(&iph, &pd[offset], sizeof(e_ip)); + tvb_memcpy(tvb, (guint8 *)&iph, offset, sizeof(e_ip)); iph.ip_len = ntohs(iph.ip_len); iph.ip_id = ntohs(iph.ip_id); iph.ip_off = ntohs(iph.ip_off); iph.ip_sum = ntohs(iph.ip_sum); - /* Length of IP datagram plus headers above it. */ - len = iph.ip_len + offset; - - /* Set the payload and captured-payload lengths to the minima of (the - IP length plus the length of the headers above it) and the frame - lengths. */ - if (pi.len > len) - pi.len = len; - if (pi.captured_len > len) - pi.captured_len = len; + /* Length of payload handed to us. */ + reported_payload_len = tvb_reported_length(tvb); + payload_len = tvb_length(tvb); + + /* Length of IP datagram. */ + len = iph.ip_len; + + if (len < reported_payload_len) { + /* Adjust the length of this tvbuff to include only the IP datagram. + Our caller may use that to determine how much of its packet + was padding. */ + tvb_set_reported_length(tvb, len); + + /* Shrink the total payload by the amount of padding. */ + padding = reported_payload_len - len; + if (pinfo->len >= padding) + pinfo->len -= padding; + + /* Shrink the captured payload by the amount of padding in the + captured payload (which may be less than the amount of padding, + as the padding may not have been captured). */ + if (len < payload_len) { + padding = payload_len - len; + if (pinfo->captured_len >= padding) + pinfo->captured_len -= padding; + } + } /* XXX - check to make sure this is at least IPH_MIN_LEN. */ hlen = lo_nibble(iph.ip_v_hl) * 4; /* IP header length, in bytes */ if (tree) { - ti = proto_tree_add_item(tree, proto_ip, NullTVB, offset, hlen, FALSE); + ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, FALSE); ip_tree = proto_item_add_subtree(ti, ett_ip); - proto_tree_add_uint(ip_tree, hf_ip_version, NullTVB, offset, 1, hi_nibble(iph.ip_v_hl)); - proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, NullTVB, offset, 1, hlen, + proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1, hi_nibble(iph.ip_v_hl)); + proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen, "Header length: %u bytes", hlen); if (g_ip_dscp_actif) { - tf = proto_tree_add_uint_format(ip_tree, hf_ip_dsfield, NullTVB, offset + 1, 1, iph.ip_tos, + tf = proto_tree_add_uint_format(ip_tree, hf_ip_dsfield, tvb, offset + 1, 1, iph.ip_tos, "Differentiated Services Field: 0x%02x (DSCP 0x%02x: %s; ECN: 0x%02x)", iph.ip_tos, IPDSFIELD_DSCP(iph.ip_tos), val_to_str(IPDSFIELD_DSCP(iph.ip_tos), dscp_vals, "Unknown DSCP"),IPDSFIELD_ECN(iph.ip_tos)); field_tree = proto_item_add_subtree(tf, ett_ip_dsfield); - proto_tree_add_uint(field_tree, hf_ip_dsfield_dscp, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_uint(field_tree, hf_ip_dsfield_ect, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_uint(field_tree, hf_ip_dsfield_ce, NullTVB, offset + 1, 1, iph.ip_tos); + proto_tree_add_uint(field_tree, hf_ip_dsfield_dscp, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_uint(field_tree, hf_ip_dsfield_ect, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_uint(field_tree, hf_ip_dsfield_ce, tvb, offset + 1, 1, iph.ip_tos); } else { - tf = proto_tree_add_uint_format(ip_tree, hf_ip_tos, NullTVB, offset + 1, 1, iph.ip_tos, + tf = proto_tree_add_uint_format(ip_tree, hf_ip_tos, tvb, offset + 1, 1, iph.ip_tos, "Type of service: 0x%02x (%s)", iph.ip_tos, val_to_str( IPTOS_TOS(iph.ip_tos), iptos_vals, "Unknown") ); field_tree = proto_item_add_subtree(tf, ett_ip_tos); - proto_tree_add_uint(field_tree, hf_ip_tos_precedence, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_boolean(field_tree, hf_ip_tos_delay, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_boolean(field_tree, hf_ip_tos_throughput, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_boolean(field_tree, hf_ip_tos_reliability, NullTVB, offset + 1, 1, iph.ip_tos); - proto_tree_add_boolean(field_tree, hf_ip_tos_cost, NullTVB, offset + 1, 1, iph.ip_tos); + proto_tree_add_uint(field_tree, hf_ip_tos_precedence, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_boolean(field_tree, hf_ip_tos_delay, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_boolean(field_tree, hf_ip_tos_throughput, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_boolean(field_tree, hf_ip_tos_reliability, tvb, offset + 1, 1, iph.ip_tos); + proto_tree_add_boolean(field_tree, hf_ip_tos_cost, tvb, offset + 1, 1, iph.ip_tos); } - proto_tree_add_uint(ip_tree, hf_ip_len, NullTVB, offset + 2, 2, iph.ip_len); - proto_tree_add_uint(ip_tree, hf_ip_id, NullTVB, offset + 4, 2, iph.ip_id); + proto_tree_add_uint(ip_tree, hf_ip_len, tvb, offset + 2, 2, iph.ip_len); + proto_tree_add_uint(ip_tree, hf_ip_id, tvb, offset + 4, 2, iph.ip_id); flags = (iph.ip_off & (IP_DF|IP_MF)) >> 12; - tf = proto_tree_add_uint(ip_tree, hf_ip_flags, NullTVB, offset + 6, 1, flags); + tf = proto_tree_add_uint(ip_tree, hf_ip_flags, tvb, offset + 6, 1, flags); field_tree = proto_item_add_subtree(tf, ett_ip_off); - proto_tree_add_boolean(field_tree, hf_ip_flags_df, NullTVB, offset + 6, 1, flags), - proto_tree_add_boolean(field_tree, hf_ip_flags_mf, NullTVB, offset + 6, 1, flags), + proto_tree_add_boolean(field_tree, hf_ip_flags_df, tvb, offset + 6, 1, flags), + proto_tree_add_boolean(field_tree, hf_ip_flags_mf, tvb, offset + 6, 1, flags), - proto_tree_add_uint(ip_tree, hf_ip_frag_offset, NullTVB, offset + 6, 2, + proto_tree_add_uint(ip_tree, hf_ip_frag_offset, tvb, offset + 6, 2, (iph.ip_off & IP_OFFSET)*8); - proto_tree_add_uint(ip_tree, hf_ip_ttl, NullTVB, offset + 8, 1, iph.ip_ttl); - proto_tree_add_uint_format(ip_tree, hf_ip_proto, NullTVB, offset + 9, 1, iph.ip_p, + proto_tree_add_uint(ip_tree, hf_ip_ttl, tvb, offset + 8, 1, iph.ip_ttl); + proto_tree_add_uint_format(ip_tree, hf_ip_proto, tvb, offset + 9, 1, iph.ip_p, "Protocol: %s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p); - ipsum = ip_checksum(&pd[offset], hlen); + ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen); if (ipsum == 0) { - proto_tree_add_uint_format(ip_tree, hf_ip_checksum, NullTVB, offset + 10, 2, iph.ip_sum, + proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum, "Header checksum: 0x%04x (correct)", iph.ip_sum); } else { - proto_tree_add_uint_format(ip_tree, hf_ip_checksum, NullTVB, offset + 10, 2, iph.ip_sum, + proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum, "Header checksum: 0x%04x (incorrect, should be 0x%04x)", iph.ip_sum, ip_checksum_shouldbe(iph.ip_sum, ipsum)); } - proto_tree_add_ipv4(ip_tree, hf_ip_src, NullTVB, offset + 12, 4, iph.ip_src); - proto_tree_add_ipv4(ip_tree, hf_ip_dst, NullTVB, offset + 16, 4, iph.ip_dst); - proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, NullTVB, offset + 12, 4, iph.ip_src); - proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, NullTVB, offset + 16, 4, iph.ip_dst); + proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, iph.ip_src); + proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, iph.ip_dst); + proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 12, 4, iph.ip_src); + proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 16, 4, iph.ip_dst); /* Decode IP options, if any. */ if (hlen > sizeof (e_ip)) { /* There's more than just the fixed-length header. Decode the options. */ optlen = hlen - sizeof (e_ip); /* length of options, in bytes */ - tf = proto_tree_add_text(ip_tree, NullTVB, offset + 20, optlen, + tf = proto_tree_add_text(ip_tree, tvb, offset + 20, optlen, "Options: (%u bytes)", optlen); field_tree = proto_item_add_subtree(tf, ett_ip_options); - dissect_ip_tcp_options(&pd[offset + 20], offset + 20, optlen, + dissect_ip_tcp_options(tvb, offset + 20, optlen, ipopts, N_IP_OPTS, IPOPT_END, field_tree); } } - pi.ipproto = iph.ip_p; - pi.iplen = iph.ip_len; - pi.iphdrlen = lo_nibble(iph.ip_v_hl); - SET_ADDRESS(&pi.net_src, AT_IPv4, 4, &pd[offset + IPH_SRC]); - SET_ADDRESS(&pi.src, AT_IPv4, 4, &pd[offset + IPH_SRC]); - SET_ADDRESS(&pi.net_dst, AT_IPv4, 4, &pd[offset + IPH_DST]); - SET_ADDRESS(&pi.dst, AT_IPv4, 4, &pd[offset + IPH_DST]); + pinfo->ipproto = iph.ip_p; + pinfo->iplen = iph.ip_len; + pinfo->iphdrlen = lo_nibble(iph.ip_v_hl); + SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4)); + SET_ADDRESS(&pinfo->src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4)); + SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4)); + SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4)); /* Skip over header + options */ offset += hlen; nxt = iph.ip_p; if (iph.ip_off & IP_OFFSET) { /* fragmented */ - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "IP"); - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)", + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "IP"); + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)", ipprotostr(iph.ip_p), iph.ip_p, (iph.ip_off & IP_OFFSET) * 8); - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, offset, pinfo, tree); return; } - /* do lookup with the subdissector table */ - if (!old_dissector_try_port(ip_dissector_table, nxt, pd, offset, fd, tree)) { + /* Hand off to the next protocol. + + XXX - setting the columns only after trying various dissectors means + that if one of those dissectors throws an exception, the frame won't + even be labelled as an IP frame; ideally, if a frame being dissected + throws an exception, it'll be labelled as a mangled frame of the + type in question. */ + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + if (!dissector_try_port(ip_dissector_table, nxt, next_tvb, pinfo, tree)) { /* Unknown protocol */ - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "IP"); - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p); - old_dissect_data(pd, offset, fd, tree); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "IP"); + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p); + dissect_data(next_tvb, 0, pinfo, tree); } } @@ -1005,31 +1000,36 @@ static const gchar *par_str[] = {"IP header bad", "Required option missing"}; #define N_PARAMPROB (sizeof par_str / sizeof par_str[0]) static void -dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { - e_icmp ih; +dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ proto_tree *icmp_tree; proto_item *ti; + guint8 icmp_type; + guint8 icmp_code; + guint length, reported_length; guint16 cksum, computed_cksum; gchar type_str[64], code_str[64] = ""; guint8 num_addrs = 0; guint8 addr_entry_size = 0; int i; - OLD_CHECK_DISPLAY_AS_DATA(proto_icmp, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_icmp, tvb, pinfo, tree); + + pinfo->current_proto = "ICMP"; - /* Avoids alignment problems on many architectures. */ - memcpy(&ih, &pd[offset], sizeof(e_icmp)); /* To do: check for runts, errs, etc. */ - cksum = ntohs(ih.icmp_cksum); + icmp_type = tvb_get_guint8(tvb, 0); + icmp_code = tvb_get_guint8(tvb, 1); + cksum = tvb_get_ntohs(tvb, 2); - switch (ih.icmp_type) { + switch (icmp_type) { case ICMP_ECHOREPLY: strcpy(type_str, "Echo (ping) reply"); break; case ICMP_UNREACH: strcpy(type_str, "Destination unreachable"); - if (ih.icmp_code < N_UNREACH) { - sprintf(code_str, "(%s)", unreach_str[ih.icmp_code]); + if (icmp_code < N_UNREACH) { + sprintf(code_str, "(%s)", unreach_str[icmp_code]); } else { strcpy(code_str, "(Unknown - error?)"); } @@ -1039,8 +1039,8 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { break; case ICMP_REDIRECT: strcpy(type_str, "Redirect"); - if (ih.icmp_code < N_REDIRECT) { - sprintf(code_str, "(%s)", redir_str[ih.icmp_code]); + if (icmp_code < N_REDIRECT) { + sprintf(code_str, "(%s)", redir_str[icmp_code]); } else { strcpy(code_str, "(Unknown - error?)"); } @@ -1056,16 +1056,16 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { break; case ICMP_TIMXCEED: strcpy(type_str, "Time-to-live exceeded"); - if (ih.icmp_code < N_TIMXCEED) { - sprintf(code_str, "(%s)", ttl_str[ih.icmp_code]); + if (icmp_code < N_TIMXCEED) { + sprintf(code_str, "(%s)", ttl_str[icmp_code]); } else { strcpy(code_str, "(Unknown - error?)"); } break; case ICMP_PARAMPROB: strcpy(type_str, "Parameter problem"); - if (ih.icmp_code < N_PARAMPROB) { - sprintf(code_str, "(%s)", par_str[ih.icmp_code]); + if (icmp_code < N_PARAMPROB) { + sprintf(code_str, "(%s)", par_str[icmp_code]); } else { strcpy(code_str, "(Unknown - error?)"); } @@ -1092,49 +1092,48 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { strcpy(type_str, "Unknown ICMP (obsolete or malformed?)"); } - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "ICMP"); - if (check_col(fd, COL_INFO)) - col_add_str(fd, COL_INFO, type_str); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "ICMP"); + if (check_col(pinfo->fd, COL_INFO)) + col_add_str(pinfo->fd, COL_INFO, type_str); if (tree) { - ti = proto_tree_add_item(tree, proto_icmp, NullTVB, offset, END_OF_FRAME, FALSE); + length = tvb_length(tvb); + reported_length = tvb_reported_length(tvb); + ti = proto_tree_add_item(tree, proto_icmp, tvb, 0, length, FALSE); icmp_tree = proto_item_add_subtree(ti, ett_icmp); - proto_tree_add_uint_format(icmp_tree, hf_icmp_type, NullTVB, offset, 1, - ih.icmp_type, + proto_tree_add_uint_format(icmp_tree, hf_icmp_type, tvb, 0, 1, + icmp_type, "Type: %u (%s)", - ih.icmp_type, type_str); - proto_tree_add_uint_format(icmp_tree, hf_icmp_code, NullTVB, offset + 1, 1, - ih.icmp_code, + icmp_type, type_str); + proto_tree_add_uint_format(icmp_tree, hf_icmp_code, tvb, 1, 1, + icmp_code, "Code: %u %s", - ih.icmp_code, code_str); + icmp_code, code_str); - if (pi.captured_len >= pi.len) { + if (length >= reported_length) { /* The packet isn't truncated, so we can checksum it. XXX - we have to check whether this is part of a fragmented IP datagram, too.... */ - computed_cksum = ip_checksum(&pd[offset], END_OF_FRAME); + computed_cksum = ip_checksum(tvb_get_ptr(tvb, 0, reported_length), + reported_length); if (computed_cksum == 0) { - proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, NullTVB, - offset + 2, 2, + proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum, "Checksum: 0x%04x (correct)", cksum); } else { - proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, NullTVB, - offset + 2, 2, + proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum, "Checksum: 0x%04x (incorrect, should be 0x%04x)", cksum, ip_checksum_shouldbe(cksum, computed_cksum)); } } else { - proto_tree_add_uint(icmp_tree, hf_icmp_checksum, NullTVB, - offset + 2, 2, - cksum); + proto_tree_add_uint(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum); } /* Decode the second 4 bytes of the packet. */ - switch (ih.icmp_type) { + switch (icmp_type) { case ICMP_ECHOREPLY: case ICMP_ECHO: case ICMP_TSTAMP: @@ -1143,45 +1142,45 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { case ICMP_IREQREPLY: case ICMP_MASKREQ: case ICMP_MASKREPLY: - proto_tree_add_text(icmp_tree, NullTVB, offset + 4, 2, "Identifier: 0x%04x", - pntohs(&pd[offset + 4])); - proto_tree_add_text(icmp_tree, NullTVB, offset + 6, 2, "Sequence number: %02x:%02x", - pd[offset+6], pd[offset+7]); + proto_tree_add_text(icmp_tree, tvb, 4, 2, "Identifier: 0x%04x", + tvb_get_ntohs(tvb, 4)); + proto_tree_add_text(icmp_tree, tvb, 6, 2, "Sequence number: %02x:%02x", + tvb_get_guint8(tvb, 6), tvb_get_guint8(tvb, 7)); break; case ICMP_UNREACH: - switch (ih.icmp_code) { + switch (icmp_code) { case ICMP_FRAG_NEEDED: - proto_tree_add_text(icmp_tree, NullTVB, offset + 6, 2, "MTU of next hop: %u", - pntohs(&pd[offset + 6])); + proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u", + tvb_get_ntohs(tvb, 6)); break; } break; case ICMP_RTRADVERT: - num_addrs = pd[offset + 4]; - proto_tree_add_text(icmp_tree, NullTVB, offset + 4, 1, "Number of addresses: %u", + num_addrs = tvb_get_guint8(tvb, 4); + proto_tree_add_text(icmp_tree, tvb, 4, 1, "Number of addresses: %u", num_addrs); - addr_entry_size = pd[offset + 5]; - proto_tree_add_text(icmp_tree, NullTVB, offset + 5, 1, "Address entry size: %u", + addr_entry_size = tvb_get_guint8(tvb, 5); + proto_tree_add_text(icmp_tree, tvb, 5, 1, "Address entry size: %u", addr_entry_size); - proto_tree_add_text(icmp_tree, NullTVB, offset + 6, 2, "Lifetime: %s", - time_secs_to_str(pntohs(&pd[offset + 6]))); + proto_tree_add_text(icmp_tree, tvb, 6, 2, "Lifetime: %s", + time_secs_to_str(tvb_get_ntohs(tvb, 6))); break; case ICMP_PARAMPROB: - proto_tree_add_text(icmp_tree, NullTVB, offset + 4, 1, "Pointer: %u", - pd[offset + 4]); + proto_tree_add_text(icmp_tree, tvb, 4, 1, "Pointer: %u", + tvb_get_guint8(tvb, 4)); break; case ICMP_REDIRECT: - proto_tree_add_text(icmp_tree, NullTVB, offset + 4, 4, "Gateway address: %s", - ip_to_str((guint8 *)&pd[offset + 4])); + proto_tree_add_text(icmp_tree, tvb, 4, 4, "Gateway address: %s", + ip_to_str(tvb_get_ptr(tvb, 4, 4))); break; } /* Decode the additional information in the packet. */ - switch (ih.icmp_type) { + switch (icmp_type) { case ICMP_UNREACH: case ICMP_TIMXCEED: case ICMP_PARAMPROB: @@ -1192,41 +1191,41 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { XXX - for now, just display it as data; not all dissection routines can handle a short packet without exploding. */ - old_dissect_data(pd, offset + 8, fd, icmp_tree); + dissect_data(tvb, 8, pinfo, icmp_tree); break; case ICMP_ECHOREPLY: case ICMP_ECHO: - old_dissect_data(pd, offset + 8, fd, icmp_tree); + dissect_data(tvb, 8, pinfo, icmp_tree); break; case ICMP_RTRADVERT: if (addr_entry_size == 2) { for (i = 0; i < num_addrs; i++) { - proto_tree_add_text(icmp_tree, NullTVB, offset + 8 + (i*8), 4, + proto_tree_add_text(icmp_tree, tvb, 8 + (i*8), 4, "Router address: %s", - ip_to_str((guint8 *)&pd[offset + 8 + (i*8)])); - proto_tree_add_text(icmp_tree, NullTVB, offset + 12 + (i*8), 4, - "Preference level: %u", pntohl(&pd[offset + 12 + (i*8)])); + ip_to_str(tvb_get_ptr(tvb, 8 + (i*8), 4))); + proto_tree_add_text(icmp_tree, tvb, 12 + (i*8), 4, + "Preference level: %u", tvb_get_ntohl(tvb, 12 + (i*8))); } } else - old_dissect_data(pd, offset + 8, fd, icmp_tree); + dissect_data(tvb, 8, pinfo, icmp_tree); break; case ICMP_TSTAMP: case ICMP_TSTAMPREPLY: - proto_tree_add_text(icmp_tree, NullTVB, offset + 8, 4, "Originate timestamp: %u", - pntohl(&pd[offset + 8])); - proto_tree_add_text(icmp_tree, NullTVB, offset + 12, 4, "Receive timestamp: %u", - pntohl(&pd[offset + 12])); - proto_tree_add_text(icmp_tree, NullTVB, offset + 16, 4, "Transmit timestamp: %u", - pntohl(&pd[offset + 16])); + proto_tree_add_text(icmp_tree, tvb, 8, 4, "Originate timestamp: %u", + tvb_get_ntohl(tvb, 8)); + proto_tree_add_text(icmp_tree, tvb, 12, 4, "Receive timestamp: %u", + tvb_get_ntohl(tvb, 12)); + proto_tree_add_text(icmp_tree, tvb, 16, 4, "Transmit timestamp: %u", + tvb_get_ntohl(tvb, 16)); break; case ICMP_MASKREQ: case ICMP_MASKREPLY: - proto_tree_add_text(icmp_tree, NullTVB, offset + 8, 4, "Address mask: %s (0x%8x)", - ip_to_str((guint8 *)&pd[offset + 8]), pntohl(&pd[offset + 8])); + proto_tree_add_text(icmp_tree, tvb, 8, 4, "Address mask: %s (0x%8x)", + ip_to_str(tvb_get_ptr(tvb, 8, 4)), tvb_get_ntohl(tvb, 8)); break; } } @@ -1469,17 +1468,19 @@ proto_register_ip(void) "Decode IPv4 TOS field as DiffServ field", "Whether the IPv4 type-of-service field should be decoded as a Differentiated Services field", &g_ip_dscp_actif); + + register_dissector("ip", dissect_ip); } void proto_reg_handoff_ip(void) { - old_dissector_add("ethertype", ETHERTYPE_IP, dissect_ip); - old_dissector_add("ppp.protocol", PPP_IP, dissect_ip); - old_dissector_add("llc.dsap", SAP_IP, dissect_ip); - old_dissector_add("ip.proto", IP_PROTO_IPV4, dissect_ip); - old_dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip); - old_dissector_add("null.type", BSD_AF_INET, dissect_ip); + dissector_add("ethertype", ETHERTYPE_IP, dissect_ip); + dissector_add("ppp.protocol", PPP_IP, dissect_ip); + dissector_add("llc.dsap", SAP_IP, dissect_ip); + dissector_add("ip.proto", IP_PROTO_IPV4, dissect_ip); + dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip); + dissector_add("null.type", BSD_AF_INET, dissect_ip); } void @@ -1512,5 +1513,5 @@ proto_register_icmp(void) void proto_reg_handoff_icmp(void) { - old_dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp); + dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp); } diff --git a/packet-ip.h b/packet-ip.h index ac4485f4b9..aa6324d055 100644 --- a/packet-ip.h +++ b/packet-ip.h @@ -1,7 +1,7 @@ /* packet-ip.h * Definitions for IP packet disassembly structures and routines * - * $Id: packet-ip.h,v 1.14 2000/05/26 21:54:50 guy Exp $ + * $Id: packet-ip.h,v 1.15 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -28,7 +28,7 @@ #define __PACKET_IP_H__ void capture_ip(const u_char *, int, packet_counts *); -void dissect_ip(const u_char *, int, frame_data *, proto_tree *); +void dissect_ip(tvbuff_t *, packet_info *, proto_tree *); #define IP_PROTO_IP 0 /* dummy for IP */ #define IP_PROTO_HOPOPTS 0 /* IP6 hop-by-hop options */ @@ -76,12 +76,12 @@ typedef struct ip_tcp_opt { int *subtree_index; /* pointer to subtree index for option */ opt_len_type len_type; /* type of option length field */ int optlen; /* value length should be (minimum if VARIABLE) */ - void (*dissect)(const struct ip_tcp_opt *, const u_char *, int, guint, proto_tree *); + void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *, int, guint, proto_tree *); /* routine to dissect option */ } ip_tcp_opt; /* Routine to dissect IP or TCP options. */ -void dissect_ip_tcp_options(const u_char *, int, guint, +void dissect_ip_tcp_options(tvbuff_t *, int, guint, const ip_tcp_opt *, int, int, proto_tree *); /* Dissector table for "ip.proto"; used by IPv6 as well as IPv4 */ diff --git a/packet-mpls.c b/packet-mpls.c index b1e1ca3d70..719d26f11d 100644 --- a/packet-mpls.c +++ b/packet-mpls.c @@ -3,7 +3,7 @@ * * (c) Copyright Ashok Narayanan <ashokn@cisco.com> * - * $Id: packet-mpls.c,v 1.9 2000/08/13 14:08:29 deniel Exp $ + * $Id: packet-mpls.c,v 1.10 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -45,7 +45,6 @@ #include <glib.h> #include "etypes.h" #include "packet.h" -#include "packet-ip.h" static gint proto_mpls = -1; @@ -108,6 +107,8 @@ static hf_register_info mplsf_info[] = { "" }}, }; +static dissector_handle_t ip_handle; + /* * Given a 4-byte MPLS label starting at "start", decode this. * Return the label in "label", EXP bits in "exp", @@ -177,7 +178,7 @@ dissect_mpls(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) offset += 4; if (bos) break; } - dissect_ip(pd, offset, fd, tree); + old_call_dissector(ip_handle, pd, offset, fd, tree); } void @@ -196,4 +197,9 @@ void proto_reg_handoff_mpls(void) { old_dissector_add("ethertype", ETHERTYPE_MPLS, dissect_mpls); + + /* + * Get a handle for the IP dissector. + */ + ip_handle = find_dissector("ip"); } diff --git a/packet-msproxy.c b/packet-msproxy.c index 1f4506919b..1a94a76d41 100644 --- a/packet-msproxy.c +++ b/packet-msproxy.c @@ -2,7 +2,7 @@ * Routines for Microsoft Proxy packet dissection * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> * - * $Id: packet-msproxy.c,v 1.12 2000/10/21 05:52:21 guy Exp $ + * $Id: packet-msproxy.c,v 1.13 2000/11/18 10:38:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -220,6 +220,7 @@ static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd, conversation_t *conversation; proto_tree *msp_tree; proto_item *ti; + tvbuff_t *tvb; conversation = find_conversation( &pi.src, &pi.dst, pi.ptype, pi.srcport, pi.destport, 0); @@ -259,10 +260,11 @@ static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd, *ptr = redirect_info->remote_port; + tvb = tvb_create_from_top(0); if ( redirect_info->proto == PT_TCP) - decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport); + decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport); else - decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport); + decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport); *ptr = redirect_info->server_int_port; } diff --git a/packet-osi-options.c b/packet-osi-options.c index 5b9f1c1e88..5010fd38aa 100644 --- a/packet-osi-options.c +++ b/packet-osi-options.c @@ -5,7 +5,7 @@ * ISO 10589 ISIS (Intradomain Routeing Information Exchange Protocol) * ISO 9542 ESIS (End System To Intermediate System Routeing Exchange Protocol) * - * $Id: packet-osi-options.c,v 1.2 2000/05/11 08:15:31 gram Exp $ + * $Id: packet-osi-options.c,v 1.3 2000/11/18 10:38:24 guy Exp $ * Ralf Schneider <Ralf.Schneider@t-online.de> * * Ethereal - Network traffic analyzer @@ -171,7 +171,7 @@ static const value_string osi_opt_rfd_reassembly[] = { void dissect_option_qos( const u_char type, const u_char sub_type, u_char offset, - u_char len, const u_char *pd, proto_tree *tree ) { + u_char len, tvbuff_t *tvb, proto_tree *tree ) { u_char tmp_type = 0; proto_item *ti; @@ -221,7 +221,7 @@ dissect_option_qos( const u_char type, const u_char sub_type, u_char offset, }; void dissect_option_route( u_char parm_type, u_char offset, u_char parm_len, - const u_char *pd, proto_tree *tree ) { + tvbuff_t *tvb, proto_tree *tree ) { u_char next_hop = 0; u_char this_hop = 0; @@ -238,23 +238,25 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len, { 0, NULL} }; if ( parm_type == OSI_OPT_SOURCE_ROUTING ) { - next_hop = pd[offset + 1 ]; - netl = pd[next_hop + 2 ]; + next_hop = tvb_get_guint8(tvb, offset + 1 ); + netl = tvb_get_guint8(tvb, next_hop + 2 ); this_hop = offset + 3; /* points to first netl */ - ti = proto_tree_add_text( tree, NullTVB, offset + next_hop, netl, + ti = proto_tree_add_text( tree, tvb, offset + next_hop, netl, "Source Routing: %s ( Next Hop Highlighted In Data Buffer )", - (pd[offset] == 0) ? "Partial Source Routeing" : - "Complete Source Routeing" ); + (tvb_get_guint8(tvb, offset) == 0) ? "Partial Source Routeing" : + "Complete Source Routeing" ); } else { - last_hop = pd[offset + 1 ]; /* points to the end of the list */ - netl = pd[ last_hop ]; /* mis-used to highlight buffer */ + last_hop = tvb_get_guint8(tvb, offset + 1 ); + /* points to the end of the list */ + netl = tvb_get_guint8(tvb, last_hop ); + /* mis-used to highlight buffer */ - ti = proto_tree_add_text( tree, NullTVB, offset + next_hop, netl, + ti = proto_tree_add_text( tree, tvb, offset + next_hop, netl, "Record of Route: %s : %s", - (pd[offset] == 0) ? "Partial Source Routeing" : - "Complete Source Routeing" , + (tvb_get_guint8(tvb, offset) == 0) ? "Partial Source Routeing" : + "Complete Source Routeing" , val_to_str( last_hop, osi_opt_route, "Unknown (0x%x" ) ); if ( 255 == last_hop ) this_hop = parm_len + 1; /* recording terminated, nothing to show */ @@ -264,12 +266,12 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len, osi_route_tree = proto_item_add_subtree( ti, ott_osi_route ); while ( this_hop < parm_len ) { - netl = pd[this_hop + 1]; - proto_tree_add_text( osi_route_tree, NullTVB, offset + this_hop, netl, + netl = tvb_get_guint8(tvb, this_hop + 1); + proto_tree_add_text( osi_route_tree, tvb, offset + this_hop, netl, "Hop #%3u NETL: %2u, NET: %s", cnt_hops++, netl, - print_nsap_net( &pd[this_hop + 1], netl ) ); + print_nsap_net( tvb_get_ptr(tvb, this_hop + 1, netl), netl ) ); this_hop += 1 + netl; } }; @@ -280,7 +282,7 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len, void dissect_option_rfd( const u_char error, const u_char field, u_char offset, - u_char len, const u_char *pd, proto_tree *tree ) { + u_char len, tvbuff_t *tvb, proto_tree *tree ) { u_char error_class = 0; char *format_string[] = { "Reason for discard {General} : %s, in field %u", @@ -294,37 +296,37 @@ dissect_option_rfd( const u_char error, const u_char field, u_char offset, error_class = error & OSI_OPT_RFD_MASK; if ( OSI_OPT_RFD_GENERAL == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[0], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[0], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_general, "Unknown (0x%x)"), field ); } else if ( OSI_OPT_RFD_ADDRESS == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[1], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[1], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_address, "Unknown (0x%x)"), field ); } else if ( OSI_OPT_RFD_SOURCE_ROUTEING == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[2], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[2], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_src_route, "Unknown (0x%x)"), field ); } else if ( OSI_OPT_RFD_LIFETIME == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[3], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[3], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_lifetime, "Unknown (0x%x)"), field ); } else if ( OSI_OPT_RFD_PDU_DISCARDED == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[4], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[4], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_discarded, "Unknown (0x%x)"), field ); } else if ( OSI_OPT_RFD_REASSEMBLY == error_class ) { - proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[5], + proto_tree_add_text( tree, tvb, offset + field, 1, format_string[5], val_to_str( error & OSI_OPT_RFD_SUB_MASK, osi_opt_rfd_reassembly, "Unknown (0x%x)"), field ); } else { - proto_tree_add_text( tree, NullTVB, offset, len, + proto_tree_add_text( tree, tvb, offset, len, "Reason for discard: UNKNOWN Error Class" ); } }; @@ -351,82 +353,90 @@ dissect_option_rfd( const u_char error, const u_char field, u_char offset, * void, but we will add to the proto_tree if it is not NULL. */ void -dissect_osi_options( u_char pdu_type, u_char opt_len, const u_char *pd, - int offset, frame_data *fd, proto_tree *tree) { +dissect_osi_options( u_char pdu_type, u_char opt_len, tvbuff_t *tvb, + int offset, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *osi_option_tree = NULL; u_char parm_len = 0; u_char parm_type = 0; + guint8 octet; if (tree) { if ( 0 == opt_len ) { - proto_tree_add_text( tree, NullTVB, offset, 0, + proto_tree_add_text( tree, tvb, offset, 0, "### No Options for this PDU ###" ); return; } if ( opt_len > END_OF_FRAME ) { - proto_tree_add_text( tree, NullTVB, offset, END_OF_FRAME, + proto_tree_add_text( tree, tvb, offset, END_OF_FRAME, "### Options go past the end of the captured data in this PDU ###" ); return; } - ti = proto_tree_add_text( tree, NullTVB, offset, opt_len, + ti = proto_tree_add_text( tree, tvb, offset, opt_len, "### Option Section ###" ); osi_option_tree = proto_item_add_subtree( ti, ott_osi_options ); while ( 0 < opt_len ) { - parm_type = (int) pd[offset++]; - parm_len = (int) pd[offset++]; + parm_type = (int) tvb_get_guint8(tvb, offset); + offset++; + parm_len = (int) tvb_get_guint8(tvb, offset); + offset++; switch ( parm_type ) { case OSI_OPT_QOS_MAINTANANCE: - dissect_option_qos( pd[offset]&OSI_OPT_QOS_MASK, - pd[offset]&OSI_OPT_QOS_SUB_MASK, - offset, parm_len, pd, osi_option_tree ); + octet = tvb_get_guint8(tvb, offset); + dissect_option_qos( octet&OSI_OPT_QOS_MASK, + octet&OSI_OPT_QOS_SUB_MASK, + offset, parm_len, tvb, osi_option_tree ); break; case OSI_OPT_SECURITY: - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, + octet = tvb_get_guint8(tvb, offset); + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Security type: %s", - val_to_str( pd[offset]&OSI_OPT_SEC_MASK, + val_to_str( octet&OSI_OPT_SEC_MASK, osi_opt_sec_vals, "Unknown (0x%x)") ); break; case OSI_OPT_PRIORITY: - if ( OSI_OPT_MAX_PRIORITY >= pd[offset] ) { - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, - "Priority : %u", pd[offset] ); + octet = tvb_get_guint8(tvb, offset); + if ( OSI_OPT_MAX_PRIORITY >= octet ) { + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, + "Priority : %u", octet ); } else { - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Priority : %u ( Invalid )", - pd[offset] ); + octet ); } break; case OSI_OPT_ADDRESS_MASK: - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, - "Address Mask: %s", print_area( &pd[offset], parm_len ) ); + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, + "Address Mask: %s", + print_area( tvb_get_ptr(tvb, offset, parm_len), parm_len ) ); break; case OSI_OPT_SNPA_MASK: - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, - "SNPA Mask : %s", print_system_id( &pd[offset], parm_len )); + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, + "SNPA Mask : %s", + print_system_id( tvb_get_ptr(tvb, offset, parm_len), parm_len )); break; case OSI_OPT_ES_CONFIG_TIMER: - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, - "ESCT : %u seconds", pntohs( &pd[offset] ) ); + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, + "ESCT : %u seconds", tvb_get_ntohs( tvb, offset ) ); break; case OSI_OPT_PADDING: - proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len, + proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Padding : %u Octets", parm_len ) ; break; case OSI_OPT_SOURCE_ROUTING: case OSI_OPT_RECORD_OF_ROUTE: dissect_option_route( parm_type, - offset, parm_len, pd, osi_option_tree ); + offset, parm_len, tvb, osi_option_tree ); break; case OSI_OPT_REASON_OF_DISCARD: - dissect_option_rfd( pd[offset], - pd[offset + 1], - offset, parm_len, pd, osi_option_tree ); + dissect_option_rfd( tvb_get_guint8(tvb, offset), + tvb_get_guint8(tvb, offset + 1), + offset, parm_len, tvb, osi_option_tree ); break; } opt_len -= parm_len + 2; diff --git a/packet-osi-options.h b/packet-osi-options.h index fdd54d8368..d3b760d800 100644 --- a/packet-osi-options.h +++ b/packet-osi-options.h @@ -1,7 +1,7 @@ /* packet-osi-options.h * Defines for OSI options part decode * - * $Id: packet-osi-options.h,v 1.1 2000/04/15 22:11:12 guy Exp $ + * $Id: packet-osi-options.h,v 1.2 2000/11/18 10:38:24 guy Exp $ * Ralf Schneider <Ralf.Schneider@t-online.de> * * Ethereal - Network traffic analyzer @@ -32,8 +32,8 @@ /* * published API functions */ -extern void dissect_osi_options( u_char, u_char, const u_char *, int, - frame_data *, proto_tree *); +extern void dissect_osi_options( u_char, u_char, tvbuff_t *, int, + packet_info *, proto_tree *); extern void proto_register_osi_options(void); #endif /* _PACKET_OSI_OPTIONS_H */ diff --git a/packet-osi.c b/packet-osi.c index e2a9c8c5e3..0a39f27a94 100644 --- a/packet-osi.c +++ b/packet-osi.c @@ -2,7 +2,7 @@ * Routines for ISO/OSI network and transport protocol packet disassembly * Main entrance point and common functions * - * $Id: packet-osi.c,v 1.35 2000/11/17 06:02:21 guy Exp $ + * $Id: packet-osi.c,v 1.36 2000/11/18 10:38:24 guy Exp $ * Laurent Deniel <deniel@worldnet.fr> * Ralf Schneider <Ralf.Schneider@t-online.de> * @@ -176,25 +176,29 @@ gchar *print_nsap_net( const u_char *buffer, int length) } /* print_nsap */ -gchar *calc_checksum( const u_char *buffer, u_int len, u_int checksum) { +gchar *calc_checksum( tvbuff_t *tvb, int offset, u_int len, u_int checksum) { u_int calc_sum = 0; u_int count = 0; + const gchar *buffer; + guint available_len; - static char *checksum_string[] = { "Not Used", - "Is good", - "Is wrong" }; if ( 0 == checksum ) - return( checksum_string[0] ); + return( "Not Used" ); + available_len = tvb_length_remaining( tvb, offset ); + if ( available_len < len ) + return( "Not checkable - not all of packet was captured" ); + + buffer = tvb_get_ptr( tvb, offset, len ); for ( count = 0; count < len; count++ ) { calc_sum += (u_int) buffer[count]; } calc_sum %= 255; /* modulo 255 divison */ if ( 0 == calc_sum ) - return( checksum_string[1] ); + return( "Is good" ); else - return( checksum_string[2] ); + return( "Is wrong" ); /* XXX - what should the checksum be? */ } @@ -222,37 +226,42 @@ const value_string nlpid_vals[] = { static dissector_table_t subdissector_table; -void dissect_osi(const u_char *pd, int offset, frame_data *fd, - proto_tree *tree) +void dissect_osi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + guint8 nlpid; + + pinfo->current_proto = "OSI"; + + nlpid = tvb_get_guint8(tvb, 0); + /* do lookup with the subdissector table */ - if (old_dissector_try_port(subdissector_table, pd[offset], pd, offset, fd, tree)) + if (dissector_try_port(subdissector_table, nlpid, tvb, pinfo, tree)) return; - switch (pd[offset]) { + switch (nlpid) { /* ESIS (X.25) is not currently decoded */ case NLPID_ISO9542X25_ESIS: - if (check_col(fd, COL_PROTOCOL)) { - col_add_str(fd, COL_PROTOCOL, "ESIS (X.25)"); + if (check_col(pinfo->fd, COL_PROTOCOL)) { + col_add_str(pinfo->fd, COL_PROTOCOL, "ESIS (X.25)"); } - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, 0, pinfo, tree); break; case NLPID_ISO10747_IDRP: - if (check_col(fd, COL_PROTOCOL)) { - col_add_str(fd, COL_PROTOCOL, "IDRP"); + if (check_col(pinfo->fd, COL_PROTOCOL)) { + col_add_str(pinfo->fd, COL_PROTOCOL, "IDRP"); } - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, 0, pinfo, tree); break; default: - if (check_col(fd, COL_PROTOCOL)) { - col_add_str(fd, COL_PROTOCOL, "ISO"); + if (check_col(pinfo->fd, COL_PROTOCOL)) { + col_add_str(pinfo->fd, COL_PROTOCOL, "ISO"); } - if (check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, "Unknown ISO protocol (%02x)", pd[offset]); + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, "Unknown ISO protocol (%02x)", nlpid); } - old_dissect_data(pd, offset, fd, tree); + dissect_data(tvb, 0, pinfo, tree); break; } } /* dissect_osi */ @@ -269,6 +278,6 @@ proto_register_osi(void) void proto_reg_handoff_osi(void) { - old_dissector_add("llc.dsap", SAP_OSINL, dissect_osi); - old_dissector_add("null.type", BSD_AF_ISO, dissect_osi); + dissector_add("llc.dsap", SAP_OSINL, dissect_osi); + dissector_add("null.type", BSD_AF_ISO, dissect_osi); } diff --git a/packet-osi.h b/packet-osi.h index 04e310cacc..b5c759228b 100644 --- a/packet-osi.h +++ b/packet-osi.h @@ -1,6 +1,6 @@ /* packet-osi.h * - * $Id: packet-osi.h,v 1.4 2000/07/01 08:55:28 guy Exp $ + * $Id: packet-osi.h,v 1.5 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -102,11 +102,11 @@ * published API functions */ -extern void dissect_osi( const u_char *, int, frame_data *, proto_tree *); +extern void dissect_osi( tvbuff_t *, packet_info *, proto_tree *); extern gchar *print_nsap_net ( const u_char *, int ); extern gchar *print_area ( const u_char *, int ); extern gchar *print_system_id( const u_char *, int ); -extern gchar *calc_checksum ( const u_char *, u_int, u_int ); +extern gchar *calc_checksum ( tvbuff_t *, int, u_int, u_int ); #endif /* _PACKET_OSI_H */ diff --git a/packet-pim.c b/packet-pim.c index 753acbbbd2..86a31cf4d7 100644 --- a/packet-pim.c +++ b/packet-pim.c @@ -2,7 +2,7 @@ * Routines for PIM disassembly * (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org> * - * $Id: packet-pim.c,v 1.18 2000/11/17 21:00:35 gram Exp $ + * $Id: packet-pim.c,v 1.19 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -70,6 +70,8 @@ static int hf_pim_cksum = -1; static gint ett_pim = -1; +static dissector_handle_t ip_handle; + static const char * dissect_pim_addr(const u_char *bp, const u_char *ep, enum pimv2_addrtype at, int *advance) { @@ -284,9 +286,9 @@ dissect_pim(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { switch((*ip & 0xf0) >> 4) { case 4: /* IPv4 */ #if 0 - dissect_ip(pd, ip - pd, fd, tree); + old_call_dissector(ip_handle, pd, ip - pd, fd, tree); #else - dissect_ip(pd, ip - pd, fd, pimopt_tree); + old_call_dissector(ip_handle, pd, ip - pd, fd, pimopt_tree); #endif break; case 6: /* IPv6 */ @@ -607,5 +609,9 @@ void proto_reg_handoff_pim(void) { old_dissector_add("ip.proto", IP_PROTO_PIM, dissect_pim); -} + /* + * Get a handle for the IP dissector. + */ + ip_handle = find_dissector("ip"); +} diff --git a/packet-ppp.c b/packet-ppp.c index 06f97d33d6..7b4c167dbe 100644 --- a/packet-ppp.c +++ b/packet-ppp.c @@ -1,7 +1,7 @@ /* packet-ppp.c * Routines for ppp packet disassembly * - * $Id: packet-ppp.c,v 1.40 2000/11/16 07:35:38 guy Exp $ + * $Id: packet-ppp.c,v 1.41 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -184,37 +184,37 @@ static const value_string lcp_vals[] = { #define CI_INTERNATIONALIZATION 28 /* Internationalization (RFC 2484) */ #define CI_SDL_ON_SONET_SDH 29 /* Simple Data Link on SONET/SDH */ -static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); -static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); -static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); -static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, - const u_char *opd, int offset, guint length, + tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); @@ -427,9 +427,9 @@ static const ip_tcp_opt lcp_opts[] = { #define CI_MS_DNS2 131 /* Secondary DNS value (RFC 1877) */ #define CI_MS_WINS2 132 /* Secondary WINS value (RFC 1877) */ -static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); -static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree); static const ip_tcp_opt ipcp_opts[] = { @@ -520,103 +520,103 @@ capture_ppp( const u_char *pd, int offset, packet_counts *ld ) { } static void -dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, "MRU: %u", pntohs(opd)); + proto_tree_add_text(tree, tvb, offset, length, "MRU: %u", + tvb_get_ntohs(tvb, offset + 2)); } static void -dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, "Async characters to map: 0x%08x", - pntohl(opd)); + proto_tree_add_text(tree, tvb, offset, length, "Async characters to map: 0x%08x", + tvb_get_ntohl(tvb, offset + 2)); } static void -dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { guint16 protocol; proto_item *tf; proto_tree *field_tree = NULL; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - protocol = pntohs(opd); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s: %s (0x%02x)", optp->name, + protocol = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 2, "%s: %s (0x%02x)", optp->name, val_to_str(protocol, ppp_vals, "Unknown"), protocol); offset += 2; - opd += 2; length -= 2; if (length > 0) - proto_tree_add_text(field_tree, NullTVB, offset, length, "Data (%d byte%s)", length, + proto_tree_add_text(field_tree, tvb, offset, length, "Data (%d byte%s)", length, plurality(length, "", "s")); } static void -dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, "Magic number: 0x%08x", - pntohl(opd)); + proto_tree_add_text(tree, tvb, offset, length, "Magic number: 0x%08x", + tvb_get_ntohl(tvb, offset + 2)); } static void -dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; guint8 alternatives; - alternatives = *opd; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: 0x%02x", + alternatives = tvb_get_guint8(tvb, offset + 2); + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x", optp->name, alternatives); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; if (alternatives & 0x1) - proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s", + proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s", decode_boolean_bitfield(alternatives, 0x1, 8, "Null FCS", NULL)); if (alternatives & 0x2) - proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s", + proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s", decode_boolean_bitfield(alternatives, 0x2, 8, "CCITT 16-bit FCS", NULL)); if (alternatives & 0x4) - proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s", + proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s", decode_boolean_bitfield(alternatives, 0x4, 8, "CCITT 32-bit FCS", NULL)); } static void -dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, + proto_tree_add_text(tree, tvb, offset, length, "Maximum octets of self-describing padding: %u", - *opd); + tvb_get_guint8(tvb, offset + 2)); } static void -dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - proto_tree_add_text(field_tree, NullTVB, offset, 1, "Window: %u", *opd); + proto_tree_add_text(field_tree, tvb, offset, 1, "Window: %u", + tvb_get_guint8(tvb, offset)); offset += 1; - opd += 1; length -= 1; if (length > 0) - proto_tree_add_text(field_tree, NullTVB, offset, length, "Address (%d byte%s)", + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)", length, plurality(length, "", "s")); } @@ -630,34 +630,35 @@ static const value_string callback_op_vals[] = { }; static void -dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd, int offset, +dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; + guint8 operation; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - proto_tree_add_text(field_tree, NullTVB, offset, 1, "Operation: %s (0x%02x)", - val_to_str(*opd, callback_op_vals, "Unknown"), - *opd); + operation = tvb_get_guint8(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 1, "Operation: %s (0x%02x)", + val_to_str(operation, callback_op_vals, "Unknown"), + operation); offset += 1; - opd += 1; length -= 1; if (length > 0) - proto_tree_add_text(field_tree, NullTVB, offset, length, "Message (%d byte%s)", + proto_tree_add_text(field_tree, tvb, offset, length, "Message (%d byte%s)", length, plurality(length, "", "s")); } static void -dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, "Multilink MRRU: %u", - pntohs(opd)); + proto_tree_add_text(tree, tvb, offset, length, "Multilink MRRU: %u", + tvb_get_ntohs(tvb, offset + 2)); } #define CLASS_NULL 0 @@ -678,41 +679,40 @@ static const value_string multilink_ep_disc_class_vals[] = { }; static void -dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; guint8 ep_disc_class; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - ep_disc_class = *opd; - proto_tree_add_text(field_tree, NullTVB, offset, 1, "Class: %s (%u)", + ep_disc_class = tvb_get_guint8(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 1, "Class: %s (%u)", val_to_str(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"), ep_disc_class); offset += 1; - opd += 1; length -= 1; if (length > 0) { switch (ep_disc_class) { case CLASS_NULL: - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been empty", length, plurality(length, "", "s")); break; case CLASS_LOCAL: if (length > 20) { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been <20", length, plurality(length, "", "s")); } else { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)", length, plurality(length, "", "s")); } @@ -720,34 +720,34 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd, case CLASS_IP: if (length != 4) { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been 4", length, plurality(length, "", "s")); } else { - proto_tree_add_text(field_tree, NullTVB, offset, length, - "Address: %s", ip_to_str(opd)); + proto_tree_add_text(field_tree, tvb, offset, length, + "Address: %s", ip_to_str(tvb_get_ptr(tvb, offset, 4))); } break; case CLASS_IEEE_802_1: if (length != 6) { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been 6", length, plurality(length, "", "s")); } else { - proto_tree_add_text(field_tree, NullTVB, offset, length, - "Address: %s", ether_to_str(opd)); + proto_tree_add_text(field_tree, tvb, offset, length, + "Address: %s", ether_to_str(tvb_get_ptr(tvb, offset, 6))); } break; case CLASS_PPP_MAGIC_NUMBER: /* XXX - dissect as 32-bit magic numbers */ if (length > 20) { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been <20", length, plurality(length, "", "s")); } else { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)", length, plurality(length, "", "s")); } @@ -755,18 +755,18 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd, case CLASS_PSDN_DIRECTORY_NUMBER: if (length > 15) { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s), should have been <20", length, plurality(length, "", "s")); } else { - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)", length, plurality(length, "", "s")); } break; default: - proto_tree_add_text(field_tree, NullTVB, offset, length, + proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)", length, plurality(length, "", "s")); break; @@ -775,12 +775,12 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd, } static void -dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, + proto_tree_add_text(tree, tvb, offset, length, "Link discriminator for BAP: 0x%04x", - pntohs(opd)); + tvb_get_ntohs(tvb, offset + 2)); } /* Character set numbers from the IANA charset registry. */ @@ -790,56 +790,58 @@ static const value_string charset_num_vals[] = { }; static void -dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; + guint32 charset; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - proto_tree_add_text(field_tree, NullTVB, offset, 4, "Character set: %s (0x%04x)", - val_to_str(pntohl(opd), charset_num_vals, "Unknown"), - pntohl(opd)); + charset = tvb_get_ntohl(tvb, offset); + proto_tree_add_text(field_tree, tvb, offset, 4, "Character set: %s (0x%04x)", + val_to_str(charset, charset_num_vals, "Unknown"), + charset); offset += 4; - opd += 4; length -= 4; if (length > 0) { /* XXX - should be displayed as an ASCII string */ - proto_tree_add_text(field_tree, NullTVB, offset, length, "Language tag (%d byte%s)", + proto_tree_add_text(field_tree, tvb, offset, length, "Language tag (%d byte%s)", length, plurality(length, "", "s")); } } static void -dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd, +dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { proto_item *tf; proto_tree *field_tree = NULL; - tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s", + tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s", optp->name, length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, *optp->subtree_index); offset += 2; length -= 2; - proto_tree_add_text(field_tree, NullTVB, offset, 4, - "Source IP address: %s", ip_to_str(opd)); + proto_tree_add_text(field_tree, tvb, offset, 4, + "Source IP address: %s", + ip_to_str(tvb_get_ptr(tvb, offset, 4))); offset += 4; - opd += 4; length -= 4; - proto_tree_add_text(field_tree, NullTVB, offset, 4, - "Destination IP address: %s", ip_to_str(opd)); + proto_tree_add_text(field_tree, tvb, offset, 4, + "Destination IP address: %s", + ip_to_str(tvb_get_ptr(tvb, offset, 4))); } -static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd, +static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint length, proto_tree *tree) { - proto_tree_add_text(tree, NullTVB, offset, length, "%s: %s", optp->name, - ip_to_str((guint8 *)opd)); + proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name, + ip_to_str(tvb_get_ptr(tvb, offset + 2, 4))); } static void @@ -886,16 +888,11 @@ dissect_cp( tvbuff_t *tvb, const char *proto_short_name, case CONFREJ: if(tree) { if (length > 0) { - const guint8 *this_pd; - int this_offset; - - tvb_compat(tvb, &this_pd, &this_offset); - tf = proto_tree_add_text(fh_tree, tvb, offset, length, "Options: (%d byte%s)", length, plurality(length, "", "s")); field_tree = proto_item_add_subtree(tf, options_subtree_index); - dissect_ip_tcp_options(&this_pd[this_offset + offset],this_offset + offset, - length, opts, nopts, -1, field_tree); + dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1, + field_tree); } } break; diff --git a/packet-raw.c b/packet-raw.c index cad834baa1..edb145565f 100644 --- a/packet-raw.c +++ b/packet-raw.c @@ -1,7 +1,7 @@ /* packet-raw.c * Routines for raw packet disassembly * - * $Id: packet-raw.c,v 1.19 2000/11/17 21:00:35 gram Exp $ + * $Id: packet-raw.c,v 1.20 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -43,6 +43,8 @@ static gint ett_raw = -1; static const char zeroes[10]; +static dissector_handle_t ip_handle; + void capture_raw(const u_char *pd, packet_counts *ld) { @@ -82,8 +84,6 @@ dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_tree *fh_tree; proto_item *ti; tvbuff_t *next_tvb; - const guint8 *next_pd; - int next_offset; /* load the top pane info. This should be overwritten by the next protocol in the stack */ @@ -132,13 +132,13 @@ dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* ...and if the connection is currently down, it sends 10 bytes of zeroes * instead of a fake MAC address and PPP header. */ else if (memcmp(tvb_get_ptr(tvb, 0, 10), zeroes, 10) == 0) { - tvb_compat(tvb, &next_pd, &next_offset); - dissect_ip(next_pd, next_offset + 10, pinfo->fd, tree); + next_tvb = tvb_new_subset(tvb, 10, -1, -1); + call_dissector(ip_handle, next_tvb, pinfo, tree); return; } else { - tvb_compat(tvb, &next_pd, &next_offset); - dissect_ip(next_pd, next_offset, pinfo->fd, tree); + next_tvb = tvb_new_subset(tvb, 0, -1, -1); + call_dissector(ip_handle, next_tvb, pinfo, tree); return; } g_assert_not_reached(); @@ -153,3 +153,12 @@ proto_register_raw(void) proto_register_subtree_array(ett, array_length(ett)); } + +void +proto_reg_handoff_raw(void) +{ + /* + * Get a handle for the IP dissector. + */ + ip_handle = find_dissector("ip"); +} diff --git a/packet-socks.c b/packet-socks.c index add97af74f..2387ac2fca 100644 --- a/packet-socks.c +++ b/packet-socks.c @@ -2,7 +2,7 @@ * Routines for socks versions 4 &5 packet dissection * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> * - * $Id: packet-socks.c,v 1.13 2000/10/21 05:52:23 guy Exp $ + * $Id: packet-socks.c,v 1.14 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -366,6 +366,7 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd, conversation_t *conversation; proto_tree *socks_tree; proto_item *ti; + tvbuff_t *tvb; conversation = find_conversation( &pi.src, &pi.dst, pi.ptype, pi.srcport, pi.destport, 0); @@ -420,7 +421,8 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd, *ptr = hash_info->udp_remote_port; - decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport); + tvb = tvb_create_from_top(0); + decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport); *ptr = hash_info->udp_port; @@ -923,6 +925,7 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd, /* payload, and restore the pi port after that is done. */ guint32 *ptr; + tvbuff_t *tvb; if (( hash_info->command == PING_COMMAND) || ( hash_info->command == TRACERT_COMMAND)) @@ -939,7 +942,8 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd, ptr = &pi.srcport; *ptr = hash_info->port; - decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport); + tvb = tvb_create_from_top(0); + decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport); *ptr = TCP_PORT_SOCKS; } } diff --git a/packet-tcp.c b/packet-tcp.c index a7e82a8d1f..d37600cad6 100644 --- a/packet-tcp.c +++ b/packet-tcp.c @@ -1,7 +1,7 @@ /* packet-tcp.c * Routines for TCP packet disassembly * - * $Id: packet-tcp.c,v 1.87 2000/11/05 09:26:47 oabad Exp $ + * $Id: packet-tcp.c,v 1.88 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -163,32 +163,38 @@ tcp_info_append_uint(const char *abbrev, guint32 val) { } static void -dissect_tcpopt_maxseg(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: %u bytes", optp->name, pntohs(opd)); - tcp_info_append_uint("MSS", pntohs(opd)); + guint16 mss; + + mss = tvb_get_ntohs(tvb, offset + 2); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: %u bytes", optp->name, mss); + tcp_info_append_uint("MSS", mss); } static void -dissect_tcpopt_wscale(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: %u bytes", optp->name, *opd); - tcp_info_append_uint("WS", *opd); + guint8 ws; + + ws = tvb_get_guint8(tvb, offset + 2); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: %u bytes", optp->name, ws); + tcp_info_append_uint("WS", ws); } static void -dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { proto_tree *field_tree = NULL; proto_item *tf; guint leftedge, rightedge; - tf = proto_tree_add_text(opt_tree, NullTVB, offset, optlen, "%s:", optp->name); + tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name); offset += 2; /* skip past type and length */ optlen -= 2; /* subtract size of type and length */ while (optlen > 0) { @@ -197,24 +203,21 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd, field_tree = proto_item_add_subtree(tf, *optp->subtree_index); } if (optlen < 4) { - proto_tree_add_text(field_tree, NullTVB, offset, optlen, + proto_tree_add_text(field_tree, tvb, offset, optlen, "(suboption would go past end of option)"); break; } - /* XXX - check whether it goes past end of packet */ - leftedge = pntohl(opd); - opd += 4; + leftedge = tvb_get_ntohl(tvb, offset); optlen -= 4; if (optlen < 4) { - proto_tree_add_text(field_tree, NullTVB, offset, optlen, + proto_tree_add_text(field_tree, tvb, offset, optlen, "(suboption would go past end of option)"); break; } /* XXX - check whether it goes past end of packet */ - rightedge = pntohl(opd); - opd += 4; + rightedge = tvb_get_ntohl(tvb, offset + 4); optlen -= 4; - proto_tree_add_text(field_tree, NullTVB, offset, 8, + proto_tree_add_text(field_tree, tvb, offset, 8, "left edge = %u, right edge = %u", leftedge, rightedge); tcp_info_append_uint("SLE", leftedge); tcp_info_append_uint("SRE", rightedge); @@ -223,31 +226,41 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd, } static void -dissect_tcpopt_echo(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: %u", optp->name, pntohl(opd)); - tcp_info_append_uint("ECHO", pntohl(opd)); + guint32 echo; + + echo = tvb_get_ntohl(tvb, offset + 2); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: %u", optp->name, echo); + tcp_info_append_uint("ECHO", echo); } static void -dissect_tcpopt_timestamp(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: tsval %u, tsecr %u", optp->name, pntohl(opd), pntohl(opd + 4)); - tcp_info_append_uint("TSV", pntohl(opd)); - tcp_info_append_uint("TSER", pntohl(opd + 4)); + guint32 tsv, tser; + + tsv = tvb_get_ntohl(tvb, offset + 2); + tser = tvb_get_ntohl(tvb, offset + 6); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: tsval %u, tsecr %u", optp->name, tsv, tser); + tcp_info_append_uint("TSV", tsv); + tcp_info_append_uint("TSER", tser); } static void -dissect_tcpopt_cc(const ip_tcp_opt *optp, const u_char *opd, +dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset, guint optlen, proto_tree *opt_tree) { - proto_tree_add_text(opt_tree, NullTVB, offset, optlen, - "%s: %u", optp->name, pntohl(opd)); - tcp_info_append_uint("CC", pntohl(opd)); + guint32 cc; + + cc = tvb_get_ntohl(tvb, offset + 2); + proto_tree_add_text(opt_tree, tvb, offset, optlen, + "%s: %u", optp->name, cc); + tcp_info_append_uint("CC", cc); } static const ip_tcp_opt tcpopts[] = { @@ -363,14 +376,20 @@ static const true_false_string flags_set_truth = { /* can call to it, ie. socks */ void -decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, - int src_port, int dst_port) +decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, int src_port, int dst_port) { + tvbuff_t *next_tvb; + const u_char *next_pd; + int next_offset; + + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + /* determine if this packet is part of a conversation and call dissector */ /* for the conversation if available */ - if (old_try_conversation_dissector(&pi.src, &pi.dst, PT_TCP, - src_port, dst_port, pd, offset, fd, tree)) + if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP, + src_port, dst_port, next_tvb, pinfo, tree)) return; /* try to apply the plugins */ @@ -379,10 +398,11 @@ decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, plugin *pt_plug = plugin_list; if (enabled_plugins_number > 0) { + tvb_compat(next_tvb, &next_pd, &next_offset); while (pt_plug) { if (pt_plug->enabled && strstr(pt_plug->protocol, "tcp") && - tree && dfilter_apply(pt_plug->filter, tree, pd, fd->cap_len)) { - pt_plug->dissector(pd, offset, fd, tree); + tree && dfilter_apply(pt_plug->filter, tree, next_pd, pinfo->fd->cap_len)) { + pt_plug->dissector(next_pd, next_offset, pinfo->fd, tree); return; } pt_plug = pt_plug->next; @@ -392,39 +412,42 @@ decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, #endif /* do lookup with the subdissector table */ - if (old_dissector_try_port(subdissector_table, src_port, pd, offset, fd, tree) || - old_dissector_try_port(subdissector_table, dst_port, pd, offset, fd, tree)) + if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) || + dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree)) return; /* do lookup with the heuristic subdissector table */ - if (old_dissector_try_heuristic(heur_subdissector_list, pd, offset, fd, tree)) + if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)) return; /* Oh, well, we don't know this; dissect it as data. */ - old_dissect_data(pd, offset, fd, tree); + dissect_data(next_tvb, 0, pinfo, tree); } static void -dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { +dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ e_tcphdr th; proto_tree *tcp_tree = NULL, *field_tree = NULL; proto_item *ti, *tf; + int offset = 0; gchar flags[64] = "<None>"; gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" }; gint fpos = 0, i; guint bpos; guint hlen; guint optlen; - guint packet_max = pi.len; guint32 seglen; guint32 nxtseq; + guint length_remaining; + + CHECK_DISPLAY_AS_DATA(proto_tcp, tvb, pinfo, tree); - OLD_CHECK_DISPLAY_AS_DATA(proto_tcp, pd, offset, fd, tree); + pinfo->current_proto = "TCP"; - /* To do: Check for {cap len,pkt len} < struct len */ /* Avoids alignment problems on many architectures. */ - memcpy(&th, &pd[offset], sizeof(e_tcphdr)); + tvb_memcpy(tvb, (guint8 *)&th, offset, sizeof(e_tcphdr)); th.th_sport = ntohs(th.th_sport); th.th_dport = ntohs(th.th_dport); th.th_win = ntohs(th.th_win); @@ -439,7 +462,7 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { info_len = 0; - if (check_col(fd, COL_INFO) || tree) { + if (check_col(pinfo->fd, COL_INFO) || tree) { for (i = 0; i < 8; i++) { bpos = 1 << i; if (th.th_flags & bpos) { @@ -457,14 +480,14 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { hlen = hi_nibble(th.th_off_x2) * 4; /* TCP header length, in bytes */ /* Compute the length of data in this segment. */ - seglen = pi.len - (offset + hlen); + seglen = tvb_reported_length(tvb) - hlen; /* Compute the sequence number of next octet after this segment. */ nxtseq = th.th_seq + seglen; - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "TCP"); - if (check_col(fd, COL_INFO)) { + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "TCP"); + if (check_col(pinfo->fd, COL_INFO)) { /* Copy the data into info_str in case one of the option handling routines needs to append to it. */ if (th.th_flags & TH_URG) @@ -480,40 +503,40 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { if (tree) { if (g_tcp_summary_in_tree) { - ti = proto_tree_add_protocol_format(tree, proto_tcp, NullTVB, offset, hlen, "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u", get_tcp_port(th.th_sport), th.th_sport, get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack); + ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, offset, hlen, "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u", get_tcp_port(th.th_sport), th.th_sport, get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack); } else { - ti = proto_tree_add_item(tree, proto_tcp, NullTVB, offset, hlen, FALSE); + ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE); } tcp_tree = proto_item_add_subtree(ti, ett_tcp); - proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, NullTVB, offset, 2, th.th_sport, + proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th.th_sport, "Source port: %s (%u)", get_tcp_port(th.th_sport), th.th_sport); - proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, NullTVB, offset + 2, 2, th.th_dport, + proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th.th_dport, "Destination port: %s (%u)", get_tcp_port(th.th_dport), th.th_dport); - proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, NullTVB, offset, 2, th.th_sport); - proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, NullTVB, offset + 2, 2, th.th_dport); - proto_tree_add_uint(tcp_tree, hf_tcp_seq, NullTVB, offset + 4, 4, th.th_seq); + proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th.th_sport); + proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th.th_dport); + proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th.th_seq); if (nxtseq != th.th_seq) - proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, NullTVB, offset, 0, nxtseq); + proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq); if (th.th_flags & TH_ACK) - proto_tree_add_uint(tcp_tree, hf_tcp_ack, NullTVB, offset + 8, 4, th.th_ack); - proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, NullTVB, offset + 12, 1, hlen, + proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th.th_ack); + proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen, "Header length: %u bytes", hlen); - tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, NullTVB, offset + 13, 1, + tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1, th.th_flags, "Flags: 0x%04x (%s)", th.th_flags, flags); field_tree = proto_item_add_subtree(tf, ett_tcp_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_push, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, NullTVB, offset + 13, 1, th.th_flags); - proto_tree_add_uint(tcp_tree, hf_tcp_window_size, NullTVB, offset + 14, 2, th.th_win); - proto_tree_add_uint(tcp_tree, hf_tcp_checksum, NullTVB, offset + 16, 2, th.th_sum); + proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th.th_flags); + proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th.th_win); + proto_tree_add_uint(tcp_tree, hf_tcp_checksum, tvb, offset + 16, 2, th.th_sum); if (th.th_flags & TH_URG) - proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, NullTVB, offset + 18, 2, th.th_urp); + proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th.th_urp); } /* Decode TCP options, if any. */ @@ -521,26 +544,27 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { /* There's more than just the fixed-length header. Decode the options. */ optlen = hlen - sizeof (e_tcphdr); /* length of options, in bytes */ - tf = proto_tree_add_text(tcp_tree, NullTVB, offset + 20, optlen, + tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen, "Options: (%d bytes)", optlen); field_tree = proto_item_add_subtree(tf, ett_tcp_options); - dissect_ip_tcp_options(&pd[offset + 20], offset + 20, optlen, + dissect_ip_tcp_options(tvb, offset + 20, optlen, tcpopts, N_TCP_OPTS, TCPOPT_EOL, field_tree); } - if (check_col(fd, COL_INFO)) - col_add_str(fd, COL_INFO, info_str); + if (check_col(pinfo->fd, COL_INFO)) + col_add_str(pinfo->fd, COL_INFO, info_str); /* Skip over header + options */ offset += hlen; - pi.ptype = PT_TCP; - pi.srcport = th.th_sport; - pi.destport = th.th_dport; + pinfo->ptype = PT_TCP; + pinfo->srcport = th.th_sport; + pinfo->destport = th.th_dport; /* Check the packet length to see if there's more data (it could be an ACK-only packet) */ - if (packet_max > offset) { + length_remaining = tvb_length_remaining(tvb, offset); + if (length_remaining != 0) { if (th.th_flags & TH_RST) { /* * RFC1122 says: @@ -557,23 +581,23 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { * * so for segments with RST we just display the data as text. */ - proto_tree_add_text(tcp_tree, NullTVB, offset, END_OF_FRAME, + proto_tree_add_text(tcp_tree, tvb, offset, length_remaining, "Reset cause: %s", - format_text(&pd[offset], END_OF_FRAME)); + tvb_format_text(tvb, offset, length_remaining)); } else - decode_tcp_ports( pd, offset, fd, tree, th.th_sport, th.th_dport); + decode_tcp_ports( tvb, offset, pinfo, tree, th.th_sport, th.th_dport); } if( data_out_file ) { reassemble_tcp( th.th_seq, /* sequence number */ seglen, /* data length */ - ( pd+offset ), /* data */ - ( pi.captured_len - offset ), /* captured data length */ + tvb_get_ptr(tvb, offset, length_remaining), /* data */ + length_remaining, /* captured data length */ ( th.th_flags & TH_SYN ), /* is syn set? */ - &pi.net_src, - &pi.net_dst, - pi.srcport, - pi.destport); + &pinfo->net_src, + &pinfo->net_dst, + pinfo->srcport, + pinfo->destport); } } @@ -685,5 +709,5 @@ proto_register_tcp(void) void proto_reg_handoff_tcp(void) { - old_dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp); + dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp); } diff --git a/packet-tcp.h b/packet-tcp.h index 69045dead6..6cdba3dfe8 100644 --- a/packet-tcp.h +++ b/packet-tcp.h @@ -1,6 +1,6 @@ /* packet-tcp.h * - * $Id: packet-tcp.h,v 1.5 2000/08/11 13:33:59 deniel Exp $ + * $Id: packet-tcp.h,v 1.6 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -28,7 +28,7 @@ /* Urgent pointer value for the current packet. */ extern guint16 tcp_urgent_pointer; -extern void decode_tcp_ports(const u_char *, int, frame_data *, +extern void decode_tcp_ports(tvbuff_t *, int, packet_info *, proto_tree *, int, int); #endif diff --git a/packet-udp.c b/packet-udp.c index 2ccf2f175c..cd39e75914 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,7 +1,7 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.77 2000/11/05 09:26:47 oabad Exp $ + * $Id: packet-udp.c,v 1.78 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -82,14 +82,20 @@ static heur_dissector_list_t heur_subdissector_list; /* can call to it, ie. socks */ void -decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, - int uh_sport, int uh_dport) +decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, int uh_sport, int uh_dport) { + tvbuff_t *next_tvb; + const u_char *next_pd; + int next_offset; + + next_tvb = tvb_new_subset(tvb, offset, -1, -1); + /* determine if this packet is part of a conversation and call dissector */ /* for the conversation if available */ - if (old_try_conversation_dissector(&pi.src, &pi.dst, PT_UDP, - uh_sport, uh_dport, pd, offset, fd, tree)) + if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_UDP, + uh_sport, uh_dport, next_tvb, pinfo, tree)) return; /* try to apply the plugins */ @@ -98,10 +104,11 @@ decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, plugin *pt_plug = plugin_list; if (enabled_plugins_number > 0) { + tvb_compat(next_tvb, &next_pd, &next_offset); while (pt_plug) { if (pt_plug->enabled && strstr(pt_plug->protocol, "udp") && - tree && dfilter_apply(pt_plug->filter, tree, pd, fd->cap_len)) { - pt_plug->dissector(pd, offset, fd, tree); + tree && dfilter_apply(pt_plug->filter, tree, next_pd, pinfo->fd->cap_len)) { + pt_plug->dissector(next_pd, next_offset, pinfo->fd, tree); return; } pt_plug = pt_plug->next; @@ -111,77 +118,77 @@ decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, #endif /* do lookup with the subdissector table */ - if (old_dissector_try_port(udp_dissector_table, uh_sport, pd, offset, fd, tree) || - old_dissector_try_port(udp_dissector_table, uh_dport, pd, offset, fd, tree)) + if (dissector_try_port(udp_dissector_table, uh_sport, next_tvb, pinfo, tree) || + dissector_try_port(udp_dissector_table, uh_dport, next_tvb, pinfo, tree)) return; /* do lookup with the heuristic subdissector table */ - if (old_dissector_try_heuristic(heur_subdissector_list, pd, offset, fd, tree)) + if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)) return; /* XXX - we should do these with the subdissector table as well. */ #define PORT_IS(port) (uh_sport == port || uh_dport == port) if (PORT_IS(UDP_PORT_VINES)) { /* FIXME: AFAIK, src and dst port must be the same */ - dissect_vines_frp(pd, offset, fd, tree); + tvb_compat(next_tvb, &next_pd, &next_offset); + dissect_vines_frp(next_pd, next_offset, pinfo->fd, tree); } else - old_dissect_data(pd, offset, fd, tree); + dissect_data(next_tvb, 0, pinfo, tree); } static void -dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { +dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ e_udphdr uh; guint16 uh_sport, uh_dport, uh_ulen, uh_sum; proto_tree *udp_tree; proto_item *ti; + int offset = 0; - OLD_CHECK_DISPLAY_AS_DATA(proto_udp, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_udp, tvb, pinfo, tree); - if (!BYTES_ARE_IN_FRAME(offset, sizeof(e_udphdr))) { - old_dissect_data(pd, offset, fd, tree); - return; - } + pinfo->current_proto = "UDP"; /* Avoids alignment problems on many architectures. */ - memcpy(&uh, &pd[offset], sizeof(e_udphdr)); + tvb_memcpy(tvb, (guint8 *)&uh, offset, sizeof(e_udphdr)); uh_sport = ntohs(uh.uh_sport); uh_dport = ntohs(uh.uh_dport); uh_ulen = ntohs(uh.uh_ulen); uh_sum = ntohs(uh.uh_sum); - if (check_col(fd, COL_PROTOCOL)) - col_add_str(fd, COL_PROTOCOL, "UDP"); - if (check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Source port: %s Destination port: %s", + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_add_str(pinfo->fd, COL_PROTOCOL, "UDP"); + if (check_col(pinfo->fd, COL_INFO)) + col_add_fstr(pinfo->fd, COL_INFO, "Source port: %s Destination port: %s", get_udp_port(uh_sport), get_udp_port(uh_dport)); if (tree) { - ti = proto_tree_add_item(tree, proto_udp, NullTVB, offset, 8, FALSE); + ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE); udp_tree = proto_item_add_subtree(ti, ett_udp); - proto_tree_add_uint_format(udp_tree, hf_udp_srcport, NullTVB, offset, 2, uh_sport, + proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, uh_sport, "Source port: %s (%u)", get_udp_port(uh_sport), uh_sport); - proto_tree_add_uint_format(udp_tree, hf_udp_dstport, NullTVB, offset + 2, 2, uh_dport, + proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, uh_dport, "Destination port: %s (%u)", get_udp_port(uh_dport), uh_dport); - proto_tree_add_uint_hidden(udp_tree, hf_udp_port, NullTVB, offset, 2, uh_sport); - proto_tree_add_uint_hidden(udp_tree, hf_udp_port, NullTVB, offset+2, 2, uh_dport); + proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset, 2, uh_sport); + proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset+2, 2, uh_dport); - proto_tree_add_uint(udp_tree, hf_udp_length, NullTVB, offset + 4, 2, uh_ulen); - proto_tree_add_uint_format(udp_tree, hf_udp_checksum, NullTVB, offset + 6, 2, uh_sum, + proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, uh_ulen); + proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, uh_sum, "Checksum: 0x%04x", uh_sum); } /* Skip over header */ offset += 8; - pi.ptype = PT_UDP; - pi.srcport = uh_sport; - pi.destport = uh_dport; + pinfo->ptype = PT_UDP; + pinfo->srcport = uh_sport; + pinfo->destport = uh_dport; /* call sub-dissectors */ - decode_udp_ports( pd, offset, fd, tree, uh_sport, uh_dport); + decode_udp_ports( tvb, offset, pinfo, tree, uh_sport, uh_dport); } @@ -225,5 +232,5 @@ proto_register_udp(void) void proto_reg_handoff_udp(void) { - old_dissector_add("ip.proto", IP_PROTO_UDP, dissect_udp); + dissector_add("ip.proto", IP_PROTO_UDP, dissect_udp); } diff --git a/packet-udp.h b/packet-udp.h index 9521d4a0fc..c8192690e3 100644 --- a/packet-udp.h +++ b/packet-udp.h @@ -1,6 +1,6 @@ /* packet-udp.h * - * $Id: packet-udp.h,v 1.4 2000/08/11 13:33:58 deniel Exp $ + * $Id: packet-udp.h,v 1.5 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -25,7 +25,7 @@ #ifndef __PACKET_UDP_H__ #define __PACKET_UDP_H__ -extern void decode_udp_ports(const u_char *, int, frame_data *, +extern void decode_udp_ports(tvbuff_t *, int, packet_info *, proto_tree *, int, int); #endif diff --git a/packet-vlan.c b/packet-vlan.c index adcbfdb96d..c0ffdcff7b 100644 --- a/packet-vlan.c +++ b/packet-vlan.c @@ -1,7 +1,7 @@ /* packet-vlan.c * Routines for VLAN 802.1Q ethernet header disassembly * - * $Id: packet-vlan.c,v 1.23 2000/11/13 05:22:58 guy Exp $ + * $Id: packet-vlan.c,v 1.24 2000/11/18 10:38:25 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -79,6 +79,7 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvbuff_t *volatile next_tvb; tvbuff_t *volatile trailer_tvb; proto_tree *volatile vlan_tree; + guint length_before, length; CHECK_DISPLAY_AS_DATA(proto_vlan, tvb, pinfo, tree); @@ -107,7 +108,7 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } if ( encap_proto <= IEEE_802_3_MAX_LEN) { - /* Give the next dissector only 'length' number of bytes */ + /* Give the next dissector only 'encap_proto' number of bytes */ proto_tree_add_uint(vlan_tree, hf_vlan_len, tvb, 2, 2, encap_proto); TRY { next_tvb = tvb_new_subset(tvb, 4, encap_proto, encap_proto); @@ -160,21 +161,40 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } else { dissect_ipx(next_tvb, pinfo, tree); } + } else { + length_before = tvb_reported_length(tvb); + length = ethertype(encap_proto, tvb, 4, pinfo, tree, vlan_tree, + hf_vlan_etype) + 4; + if (length < length_before) { + /* + * Create a tvbuff for the padding. + */ + TRY { + trailer_tvb = tvb_new_subset(tvb, length, -1, -1); + } + CATCH2(BoundsError, ReportedBoundsError) { + /* The packet doesn't have "length" bytes worth of captured + data left in it. No trailer to display. */ + trailer_tvb = NULL; + } + ENDTRY; + } else { + /* No padding. */ + trailer_tvb = NULL; + } + } - /* If there's some bytes left over, mark them. */ - if (trailer_tvb && tree) { - int trailer_length; - const guint8 *ptr; + /* If there's some bytes left over, mark them. */ + if (trailer_tvb && tree) { + int trailer_length; + const guint8 *ptr; - trailer_length = tvb_length(trailer_tvb); - if (trailer_length > 0) { - ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length); - proto_tree_add_bytes(vlan_tree, hf_vlan_trailer, tvb, 4 + encap_proto, - trailer_length, ptr); - } + trailer_length = tvb_length(trailer_tvb); + if (trailer_length > 0) { + ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length); + proto_tree_add_bytes(vlan_tree, hf_vlan_trailer, trailer_tvb, 0, + trailer_length, ptr); } - } else { - ethertype(encap_proto, tvb, 4, pinfo, tree, vlan_tree, hf_vlan_etype); } } diff --git a/packet-x25.c b/packet-x25.c index 5cfee0201a..694a830393 100644 --- a/packet-x25.c +++ b/packet-x25.c @@ -2,7 +2,7 @@ * Routines for x25 packet disassembly * Olivier Abad <oabad@cybercable.fr> * - * $Id: packet-x25.c,v 1.36 2000/11/16 07:35:38 guy Exp $ + * $Id: packet-x25.c,v 1.37 2000/11/18 10:38:26 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -173,7 +173,7 @@ static const value_string vals_x25_type[] = { typedef struct _vc_info { guint32 first_frame_secs, first_frame_usecs; guint32 last_frame_secs, last_frame_usecs; - void (*dissect)(const u_char *, int, frame_data *, proto_tree *); + dissector_t dissect; struct _vc_info *next; } vc_info; @@ -191,7 +191,7 @@ typedef struct _global_vc_info { static global_vc_info *hash_table[64]; -void +static void free_vc_info(vc_info *pt) { vc_info *vci = pt; @@ -225,10 +225,9 @@ reinit_x25_hashtable(void) } } -void +static void x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, - void (*dissect)(const u_char *, int, frame_data *, - proto_tree *)) + dissector_t dissect) { int idx = vc % 64; global_vc_info *hash_ent; @@ -308,7 +307,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs, } } -void +static void x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs) { global_vc_info *hash_ent = hash_table[vc%64]; @@ -324,7 +323,8 @@ x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs) vci->last_frame_usecs = frame_usecs; } -void (*x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc))(const u_char *, int, frame_data *, proto_tree *) +static dissector_t +x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc) { global_vc_info *hash_ent = hash_table[vc%64]; vc_info *vci; @@ -621,7 +621,7 @@ static char *registration_code(unsigned char code) return buffer; } -void +static void dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb) { guint8 fac, byte1, byte2, byte3; @@ -1200,7 +1200,7 @@ dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb) } } -void +static void x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb, frame_data *fd, gboolean toa) { @@ -1289,7 +1289,7 @@ x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb, (*offset) += ((len1 + len2 + 1) / 2); } -int +static int get_x25_pkt_len(tvbuff_t *tvb) { int length, called_len, calling_len, dte_len, dce_len; @@ -1394,13 +1394,11 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) int x25_pkt_len; int modulo; guint16 vc; - void (*dissect)(const u_char *, int, frame_data *, proto_tree *); + dissector_t dissect; gboolean toa; /* TOA/NPI address format */ guint16 bytes0_1; guint8 pkt_type; tvbuff_t *next_tvb; - const guint8 *next_pd; - int next_offset; pinfo->current_proto = "X.25"; @@ -1921,16 +1919,15 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if (localoffset >= tvb_reported_length(tvb)) return; next_tvb = tvb_new_subset(tvb, localoffset, -1, -1); - tvb_compat(next_tvb, &next_pd, &next_offset); /* search the dissector in the hash table */ if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc))) - (*dissect)(next_pd, next_offset, pinfo->fd, tree); + (*dissect)(next_tvb, pinfo, tree); else { /* If the Call Req. has not been captured, assume these packets carry IP */ if (tvb_get_guint8(tvb, localoffset) == 0x45) { x25_hash_add_proto_start(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs, dissect_ip); - dissect_ip(next_pd, next_offset, pinfo->fd, tree); + dissect_ip(next_tvb, pinfo, tree); } else { dissect_data(next_tvb, 0, pinfo, tree); |