aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-03-13 10:29:00 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-03-13 10:29:00 +0000
commitedcaaee164ad486bc1302d11f08a021d0301e8b5 (patch)
treee8b6570c770b12e2f948a637a9a15a2c37e04896
parent11c3d3d90dead7cbc4439cf6e70ac89182e61d90 (diff)
SCSI is fairly unique among the ethereal protocols in that it is sometimes normal for a PDU we receive back froma device to be truncated.
(report luns with allocation length 8 for example) Therefore it is a bit wrong to mark these packets as [malformed packets] Since they are truncated by scsi and this is NOTY an error condition. Add a new exception type : ScsiBoundsError If this exception is caught by packet-frame, then print an appropriate message instead of [malformed packet] For SCSI, add helper macros TRY_SCSI_SHORT_PACKET and END_... If the packet was not short in the normal sense (snaplen < packetlen) then intercept the exception for BoundsError and rethrow it as ScsiBoundsError instead. svn path=/trunk/; revision=17611
-rw-r--r--epan/dissectors/packet-frame.c11
-rw-r--r--epan/dissectors/packet-scsi.c48
-rw-r--r--epan/exceptions.h12
3 files changed, 70 insertions, 1 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index 3929956a4c..28d869ceeb 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -333,6 +333,17 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
switch (exception) {
+ case ScsiBoundsError:
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "[SCSI transfer limited due to allocation_length too small]");
+ /*item =*/ proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
+ "SCSI transfer limited due to allocation_length too small: %s truncated]", pinfo->current_proto);
+ /* Don't record ScsiBoundsError exceptions as expert events - they merely
+ * reflect a normal SCSI condition.
+ * (any case where it's caused by something else is a bug). */
+ /* expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Packet size limited");*/
+ break;
+
case BoundsError:
if (check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO, "[Packet size limited during capture]");
diff --git a/epan/dissectors/packet-scsi.c b/epan/dissectors/packet-scsi.c
index 1f2299e78a..2c7cc543d5 100644
--- a/epan/dissectors/packet-scsi.c
+++ b/epan/dissectors/packet-scsi.c
@@ -319,6 +319,48 @@ static int hf_ssc3_locate16_loid = -1;
static gint ett_scsi = -1;
static gint ett_scsi_page = -1;
+
+/* These two defines are used to handle cases where data coming back from
+ * the device is truncated due to a too short allocation_length specified
+ * in the command CDB.
+ * This is semi-common in SCSI and it would be wrong to mark these packets
+ * as [malformed packets].
+ * These macros will reset the reported length to what the data pdu specified
+ * and if a BoundsError is generated we will instead throw ScsiBoundsError
+ *
+ * Please see dissect_mmc4_getconfiguration() for an example how to use these
+ * macros.
+ */
+#define TRY_SCSI_SHORT_TRANSFER(tvb, length) \
+ { \
+ gboolean short_packet; \
+ tvbuff_t *new_tvb; \
+ \
+ short_packet=tvb_length(tvb) < tvb_reported_length(tvb); \
+ new_tvb=tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), length);\
+ tvb=new_tvb; \
+ offset=0; \
+ TRY {
+
+#define END_TRY_SCSI_SHORT_TRANSFER \
+ } /* TRY */ \
+ CATCH(BoundsError) { \
+ if(short_packet){ \
+ /* this was a short packet */ \
+ RETHROW; \
+ } else { \
+ /* this packet was not really short but limited \
+ * due to a short SCSI allocation length \
+ */ \
+ THROW(ScsiBoundsError); \
+ } \
+ } \
+ CATCH_ALL { \
+ RETHROW; \
+ } \
+ ENDTRY; \
+ }
+
typedef guint32 scsi_cmnd_type;
typedef guint32 scsi_device_type;
@@ -4060,7 +4102,10 @@ dissect_mmc4_getconfiguration (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
}
if(tree && (!isreq)) {
len=tvb_get_ntohl(tvb, offset+0);
- proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset+0, 4, 0);
+
+ TRY_SCSI_SHORT_TRANSFER(tvb, len); /* offset is reset to 0 */
+
+ proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 4, 0);
proto_tree_add_item (tree, hf_scsi_getconf_current_profile, tvb, offset+6, 2, 0);
offset+=8;
len-=4;
@@ -4153,6 +4198,7 @@ dissect_mmc4_getconfiguration (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
old_offset+=additional_length;
len-=4+additional_length;
}
+ END_TRY_SCSI_SHORT_TRANSFER;
}
}
diff --git a/epan/exceptions.h b/epan/exceptions.h
index a3d814cba9..92cf9a7ced 100644
--- a/epan/exceptions.h
+++ b/epan/exceptions.h
@@ -56,6 +56,18 @@
**/
#define DissectorError 4
+/**
+ Index is out of range.
+ An attempt was made to read past the end of a buffer.
+ This error is specific to SCSI data transfers where for some CDBs
+ it is normal that the data PDU might be short.
+ I.e. ReportLuns initially called with allocation_length=8, just enough
+ to get the "size" of lun list back after which the initiator will
+ reissue the command with an allocation_length that is big enough.
+**/
+#define ScsiBoundsError 5
+
+
/* Usage:
*
* TRY {