/* real run, dissect the elements */
for(i=0;i<di->array_actual_count;i++){
+ old_offset = offset;
offset = (*fnct)(tvb, offset, pinfo, tree, drep);
+ if (offset <= old_offset)
+ THROW(ReportedBoundsError);
}
}
dcerpc_dissect_fnct_t *volatile sub_dissect;
const char *volatile saved_proto;
void *volatile saved_private_data;
- guint length, reported_length;
+ guint length = 0, reported_length = 0;
tvbuff_t *volatile stub_tvb;
volatile guint auth_pad_len;
volatile int auth_pad_offset;
proc->dissect_rqst : proc->dissect_resp;
if (tree) {
- sub_item = proto_tree_add_item (tree, sub_proto->proto_id, tvb, 0,
- -1, FALSE);
+ sub_item = proto_tree_add_item (tree, sub_proto->proto_id,
+ (decrypted_tvb != NULL)?decrypted_tvb:tvb,
+ 0, -1, FALSE);
if (sub_item) {
sub_tree = proto_item_add_subtree (sub_item, sub_proto->ett);
* Put the operation number into the tree along with
* the operation's name.
*/
- if(sub_dissect == NULL)
if (sub_proto->opnum_hf != -1)
- proto_tree_add_uint_format(sub_tree, sub_proto->opnum_hf,
- tvb, 0, 0, info->call_data->opnum,
- "Operation: %s (%u)",
- name, info->call_data->opnum);
+ proto_tree_add_uint_format(sub_tree, sub_proto->opnum_hf,
+ tvb, 0, 0, info->call_data->opnum,
+ "Operation: %s (%u)",
+ name, info->call_data->opnum);
else
- proto_tree_add_uint_format(sub_tree, hf_dcerpc_op, tvb,
- 0, 0, info->call_data->opnum,
- "Operation: %s (%u)",
- name, info->call_data->opnum);
-
- if(info->ptype == PDU_REQ && info->call_data->rep_frame!=0) {
- pi = proto_tree_add_uint(sub_tree, hf_dcerpc_response_in,
- tvb, 0, 0, info->call_data->rep_frame);
- PROTO_ITEM_SET_GENERATED(pi);
- }
- if(info->ptype == PDU_RESP && info->call_data->req_frame!=0) {
- pi = proto_tree_add_uint(sub_tree, hf_dcerpc_request_in,
- tvb, 0, 0, info->call_data->req_frame);
- PROTO_ITEM_SET_GENERATED(pi);
- }
+ proto_tree_add_uint_format(sub_tree, hf_dcerpc_op, tvb,
+ 0, 0, info->call_data->opnum,
+ "Operation: %s (%u)",
+ name, info->call_data->opnum);
+
+ if(info->ptype == PDU_REQ && info->call_data->rep_frame!=0) {
+ pi = proto_tree_add_uint(sub_tree, hf_dcerpc_response_in,
+ tvb, 0, 0, info->call_data->rep_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+ if(info->ptype == PDU_RESP && info->call_data->req_frame!=0) {
+ pi = proto_tree_add_uint(sub_tree, hf_dcerpc_request_in,
+ tvb, 0, 0, info->call_data->req_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
} /* tree */
if (decrypted_tvb != NULL) {
init_ndr_pointer_list(pinfo);
+ length = tvb_length(decrypted_tvb);
+ reported_length = tvb_reported_length(decrypted_tvb);
+
/*
* Remove the authentication padding from the stub data.
*/
if (auth_info != NULL && auth_info->auth_pad_len != 0) {
- length = tvb_length(decrypted_tvb);
- reported_length = tvb_reported_length(decrypted_tvb);
if (reported_length >= auth_info->auth_pad_len) {
/*
* OK, the padding length isn't so big that it
if (length > reported_length)
length = reported_length;
- stub_tvb = tvb_new_subset(tvb, 0, length, reported_length);
+ stub_tvb = tvb_new_subset(decrypted_tvb, 0, length, reported_length);
auth_pad_len = auth_info->auth_pad_len;
auth_pad_offset = reported_length;
} else {
stub_tvb = NULL;
auth_pad_len = reported_length;
auth_pad_offset = 0;
+ length = 0;
+ reported_length = 0;
}
} else {
/*
auth_pad_offset = 0;
}
+ if (sub_item) {
+ proto_item_set_len(sub_item, length);
+ }
+
if (stub_tvb != NULL) {
/*
* Catch all exceptions other than BoundsError, so that even
* dissect; just re-throw that exception.
*/
TRY {
- offset = sub_dissect (decrypted_tvb, 0, pinfo, sub_tree,
+ int remaining;
+
+ offset = sub_dissect (stub_tvb, 0, pinfo, sub_tree,
drep);
- if(tree) {
- proto_item_set_len(sub_item, offset);
- }
/* If we have a subdissector and it didn't dissect all
data in the tvb, make a note of it. */
- /* XXX - don't do this, as this could be just another RPC Req./Resp. in this PDU */
- /*if (tvb_reported_length_remaining(stub_tvb, offset) > 0) {
+ remaining = tvb_reported_length_remaining(stub_tvb, offset);
+ if (remaining > 0) {
+ proto_tree_add_text(sub_tree, stub_tvb, offset,
+ remaining,
+ "[Long frame (%d byte%s)]",
+ remaining,
+ plurality(remaining, "", "s"));
if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO,
- "[Long frame (%d bytes)]",
- tvb_reported_length_remaining(stub_tvb, offset));
- }*/
+ "[Long frame (%d byte%s)]",
+ remaining,
+ plurality(remaining, "", "s"));
+
+ }
} CATCH(BoundsError) {
RETHROW;
} CATCH_ALL {
- show_exception(decrypted_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
+ show_exception(stub_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
} ENDTRY;
}
* prepend a delimiter */
col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
}
- }
+ }
/* save context ID for use with dcerpc_add_conv_to_bind_table() */
/* (if we have multiple contexts, this might cause "decode as"
if(uuid_name) {
proto_tree_add_guid_format (iface_tree, hf_dcerpc_cn_bind_if_id, tvb,
offset, 16, (e_guid_t *) &if_id, "Interface: %s UUID: %s", uuid_name, uuid_str);
- proto_item_append_text(iface_item, "%s", uuid_name);
+ proto_item_append_text(iface_item, ": %s", uuid_name);
} else {
proto_tree_add_guid_format (iface_tree, hf_dcerpc_cn_bind_if_id, tvb,
offset, 16, (e_guid_t *) &if_id, "Interface UUID: %s", uuid_str);
- proto_item_append_text(iface_item, "%s", uuid_str);
+ proto_item_append_text(iface_item, ": %s", uuid_str);
}
}
offset += 16;
dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &trans_id);
if (ctx_tree) {
proto_tree_add_guid_format (ctx_tree, hf_dcerpc_cn_ack_trans_id, tvb,
- offset, 16, (e_guid_t *) &trans_id, "Transfer Syntax: %s",
+ offset, 16, (e_guid_t *) &trans_id, "Transfer Syntax: %s",
guid_to_str((e_guid_t *) &trans_id));
}
offset += 16;
nor the first fragment then there is nothing more we can do
so we just have to exit
*/
- if( !dcerpc_reassemble )
+ if( !dcerpc_reassemble || (tvb_length(tvb)!=tvb_reported_length(tvb)) )
goto end_cn_stub;
/* if we didnt get 'frame' we dont know where the PDU started and thus
/* defragmentation is a bit tricky, as there's no offset of the fragment
* in the protocol data.
*
- * just use fragment_add_seq_next() and hope that TCP/SMB segments coming
- * in with the correct sequence.
- */
+ * just use fragment_add_seq_next() and hope that TCP/SMB segments coming
+ * in with the correct sequence.
+ */
fd_head = fragment_add_seq_next(decrypted_tvb, 0, pinfo, frame,
dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
tvb_length(decrypted_tvb),
pinfo->fragmented = FALSE;
expert_add_info_format(pinfo, frag_tree_item, PI_REASSEMBLE, PI_CHAT,
- "%s fragment, %u bytes reassembled here in #%u",
- fragment_type(hdr->flags), fd_head->len, fd_head->reassembled_in);
+ "%s fragment, reassembled",
+ fragment_type(hdr->flags));
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, next_tvb,
next_tvb, hdr->drep, di, auth_info);
* prepend a delimiter */
col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
}
- }
+ }
offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
hf_dcerpc_opnum, &opnum);
dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &obj_id);
if (dcerpc_tree) {
proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
- offset, 16, (e_guid_t *) &obj_id, "Object UUID: %s",
+ offset, 16, (e_guid_t *) &obj_id, "Object UUID: %s",
guid_to_str((e_guid_t *) &obj_id));
}
offset += 16;
call_value->req_time=pinfo->fd->abs_ts;
call_value->rep_frame=0;
call_value->max_ptr=0;
+ call_value->se_data = NULL;
call_value->private_data = NULL;
g_hash_table_insert (dcerpc_cn_calls, call_key, call_value);
/* no bind information, simply show stub data */
pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
PROTO_ITEM_SET_GENERATED(pi);
- expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u (Call ID:%u)",
- ctx_id, hdr->call_id);
+ expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
+ ctx_id);
show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
}
}
* prepend a delimiter */
col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
}
- }
+ }
/* save context ID for use with dcerpc_add_conv_to_bind_table() */
pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
PROTO_ITEM_SET_GENERATED(pi);
} else {
- pi = proto_tree_add_text(dcerpc_tree,
+ pi = proto_tree_add_text(dcerpc_tree,
tvb, 0, 0, "No request to this DCE/RPC call found");
expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
"No request to this DCE/RPC call found");
/* no bind information, simply show stub data */
pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
PROTO_ITEM_SET_GENERATED(pi);
- expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u (Call ID:%u)",
- ctx_id, hdr->call_id);
+ expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
+ ctx_id);
show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
}
}
* prepend a delimiter */
col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
}
- }
+ }
offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
hf_dcerpc_cn_cancel_count, NULL);
pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
PROTO_ITEM_SET_GENERATED(pi);
} else {
- pi = proto_tree_add_text(dcerpc_tree,
+ pi = proto_tree_add_text(dcerpc_tree,
tvb, 0, 0, "No request to this DCE/RPC call found");
expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
"No request to this DCE/RPC call found");
call_value->req_time=pinfo->fd->abs_ts;
call_value->rep_frame=0;
call_value->max_ptr=0;
+ call_value->se_data = NULL;
call_value->private_data = NULL;
g_hash_table_insert (dcerpc_dg_calls, call_key, call_value);
v.req_frame = pinfo->fd->num;
v.rep_frame = 0;
v.max_ptr = 0;
+ v.se_data=NULL;
v.private_data=NULL;
value = &v;
}
v.opnum = hdr->opnum;
v.req_frame=0;
v.rep_frame=pinfo->fd->num;
+ v.se_data=NULL;
v.private_data=NULL;
value = &v;
}
pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
PROTO_ITEM_SET_GENERATED(pi);
} else {
- pi = proto_tree_add_text(dcerpc_tree,
+ pi = proto_tree_add_text(dcerpc_tree,
tvb, 0, 0, "No request to this DCE/RPC call found");
expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
"No request to this DCE/RPC call found");
int offset = 0;
conversation_t *conv;
int auth_level;
+ char *uuid_str;
+ const char *uuid_name = NULL;
/*
* Check if this looks like a CL DCERPC call. All dg packets
if (tree) {
proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
- offset, 16, (e_guid_t *) &hdr.obj_id, "Object UUID: %s",
+ offset, 16, (e_guid_t *) &hdr.obj_id, "Object UUID: %s",
guid_to_str((e_guid_t *) &hdr.obj_id));
}
offset += 16;
if (tree) {
- proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
- offset, 16, (e_guid_t *) &hdr.if_id, "Interface: %s",
- guid_to_str((e_guid_t *) &hdr.if_id));
+ uuid_str = guid_to_str((e_guid_t*)&hdr.if_id);
+ uuid_name = guids_get_uuid_name(&hdr.if_id);
+ if(uuid_name) {
+ proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
+ offset, 16, (e_guid_t *) &hdr.if_id, "Interface: %s UUID: %s", uuid_name, uuid_str);
+ } else {
+ proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
+ offset, 16, (e_guid_t *) &hdr.if_id, "Interface UUID: %s", uuid_str);
+ }
}
offset += 16;
break;
case PDU_FACK:
- dissect_dcerpc_dg_fack (tvb, offset, pinfo, dcerpc_tree, &hdr);
+ /* Body is optional */
+ /* XXX - we assume "frag_len" is the length of the body */
+ if (hdr.frag_len != 0)
+ dissect_dcerpc_dg_fack (tvb, offset, pinfo, dcerpc_tree, &hdr);
break;
case PDU_REJECT: