HDDSCAP File Format

The .hddscap format is the native capture format for hdds_viewer, optimized for high-throughput recording and efficient replay.

Overview

PropertyValue

Extension.hddscap
Magic bytesHDDS (0x48 0x44 0x44 0x53)
Version1.0
EndiannessLittle-endian
CompressionOptional (LZ4)

File Structure

┌──────────────────────────────────────┐

│ Header (256 bytes) │

├──────────────────────────────────────┤

│ Type Registry (variable) │

├──────────────────────────────────────┤

│ Segment 1 │

├──────────────────────────────────────┤

│ Segment 2 │

├──────────────────────────────────────┤

│ ... │

├──────────────────────────────────────┤

│ Segment N │

├──────────────────────────────────────┤

│ Footer (64 bytes) │

└──────────────────────────────────────┘

Header Format (256 bytes)

OffsetSizeFieldDescription

0x004magic"HDDS" (0x48444453)
0x042version_majorFormat major version
0x062version_minorFormat minor version
0x088timestamp_startCapture start (ns since epoch)
0x108timestamp_endCapture end (set in footer)
0x188frame_countTotal frames (set in footer)
0x204flagsCompression, encryption flags
0x244type_registry_offsetOffset to type registry
0x284type_registry_sizeSize of type registry
0x2C4first_segment_offsetOffset to first segment
0x3032capture_nameUTF-8 capture name
0x5032hostnameCapturing host
0x7016hdds_versionHDDS version string
0x80128reservedFuture use (zero-filled)

Flags

BitMeaning

0Compressed (LZ4)
1Encrypted (AES-256-GCM)
2Indexed (fast seek)
3-31Reserved

Type Registry

Maps type IDs to type descriptors:

┌─────────────────────────────────────┐

│ Entry Count (u32) │

├─────────────────────────────────────┤

│ Type Entry 1 │

│ ├─ type_id (u16) │

│ ├─ name_len (u16) │

│ ├─ name (UTF-8, name_len bytes) │

│ └─ schema (CDR2 TypeObject) │

├─────────────────────────────────────┤

│ Type Entry 2 │

├─────────────────────────────────────┤

│ ... │

└─────────────────────────────────────┘

Segment Format

Each segment contains up to 1000 frames:

┌─────────────────────────────────────┐

│ Segment Header (32 bytes) │

│ ├─ segment_id (u32) │

│ ├─ frame_count (u32) │

│ ├─ compressed_size (u32) │

│ ├─ uncompressed_size (u32) │

│ ├─ timestamp_start (u64) │

│ ├─ timestamp_end (u64) │

│ └─ crc32 (u32) │

├─────────────────────────────────────┤

│ Frame 1 │

├─────────────────────────────────────┤

│ Frame 2 │

├─────────────────────────────────────┤

│ ... │

└─────────────────────────────────────┘

Frame Format

┌─────────────────────────────────────┐

│ Frame Header (24 bytes) │

│ ├─ timestamp_ns (u64) │

│ ├─ topic_id (u16) │

│ ├─ type_id (u16) │

│ ├─ qos_hash (u32) │

│ ├─ payload_size (u32) │

│ └─ flags (u32) │

├─────────────────────────────────────┤

│ Payload (CDR2 encoded) │

└─────────────────────────────────────┘

Frame Flags

BitMeaning

0Key sample
1Dispose
2Unregister
3Inline QoS present
4-31Reserved

Footer Format (64 bytes)

OffsetSizeFieldDescription

0x008timestamp_endCapture end time
0x088frame_countTotal frames captured
0x108byte_countTotal payload bytes
0x184segment_countNumber of segments
0x1C4topic_countUnique topics
0x204type_countUnique types
0x244crc32_headerCRC32 of header
0x284crc32_footerCRC32 of footer
0x2C20reservedFuture use

Performance

MetricValue

Write throughput625 MB/s
Read throughput800+ MB/s
Compression ratio3:1 typical
Max file size16 TB
Max frames2^64 - 1

Tools

Create Capture

# From live traffic

hdds-viewer --domain 0 --record output.hddscap

With compression

hdds-viewer --domain 0 --record output.hddscap --compress

Inspect Capture

# Show header info

hdds-viewer --info capture.hddscap

Output:

File: capture.hddscap

Version: 1.0

Duration: 5m 23s

Frames: 1,234,567

Size: 156 MB (compressed)

Topics: 12

Types: 8

Convert to PCAP

hdds-viewer --convert capture.hddscap --output capture.pcap

Merge Captures

hdds-viewer --merge capture1.hddscap capture2.hddscap -o merged.hddscap

Extract Time Range

hdds-viewer --extract capture.hddscap \

--start "2025-01-01T12:00:00" \

--end "2025-01-01T12:05:00" \

-o subset.hddscap

Comparison with PCAP

FeatureHDDSCAPPCAP/PCAPNG

DDS-nativeYesNo (raw packets)
Type informationEmbeddedExternal IDL
CompressionLZ4 (built-in)External tool
Random accessYes (indexed)Sequential
CDR decodingPre-parsedRuntime
File size3x smallerLarger
Wireshark compatibleVia exportNative

API (Rust)

Reading

use viewer_core::capture::{CaptureReader, Frame};

let reader = CaptureReader::open("capture.hddscap")?;

println!("Frames: {}", reader.header().frame_count);

for frame in reader.frames() {

let frame: Frame = frame?;

println!("{}: {} bytes", frame.topic_name, frame.payload.len());

}

Writing

use viewer_core::capture::{CaptureWriter, CaptureConfig};

let config = CaptureConfig::new("my_capture")

.with_compression(true)

.with_hostname("node-1");

let mut writer = CaptureWriter::create("output.hddscap", config)?;

writer.write_frame(&frame)?;

writer.finalize()?; // Writes footer

Security

Encryption (Enterprise)

Captures can be encrypted with AES-256-GCM:

hdds-viewer --record output.hddscap --encrypt --key-file key.bin

Integrity

CRC32 checksums protect:

  • Header integrity
  • Segment integrity
  • Footer integrity

# Verify capture

hdds-viewer --verify capture.hddscap