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
/* 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>
/* 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[];
* 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>
*
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*
* 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>
*
/* 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*);
/* 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>
static gint ett_clip = -1;
+static dissector_handle_t ip_handle;
+
void
capture_clip( const u_char *pd, packet_counts *ld ) {
{
proto_tree *fh_tree;
proto_item *ti;
- const guint8 *this_pd;
- int this_offset;
pinfo->current_proto = "CLIP";
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
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");
+}
/* 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>
*
/* 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
/* 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 */
} /* 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)
{
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"));
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
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
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
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
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);
}
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;
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");
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");
}
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 */
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
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
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;
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;
}
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;
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;
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);
}
}
} /* 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 */
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");
}
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;
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;
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 */
} /* 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;
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;
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;
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;
}
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;
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;
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);
}
} /* 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
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;
}
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);
}
* 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;
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
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:
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;
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 */
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 */
}
/* 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
*/
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 */
* 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
/* 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
* 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;
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 );
}
}
* 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.
*
* 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 ) );
}
* 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
void
proto_reg_handoff_esis(void)
{
- old_dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis);
+ dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis);
}
/* 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
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 */
/* 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>
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);
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))
}
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;
}
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);
}
}
/* 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>
*
}
}
-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)
{
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 */
}
}
}
+
+ /* 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);
}
* 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>
{ 0, NULL }
};
+static dissector_handle_t ip_handle;
+
static void
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);
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");
}
/* 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>
#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 */
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
}
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;
{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;
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;
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;
}
/* 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)
{
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;
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)
}
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);
}
}
#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?)");
}
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?)");
}
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?)");
}
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:
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:
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;
}
}
"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
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);
}
/* 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>
#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 */
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 */
*
* (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>
#include <glib.h>
#include "etypes.h"
#include "packet.h"
-#include "packet-ip.h"
static gint proto_mpls = -1;
"" }},
};
+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",
offset += 4;
if (bos) break;
}
- dissect_ip(pd, offset, fd, tree);
+ old_call_dissector(ip_handle, pd, offset, fd, tree);
}
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");
}
* 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>
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);
*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;
}
* 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
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;
};
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;
{ 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 */
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;
}
};
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",
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" );
}
};
* 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;
/* 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
/*
* 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 */
* 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>
*
} /* 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? */
}
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 */
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);
}
/* 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>
* 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 */
* 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>
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) {
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 */
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");
+}
/* 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>
#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);
#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[] = {
}
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"));
}
};
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
};
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"));
}
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"));
}
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;
}
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. */
};
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
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;
/* 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>
static const char zeroes[10];
+static dissector_handle_t ip_handle;
+
void
capture_raw(const u_char *pd, packet_counts *ld)
{
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 */
/* ...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();
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");
+}
* 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>
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);
*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;
/* 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))
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;
}
}
/* 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>
}
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) {
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);
}
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[] = {
/* 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 */
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;
#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);
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) {
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)
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. */
/* 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:
*
* 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);
}
}
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);
}
/* 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>
/* 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
/* 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>
/* 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 */
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;
#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);
}
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);
}
/* 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>
#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
/* 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>
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);
}
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);
} 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);
}
}
* 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>
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;
static global_vc_info *hash_table[64];
-void
+static void
free_vc_info(vc_info *pt)
{
vc_info *vci = pt;
}
}
-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;
}
}
-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];
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;
return buffer;
}
-void
+static void
dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
{
guint8 fac, byte1, byte2, byte3;
}
}
-void
+static void
x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
frame_data *fd, gboolean toa)
{
(*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;
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";
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);