return fr_packet_cmp(a->expect, b->expect);
}
+static inline int rs_response_to_pcap(rs_event_t *event, rs_request_t *request, struct pcap_pkthdr const *header,
+ uint8_t const *data)
+{
+ if (!event->out) return 0;
+
+ /*
+ * If we're filtering by response then the requests then the capture buffer
+ * associated with the request should contain buffered request packets.
+ */
+ if (conf->filter_response) {
+ rs_capture_t *start;
+
+ /*
+ * Record the current position in the header
+ */
+ start = request->capture_p;
+
+ /*
+ * Buffer hasn't looped set capture_p to the start of the buffer
+ */
+ if (!start->header) request->capture_p = request->capture;
+
+ /*
+ * If where capture_p points to, has a header set, write out the
+ * packet to the PCAP file, looping over the buffer until we
+ * hit our start point.
+ */
+ if (request->capture_p->header) do {
+ pcap_dump((void *)event->out->dumper, request->capture_p->header,
+ request->capture_p->data);
+ TALLOC_FREE(request->capture_p->header);
+ TALLOC_FREE(request->capture_p->data);
+
+ /* Reset the pointer to the start of the circular buffer */
+ if (request->capture_p++ >= (request->capture + sizeof(request->capture))) {
+ request->capture_p = request->capture;
+ }
+ } while (request->capture_p != start);
+ }
+
+ /*
+ * Now log the response
+ */
+ pcap_dump((void *)event->out->dumper, header, data);
+
+ return 0;
+}
+
+static inline int rs_request_to_pcap(rs_event_t *event, rs_request_t *request, struct pcap_pkthdr const *header,
+ uint8_t const *data)
+{
+ if (!event->out) return 0;
+
+ /*
+ * If we're filtering by response, then we need to wait to write out the requests
+ */
+ if (conf->filter_response) {
+ /* Free the old capture */
+ if (request->capture_p->header) {
+ talloc_free(request->capture_p->header);
+ talloc_free(request->capture_p->data);
+ }
+
+ if (!(request->capture_p->header = talloc(request, struct pcap_pkthdr))) return -1;
+ if (!(request->capture_p->data = talloc_array(request, uint8_t, header->caplen))) {
+ TALLOC_FREE(request->capture_p->header);
+ return -1;
+ }
+ memcpy(request->capture_p->header, header, sizeof(struct pcap_pkthdr));
+ memcpy(request->capture_p->data, data, header->caplen);
+
+ /* Reset the pointer to the start of the circular buffer */
+ if (++request->capture_p >= (request->capture + sizeof(request->capture))) {
+ request->capture_p = request->capture;
+ }
+ return 0;
+ }
+
+ pcap_dump((void *)event->out->dumper, header, data);
+
+ return 0;
+}
+
/* This is the same as immediately scheduling the cleanup event */
#define RS_CLEANUP_NOW(_x, _s)\
{\
stats->exchange[current->code].interval.unlinked_total++;
}
+ rs_response_to_pcap(event, original, header, data);
response = true;
break;
}
*/
} else {
original = rbtree_finddata(request_tree, &search);
- if (original && memcmp(original->expect->vector, current->vector,
- sizeof(original->expect->vector)) != 0) {
+ if (original && (memcmp(original->expect->vector, current->vector,
+ sizeof(original->expect->vector)) != 0)) {
/*
* ID reused before the request timed out (which may be an issue)...
*/
original->in = event->in;
original->stats_req = &stats->exchange[current->code];
+ /* Set the packet pointer to the start of the buffer*/
+ original->capture_p = original->capture;
+
original->packet = talloc_steal(original, current);
original->expect = talloc_steal(original, search.expect);
talloc_free(original);
return;
}
+ rs_request_to_pcap(event, original, header, data);
response = false;
break;
}
return;
}
- if (event->out) {
- pcap_dump((void *) (event->out->dumper), header, data);
- }
-
rs_tv_sub(&header->ts, &start_pcap, &elapsed);
/*