summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-ppp.c341
1 files changed, 202 insertions, 139 deletions
diff --git a/epan/dissectors/packet-ppp.c b/epan/dissectors/packet-ppp.c
index 0e654ffbed..e2a87cf461 100644
--- a/epan/dissectors/packet-ppp.c
+++ b/epan/dissectors/packet-ppp.c
@@ -55,6 +55,10 @@ static int hf_ppp_protocol = -1;
static gint ett_ppp = -1;
+static int proto_ppp_hdlc = -1;
+
+static gint ett_ppp_hdlc_data = -1;
+
static int proto_lcp = -1;
static gint ett_lcp = -1;
@@ -3107,6 +3111,90 @@ dissect_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti, 0);
}
+static void
+dissect_ppp_hdlc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *fh_tree = NULL;
+ guint8 byte0;
+ int proto_offset;
+ tvbuff_t *next_tvb;
+
+ byte0 = tvb_get_guint8(tvb, 0);
+
+ /* PPP HDLC encapsulation */
+ if (byte0 == 0xff)
+ proto_offset = 2;
+ else {
+ /* address and control are compressed (NULL) */
+ proto_offset = 0;
+ }
+
+ /* load the top pane info. This should be overwritten by
+ the next protocol in the stack */
+ if(tree) {
+ ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, FALSE);
+ fh_tree = proto_item_add_subtree(ti, ett_ppp);
+ if (byte0 == 0xff) {
+ proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1, FALSE);
+ proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1, FALSE);
+ }
+ }
+
+ next_tvb = decode_fcs(tvb, fh_tree, ppp_fcs_decode, proto_offset);
+
+ dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
+}
+
+/*
+ * Handles link-layer encapsulations where the frame might be
+ * 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 )
+{
+ guint8 byte0;
+
+ byte0 = tvb_get_guint8(tvb, 0);
+ if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
+ /* Cisco HDLC encapsulation */
+ call_dissector(chdlc_handle, tvb, pinfo, tree);
+ return;
+ }
+
+ /*
+ * XXX - should we have an exported dissector that always dissects PPP,
+ * for use when we know the packets are PPP, not CHDLC?
+ */
+ if(check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
+ switch (pinfo->p2p_dir) {
+
+ case P2P_DIR_SENT:
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
+ break;
+
+ case P2P_DIR_RECV:
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
+ break;
+
+ default:
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
+ break;
+ }
+
+ dissect_ppp_hdlc_common(tvb, pinfo, tree);
+}
+
static tvbuff_t*
remove_escape_chars(tvbuff_t *tvb, int offset, int length)
{
@@ -3123,6 +3211,8 @@ remove_escape_chars(tvbuff_t *tvb, int offset, int length)
if (octet == 0x7d){
offset++;
scanned_len++;
+ if (scanned_len >= length)
+ break;
octet = tvb_get_guint8(tvb,offset);
buff[i] = octet ^ 0x20;
}else{
@@ -3132,6 +3222,8 @@ remove_escape_chars(tvbuff_t *tvb, int offset, int length)
scanned_len++;
i++;
}
+ if (i == 0)
+ return NULL;
next_tvb = tvb_new_real_data(buff,i,i);
/* Arrange that the allocated packet data copy be freed when the
@@ -3143,163 +3235,136 @@ remove_escape_chars(tvbuff_t *tvb, int offset, int length)
return next_tvb;
}
+
/*
- * Handles link-layer encapsulations 0x8881 where the frame might be
- * a PPP in HDLC-like Framing frame .
+ * Handles link-layer encapsulations where we have a raw RFC 1662
+ * HDLC-like asynchronous framing byte stream, and have to
+ * break the byte stream into frames and remove escapes.
*/
static void
-dissect_ppp_8881( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+dissect_ppp_raw_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
- proto_item *ti = NULL;
- proto_tree *fh_tree = NULL;
- guint8 byte0;
- int proto_offset;
- tvbuff_t *next_tvb,*ppp_tvb;
- gint end_offset;
- int offset = 0;
- int length;
- int tvb_length = tvb_length_remaining(tvb,offset);
+ proto_item *ti;
+ proto_tree *bs_tree = NULL;
+ gint offset, end_offset;
+ int length;
+ tvbuff_t *ppp_tvb;
+ gboolean first = TRUE;
if(check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP" );
- while ( offset < tvb_length ){
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_ppp_hdlc, tvb, 0, -1, FALSE);
+ bs_tree = proto_item_add_subtree(ti, ett_ppp_hdlc_data);
+ }
-
- byte0 = tvb_get_guint8(tvb, 0);
+ /*
+ * XXX - this needs to handle a PPP frame split over multiple higher-level
+ * packets.
+ */
+
+ /*
+ * Look for a frame delimiter.
+ */
+ offset = tvb_find_guint8(tvb, 0, -1, 0x7e);
+ if (offset == -1) {
+ /*
+ * None found - this is presumably continued from an earlier
+ * packet and continued in a later packet.
+ */
+ if (check_col(pinfo->cinfo, COL_INFO)){
+ col_add_str(pinfo->cinfo, COL_INFO,"PPP Fragment");
+ }
+ if (tree)
+ proto_tree_add_text(bs_tree, tvb, offset, -1, "PPP Fragment");
offset++;
- if (byte0 != 0x7e ){
- /* PPP Fragment */
- if(check_col(pinfo->cinfo, COL_INFO)){
- col_add_str(pinfo->cinfo, COL_INFO,"PPP Fragment");
- }
- proto_tree_add_text(tree, tvb, 0, -1, "PPP Fragment");
- length = tvb_length_remaining(tvb,offset);
- ppp_tvb = remove_escape_chars(tvb, offset,length);
+ length = tvb_length_remaining(tvb,offset);
+ ppp_tvb = remove_escape_chars(tvb, offset,length);
+ if (ppp_tvb != NULL) {
add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
call_dissector(data_handle, ppp_tvb, pinfo, tree);
- return;
}
-
- end_offset = tvb_find_guint8(tvb, offset,-1, 0x7e);
- if ( end_offset == -1){
- if(check_col(pinfo->cinfo, COL_INFO)){
- col_add_str(pinfo->cinfo, COL_INFO,"PPP Fragment");
+ return;
+ }
+ if (offset != 0) {
+ /*
+ * We have some data preceding the first PPP packet;
+ * mark it as a PPP fragment.
+ */
+ if(check_col(pinfo->cinfo, COL_INFO)){
+ col_add_str(pinfo->cinfo, COL_INFO,"PPP Fragment");
+ }
+ length = offset;
+ if (tree)
+ proto_tree_add_text(bs_tree, tvb, 0, length, "PPP Fragment");
+ if (length != 0) {
+ ppp_tvb = remove_escape_chars(tvb, 0, length - 1);
+ if (ppp_tvb != NULL) {
+ add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
+ call_dissector(data_handle, ppp_tvb, pinfo, tree);
}
-
- proto_tree_add_text(tree, tvb, 0, -1, "PPP Fragment");
- length = tvb_length_remaining(tvb,offset);
+ }
+ }
+ while ( tvb_reported_length_remaining(tvb, offset) > 0 ){
+ /*
+ * Look for the next frame delimiter.
+ */
+ end_offset = tvb_find_guint8(tvb, offset+1, -1, 0x7e);
+ if ( end_offset == -1 ){
+ /*
+ * We didn't find one. This is probably continued in
+ * a later packet.
+ */
+ if (first) {
+ if(check_col(pinfo->cinfo, COL_INFO)){
+ col_add_str(pinfo->cinfo, COL_INFO,"PPP Fragment");
+ }
+ }
+ if (tree)
+ proto_tree_add_text(bs_tree, tvb, offset, -1, "PPP Fragment");
+ offset++;
+ length = tvb_length_remaining(tvb, offset);
ppp_tvb = remove_escape_chars(tvb, offset,length);
- add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
- call_dissector(data_handle, ppp_tvb, pinfo, tree);
+ if (ppp_tvb != NULL) {
+ add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
+ call_dissector(data_handle, ppp_tvb, pinfo, tree);
+ }
return;
}
- length = end_offset - offset+1;
- g_warning("length(%u) = end_offset(%u) - offset(%u)+1",length,end_offset,offset);
- ppp_tvb = remove_escape_chars(tvb, offset,length);
- add_new_data_source(pinfo, ppp_tvb, "PPP Message");
-
- byte0 = tvb_get_guint8(ppp_tvb, 0);
-
- /* PPP HDLC encapsulation */
- if (byte0 == 0xff){
- proto_offset = 2;
- }else {
- /* address and control are compressed (NULL) */
- proto_offset = 0;
- }
-
- if(tree) {
- ti = proto_tree_add_item(tree, proto_ppp, ppp_tvb, 0, -1, FALSE);
- fh_tree = proto_item_add_subtree(ti, ett_ppp);
- if (byte0 == 0xff) {
- proto_tree_add_item(fh_tree, hf_ppp_address, ppp_tvb, 0, 1, FALSE);
- proto_tree_add_item(fh_tree, hf_ppp_control, ppp_tvb, 1, 1, FALSE);
- }
+ length = end_offset - offset;
+ if (tree)
+ proto_tree_add_text(bs_tree, tvb, offset, length, "PPP Data");
+ if (length > 1) {
+ ppp_tvb = remove_escape_chars(tvb, offset + 1, length - 1);
+ if (ppp_tvb != NULL) {
+ add_new_data_source(pinfo, ppp_tvb, "PPP Message");
+ dissect_ppp_hdlc_common(ppp_tvb, pinfo, tree);
+ first = FALSE;
+ }
}
- next_tvb = decode_fcs(ppp_tvb, fh_tree, ppp_fcs_decode, proto_offset);
-
- dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
- offset = end_offset + 1;
-
+ offset = end_offset;
} /* end while */
}
-/*
- * Handles link-layer encapsulations where the frame might be
- * 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 )
+void
+proto_register_ppp_raw_hdlc(void)
{
- proto_item *ti = NULL;
- proto_tree *fh_tree = NULL;
- guint8 byte0;
- int proto_offset;
- tvbuff_t *next_tvb;
-
- byte0 = tvb_get_guint8(tvb, 0);
- if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
- /* Cisco HDLC encapsulation */
- call_dissector(chdlc_handle, tvb, pinfo, tree);
- return;
- }
-
- /*
- * XXX - should we have a routine that always dissects PPP, for use
- * when we know the packets are PPP, not CHDLC?
- */
-
- /* PPP HDLC encapsulation */
- if (byte0 == 0xff)
- proto_offset = 2;
- else {
- /* address and control are compressed (NULL) */
- proto_offset = 0;
- }
-
- /* load the top pane info. This should be overwritten by
- the next protocol in the stack */
-
- if(check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP" );
-
- switch (pinfo->p2p_dir) {
-
- case P2P_DIR_SENT:
- if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
- col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
- if(check_col(pinfo->cinfo, COL_RES_DL_DST))
- col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
- break;
-
- case P2P_DIR_RECV:
- if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
- col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
- if(check_col(pinfo->cinfo, COL_RES_DL_DST))
- col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
- break;
-
- default:
- if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
- col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
- if(check_col(pinfo->cinfo, COL_RES_DL_DST))
- col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
- break;
- }
+ static gint *ett[] = {
+ &ett_ppp_hdlc_data
+ };
- if(tree) {
- ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, FALSE);
- fh_tree = proto_item_add_subtree(ti, ett_ppp);
- if (byte0 == 0xff) {
- proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1, FALSE);
- proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1, FALSE);
- }
- }
+ proto_ppp_hdlc = proto_register_protocol("PPP In HDLC-Like Framing", "PPP-HDLC", "ppp_hdlc");
+ proto_register_subtree_array(ett, array_length(ett));
+}
- next_tvb = decode_fcs(tvb, fh_tree, ppp_fcs_decode, proto_offset);
+void
+proto_reg_handoff_ppp_raw_hdlc(void)
+{
+ dissector_handle_t ppp_raw_hdlc_handle;
- dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
+ ppp_raw_hdlc_handle = create_dissector_handle(dissect_ppp_raw_hdlc, proto_ppp);
+ dissector_add("gre.proto", ETHERTYPE_CDMA2000_A10_UBS, ppp_raw_hdlc_handle);
}
/*
@@ -3543,7 +3608,7 @@ proto_register_ppp(void)
VALS(ppp_vals), 0x0, "", HFILL }},
};
static gint *ett[] = {
- &ett_ppp,
+ &ett_ppp
};
module_t *ppp_module;
@@ -3556,7 +3621,6 @@ proto_register_ppp(void)
ppp_subdissector_table = register_dissector_table("ppp.protocol",
"PPP protocol", FT_UINT16, BASE_HEX);
- register_dissector("ppp_8881", dissect_ppp_8881, proto_ppp);
register_dissector("ppp_hdlc", dissect_ppp_hdlc, proto_ppp);
register_dissector("ppp_lcp_options", dissect_lcp_options, proto_ppp);
register_dissector("ppp", dissect_ppp, proto_ppp);
@@ -3585,7 +3649,7 @@ proto_register_ppp(void)
void
proto_reg_handoff_ppp(void)
{
- dissector_handle_t ppp_8881_handle, ppp_hdlc_handle, ppp_handle;
+ dissector_handle_t ppp_hdlc_handle, ppp_handle;
/*
* Get a handle for the CHDLC dissector.
@@ -3593,14 +3657,13 @@ proto_reg_handoff_ppp(void)
chdlc_handle = find_dissector("chdlc");
data_handle = find_dissector("data");
- ppp_8881_handle = find_dissector("ppp_8881");
- ppp_hdlc_handle = find_dissector("ppp_hdlc");
ppp_handle = find_dissector("ppp");
+ dissector_add("fr.ietf", NLPID_PPP, ppp_handle);
+
+ ppp_hdlc_handle = find_dissector("ppp_hdlc");
dissector_add("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_handle);
dissector_add("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR, ppp_hdlc_handle);
- dissector_add("fr.ietf", NLPID_PPP, ppp_handle);
dissector_add("gre.proto", ETHERTYPE_PPP, ppp_hdlc_handle);
- dissector_add("gre.proto", ETHERTYPE_CDMA2000_A10_UBS, ppp_8881_handle);
}
void