off_t ofs = 0;
if (state->buffer.length == 0) {
- /* first get enough to read the fragment length */
+ /*
+ * first get enough to read the fragment length
+ *
+ * We read the full fixed ncacn_packet header
+ * in order to make wireshark happy with
+ * pcap files from socket_wrapper.
+ */
ofs = 0;
- state->buffer.length = DCERPC_FRAG_LEN_OFFSET + 2;
+ state->buffer.length = DCERPC_NCACN_PAYLOAD_OFFSET;
state->buffer.data = talloc_array(state, uint8_t,
state->buffer.length);
if (!state->buffer.data) {
return -1;
}
- } else if (state->buffer.length == (DCERPC_FRAG_LEN_OFFSET + 2)) {
+ } else if (state->buffer.length == DCERPC_NCACN_PAYLOAD_OFFSET) {
/* now read the fragment length and allocate the full buffer */
size_t frag_len = dcerpc_get_frag_length(&state->buffer);
ofs = state->buffer.length;
+ if (frag_len < ofs) {
+ /*
+ * something is wrong, let the caller deal with it
+ */
+ *_vector = NULL;
+ *_count = 0;
+ return 0;
+ }
+
state->buffer.data = talloc_realloc(state,
state->buffer.data,
uint8_t, frag_len);
return;
}
+ if (state->pkt->frag_length != state->buffer.length) {
+ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
+ return;
+ }
+
tevent_req_done(req);
}
talloc_free(frame);
return endpoint;
}
+
+struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt)
+{
+ struct dcerpc_sec_vt_header2 ret;
+
+ ZERO_STRUCT(ret);
+ ret.ptype = pkt->ptype;
+ memcpy(&ret.drep, pkt->drep, sizeof(ret.drep));
+ ret.call_id = pkt->call_id;
+
+ switch (pkt->ptype) {
+ case DCERPC_PKT_REQUEST:
+ ret.context_id = pkt->u.request.context_id;
+ ret.opnum = pkt->u.request.opnum;
+ break;
+
+ case DCERPC_PKT_RESPONSE:
+ ret.context_id = pkt->u.response.context_id;
+ break;
+
+ case DCERPC_PKT_FAULT:
+ ret.context_id = pkt->u.fault.context_id;
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
+ const struct dcerpc_sec_vt_header2 *v2)
+{
+ if (v1->ptype != v2->ptype) {
+ return false;
+ }
+
+ if (memcmp(v1->drep, v2->drep, sizeof(v1->drep)) != 0) {
+ return false;
+ }
+
+ if (v1->call_id != v2->call_id) {
+ return false;
+ }
+
+ if (v1->context_id != v2->context_id) {
+ return false;
+ }
+
+ if (v1->opnum != v2->opnum) {
+ return false;
+ }
+
+ return true;
+}