aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ppp.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet-ppp.c')
-rw-r--r--packet-ppp.c182
1 files changed, 139 insertions, 43 deletions
diff --git a/packet-ppp.c b/packet-ppp.c
index 59c7a721b3..9d1f72f721 100644
--- a/packet-ppp.c
+++ b/packet-ppp.c
@@ -1,7 +1,7 @@
/* packet-ppp.c
* Routines for ppp packet disassembly
*
- * $Id: packet-ppp.c,v 1.91 2002/04/24 06:03:34 guy Exp $
+ * $Id: packet-ppp.c,v 1.92 2002/05/20 00:56:30 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -1292,11 +1292,10 @@ static const unsigned short fcstab_16[256] = {
*******************************************************************************
*/
static guint16
-fcs16(register guint16 fcs,
- tvbuff_t * tvbuff,
- guint32 offset,
- guint32 len)
+fcs16(register guint16 fcs, tvbuff_t * tvbuff)
{
+ int offset = 0;
+ guint len = tvb_length(tvbuff);
guint8 val;
/* Check for Invalid Length */
@@ -1317,11 +1316,10 @@ fcs16(register guint16 fcs,
*******************************************************************************
*/
static guint32
-fcs32(guint32 fcs,
- tvbuff_t * tvbuff,
- guint32 offset,
- guint32 len)
+fcs32(guint32 fcs, tvbuff_t * tvbuff)
{
+ int offset = 0;
+ guint len = tvb_length(tvbuff);
guint8 val;
/* Check for invalid Length */
@@ -2132,7 +2130,9 @@ dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_cp( tvbuff_t *tvb, int proto_id, int proto_subtree_index,
const value_string *proto_vals, int options_subtree_index,
- const ip_tcp_opt *opts, int nopts, packet_info *pinfo, proto_tree *tree ) {
+ const ip_tcp_opt *opts, int nopts, packet_info *pinfo,
+ proto_tree *tree )
+{
proto_item *ti;
proto_tree *fh_tree = NULL;
proto_item *tf;
@@ -2256,37 +2256,34 @@ dissect_cp( tvbuff_t *tvb, int proto_id, int proto_subtree_index,
#define PFC_BIT 0x01
static void
-dissect_ppp_common( tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, proto_tree *fh_tree,
- proto_item *ti ) {
+dissect_ppp_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *fh_tree, proto_item *ti )
+{
guint16 ppp_prot;
int proto_len;
tvbuff_t *next_tvb;
- ppp_prot = tvb_get_guint8(tvb, offset);
+ ppp_prot = tvb_get_guint8(tvb, 0);
if (ppp_prot & PFC_BIT) {
/* Compressed protocol field - just the byte we fetched. */
proto_len = 1;
} else {
/* Uncompressed protocol field - fetch all of it. */
- ppp_prot = tvb_get_ntohs(tvb, offset);
+ ppp_prot = tvb_get_ntohs(tvb, 0);
proto_len = 2;
}
/* If "ti" is not null, it refers to the top-level "proto_ppp" item
for PPP, and was given a length equal to the length of any
stuff in the header preceding the protocol type, e.g. an HDLC
- header, which is just "offset"; add the length of the protocol
- type field to it. */
+ header; add the length of the protocol type field to it. */
if (ti != NULL)
- proto_item_set_len(ti, offset + proto_len);
+ proto_item_set_len(ti, proto_item_get_len(ti) + proto_len);
- if (tree) {
- proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, offset, proto_len,
- ppp_prot);
- }
+ if (tree)
+ proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, 0, proto_len, ppp_prot);
- next_tvb = tvb_new_subset(tvb, offset + proto_len, -1, -1);
+ next_tvb = tvb_new_subset(tvb, proto_len, -1, -1);
/* do lookup with the subdissector table */
if (!dissector_try_port(subdissector_table, ppp_prot, next_tvb, pinfo, tree)) {
@@ -2603,7 +2600,7 @@ dissect_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
fh_tree = proto_item_add_subtree(ti, ett_ppp);
}
- dissect_ppp_common(tvb, 0, pinfo, tree, fh_tree, ti);
+ dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti);
}
/*
@@ -2611,11 +2608,14 @@ dissect_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
* a PPP in HDLC-like Framing frame (RFC 1662) or a Cisco HDLC frame.
*/
static void
-dissect_ppp_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
+dissect_ppp_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
proto_item *ti = NULL;
proto_tree *fh_tree = NULL;
guint8 byte0;
int proto_offset;
+ gint len, reported_len;
+ tvbuff_t *next_tvb;
int rx_fcs_offset;
guint32 rx_fcs_exp;
guint32 rx_fcs_got;
@@ -2658,29 +2658,126 @@ dissect_ppp_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
}
}
- dissect_ppp_common(tvb, proto_offset, pinfo, tree, fh_tree, ti);
+ /*
+ * Remove the FCS, if any, from the packet data.
+ */
+ switch (ppp_fcs_decode) {
+
+ case NO_FCS:
+ next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
+ break;
- /* Calculate the FCS check */
- /* XXX - deal with packets cut off by the snapshot length */
- if (ppp_fcs_decode == FCS_16) {
- rx_fcs_offset = tvb_length(tvb) - 2;
- rx_fcs_exp = fcs16(0xFFFF, tvb, 0, rx_fcs_offset);
- rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset);
- if (rx_fcs_got != rx_fcs_exp) {
- proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2, "FCS 16: 0x%04x (incorrect, should be %04x)", rx_fcs_got, rx_fcs_exp);
+ case FCS_16:
+ /*
+ * Do we have the entire packet, and does it include a 2-byte FCS?
+ */
+ len = tvb_length_remaining(tvb, proto_offset);
+ reported_len = tvb_reported_length_remaining(tvb, proto_offset);
+ if (reported_len < 2 || len < 0) {
+ /*
+ * The packet is claimed not to even have enough data for a 2-byte FCS,
+ * or we're already past the end of the captured data.
+ * Don't slice anything off.
+ */
+ next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
+ } else if (len < reported_len) {
+ /*
+ * The packet is claimed to have enough data for a 2-byte FCS, but
+ * we didn't capture all of the packet.
+ * Slice off the 2-byte FCS from the reported length, and trim the
+ * captured length so it's no more than the reported length; that
+ * will slice off what of the FCS, if any, is in the captured
+ * length.
+ */
+ reported_len -= 2;
+ if (len > reported_len)
+ len = reported_len;
+ next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
} else {
- proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2, "FCS 16: 0x%04x (correct)", rx_fcs_got);
+ /*
+ * We have the entire packet, and it includes a 2-byte FCS.
+ * Slice it off.
+ */
+ len -= 2;
+ reported_len -= 2;
+ next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
+
+ /*
+ * Compute the FCS and put it into the tree.
+ */
+ rx_fcs_offset = proto_offset + len;
+ rx_fcs_exp = fcs16(0xFFFF, next_tvb);
+ rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset);
+ if (rx_fcs_got != rx_fcs_exp) {
+ proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
+ "FCS 16: 0x%04x (incorrect, should be 0x%04x)",
+ rx_fcs_got, rx_fcs_exp);
+ } else {
+ proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
+ "FCS 16: 0x%04x (correct)",
+ rx_fcs_got);
+ }
}
- } else if (ppp_fcs_decode == FCS_32) {
- rx_fcs_offset = tvb_length(tvb) - 4;
- rx_fcs_exp = fcs32(0xFFFFFFFF, tvb, 0, rx_fcs_offset);
- rx_fcs_got = tvb_get_letohl(tvb, rx_fcs_offset);
- if (rx_fcs_got != rx_fcs_exp) {
- proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4, "FCS 32: 0x%08x (incorrect, should be %08x) ", rx_fcs_got, rx_fcs_exp);
+ break;
+
+ case FCS_32:
+ /*
+ * Do we have the entire packet, and does it include a 4-byte FCS?
+ */
+ len = tvb_length_remaining(tvb, proto_offset);
+ reported_len = tvb_reported_length_remaining(tvb, proto_offset);
+ if (reported_len < 4) {
+ /*
+ * The packet is claimed not to even have enough data for a 4-byte FCS.
+ * Just pass on the tvbuff as is.
+ */
+ next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
+ } else if (len < reported_len) {
+ /*
+ * The packet is claimed to have enough data for a 4-byte FCS, but
+ * we didn't capture all of the packet.
+ * Slice off the 4-byte FCS from the reported length, and trim the
+ * captured length so it's no more than the reported length; that
+ * will slice off what of the FCS, if any, is in the captured
+ * length.
+ */
+ reported_len -= 4;
+ if (len > reported_len)
+ len = reported_len;
+ next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
} else {
- proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4, "FCS 32: 0x%08x (correct)", rx_fcs_got);
+ /*
+ * We have the entire packet, and it includes a 4-byte FCS.
+ * Slice it off.
+ */
+ len -= 4;
+ reported_len -= 4;
+ next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
+
+ /*
+ * Compute the FCS and put it into the tree.
+ */
+ rx_fcs_offset = proto_offset + len;
+ rx_fcs_exp = fcs32(0xFFFFFFFF, next_tvb);
+ rx_fcs_got = tvb_get_letohl(tvb, rx_fcs_offset);
+ if (rx_fcs_got != rx_fcs_exp) {
+ proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
+ "FCS 32: 0x%08x (incorrect, should be 0x%08x)",
+ rx_fcs_got, rx_fcs_exp);
+ } else {
+ proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
+ "FCS 32: 0x%08x (correct)",
+ rx_fcs_got);
+ }
}
+ break;
+
+ default:
+ g_assert_not_reached();
+ next_tvb = NULL;
}
+
+ dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti);
}
/*
@@ -3354,4 +3451,3 @@ proto_reg_handoff_pppmux(void)
*/
dissector_add("ethertype", PPP_MUX, pppmux_handle);
}
-