diff options
-rw-r--r-- | epan/dissectors/packet-frame.c | 11 | ||||
-rw-r--r-- | epan/dissectors/packet-scsi.c | 48 | ||||
-rw-r--r-- | epan/exceptions.h | 12 |
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 { |