aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-per.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-per.c')
-rw-r--r--epan/dissectors/packet-per.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/epan/dissectors/packet-per.c b/epan/dissectors/packet-per.c
index 4ab51e954b..d534f4d04f 100644
--- a/epan/dissectors/packet-per.c
+++ b/epan/dissectors/packet-per.c
@@ -1452,6 +1452,7 @@ dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, packet_info *pinfo, prot
static guint8 bytes[4];
guint8 *pbytes = NULL;
proto_item *pi;
+ tvbuff_t *out_tvb = NULL;
hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
@@ -1485,12 +1486,30 @@ DEBUG_ENTRY("dissect_per_octet_string");
} else if ((min_len==max_len)&&(min_len<65536)) { /* 16.7 if length is fixed and less than to 64k*/
/* align to byte */
-
- if (is_per_byte_aligned)
- BYTE_ALIGN_OFFSET(offset);
- val_start = offset>>3;
- val_length = min_len;
- offset+=min_len*8;
+ val_start = offset>>3;
+
+ if (is_per_byte_aligned){
+ BYTE_ALIGN_OFFSET(offset);
+ val_length = min_len;
+ offset+=min_len*8;
+ }else{
+ guint8 *buff;
+ guint32 i = 0;
+ guint32 j = 0;
+ gboolean bit;
+
+ buff = ep_alloc(min_len);
+ while (j < (guint32)min_len){
+ for(i=0;i<8;i++){
+ offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
+ buff[j]=(buff[j]<<1)|bit;
+ }
+ j = j+1;
+ }
+ pbytes = buff;
+ val_length = min_len;
+ /* XXX should we return a new tvb with the octetstring? */
+ }
} else { /* 16.8 */
if(max_len>0) {
@@ -1505,12 +1524,35 @@ DEBUG_ENTRY("dissect_per_octet_string");
if(length){
/* align to byte */
- if (is_per_byte_aligned)
+ if (is_per_byte_aligned){
BYTE_ALIGN_OFFSET(offset);
+ offset+=length*8;
+ val_start = offset>>3;
+ }else{
+ guint8 *buff;
+ guint32 i = 0;
+ guint32 j = 0;
+ gboolean bit;
+
+ val_start = offset>>3;
+ buff = g_malloc(length);
+ while (j < length){
+ for(i=0;i<8;i++){
+ offset=dissect_per_boolean(tvb, offset, pinfo, tree, -1, &bit, NULL);
+ buff[j]=(buff[j]<<1)|bit;
+ }
+ j = j+1;
+ }
+ pbytes = buff;
+ out_tvb = tvb_new_real_data(buff,length,length);
+ /* Arrange that the allocated packet data copy be freed when the
+ * tvbuff is freed.
+ */
+ tvb_set_free_cb(out_tvb, g_free );
+ tvb_set_child_real_data_tvbuff(tvb,out_tvb);
+ }
}
- val_start = offset>>3;
val_length = length;
- offset+=length*8;
}
if (hfi) {
@@ -1535,7 +1577,10 @@ DEBUG_ENTRY("dissect_per_octet_string");
}
}
if (value_tvb)
- *value_tvb = tvb_new_subset(tvb, val_start, val_length, val_length);
+ if (out_tvb)
+ *value_tvb = out_tvb;
+ else
+ *value_tvb = tvb_new_subset(tvb, val_start, val_length, val_length);
return offset;
}