aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-11-18 10:38:33 +0000
committerGuy Harris <guy@alum.mit.edu>2000-11-18 10:38:33 +0000
commitc8196a1d1ca5a5021388cfc1bcbb64cdda5e9dc3 (patch)
tree5e117f446c6e233d14b642596d67c985e685f328
parent56a0c40c18271046d22bffcc5db10cfb16a2bf6c (diff)
Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
ESIS dissectors. Register the IP dissector and have dissectors that call it directly (rather than through a port table) call it through a handle. Add a routine "tvb_set_reported_length()" which a dissector can use if it was handed a tvbuff that contains more data than is actually in its part of the packet - for example, handing a padded Ethernet frame to IP; the routine sets the reported length of the tvbuff (and also adjusts the actual length, as appropriate). Then use it in IP. Given that, "ethertype()" can determine how much of the Ethernet frame was actually part of an IP datagram (and can do the same for other protocols under Ethernet that use "tvb_set_reported_length()"; have it return the actual length, and have "dissect_eth()" and "dissect_vlan()" use that to mark trailer data in Ethernet II frames as well as in 802.3 frames. svn path=/trunk/; revision=2658
-rw-r--r--epan/packet.h4
-rw-r--r--epan/tvbuff.c17
-rw-r--r--epan/tvbuff.h10
-rw-r--r--packet-clip.c18
-rw-r--r--packet-clnp.c861
-rw-r--r--packet-clnp.h4
-rw-r--r--packet-esis.c228
-rw-r--r--packet-esis.h8
-rw-r--r--packet-eth.c75
-rw-r--r--packet-ethertype.c10
-rw-r--r--packet-gre.c13
-rw-r--r--packet-ip.c457
-rw-r--r--packet-ip.h8
-rw-r--r--packet-mpls.c12
-rw-r--r--packet-msproxy.c8
-rw-r--r--packet-osi-options.c114
-rw-r--r--packet-osi-options.h6
-rw-r--r--packet-osi.c59
-rw-r--r--packet-osi.h6
-rw-r--r--packet-pim.c14
-rw-r--r--packet-ppp.c195
-rw-r--r--packet-raw.c23
-rw-r--r--packet-socks.c10
-rw-r--r--packet-tcp.c208
-rw-r--r--packet-tcp.h4
-rw-r--r--packet-udp.c77
-rw-r--r--packet-udp.h4
-rw-r--r--packet-vlan.c48
-rw-r--r--packet-x25.c31
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);