/* ======================================================================== * Copyright (c) 2005-2026 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Opc.Ua.Bindings.Pcap.Frame; using Opc.Ua.Bindings.Pcap.KeyLog; using Opc.Ua.Bindings.Pcap.Models; namespace Opc.Ua.Bindings.Pcap.Capture { /// /// An OPC UA-aware packet-capture source. Implementations buffer the /// captured traffic and any associated key material to disk so the /// recording can be replayed and decoded later. /// /// /// /// All implementations are async and may freely use I/O. They are /// sealed by default per the repository convention; extensibility is /// achieved by registering additional sources with the /// CaptureSessionManager. /// /// /// Lifecycle: construction → → /// (capture work) → → /// (any number of times) → /// . /// /// public interface ICaptureSource : IAsyncDisposable { /// /// Output formats this source can produce. Sources that capture /// link-layer frames (NIC, in-proc taps using loopback framing) /// can produce and /// . Replay sources can produce /// every format the underlying file supports. /// IReadOnlySet SupportedFormats { get; } /// /// Number of OPC UA chunks captured so far. /// long FrameCount { get; } /// /// Number of bytes (including all framing) captured so far. /// long ByteCount { get; } /// /// Begin capturing. Implementations should validate their inputs /// and throw a with a /// human-friendly message on misconfiguration. /// ValueTask StartAsync(StartCaptureRequest request, CancellationToken ct); /// /// Stop capturing and flush all buffers to disk. After this /// returns successfully the captured records are safe to enumerate /// via . /// ValueTask StopAsync(CancellationToken ct); /// /// Returns the full path to the underlying raw libpcap-format file /// if the source produces one (NIC source, in-proc taps that /// synthesize loopback framing). Returns null otherwise. /// string? GetRawPcapFilePath(); /// /// Returns the full path to the keylog file produced by this /// source (if any). Multiple formats may be produced - this /// returns the canonical one (.uakeys.json). /// string? GetKeyLogFilePath(); /// /// Replay every captured key material snapshot from buffered /// storage in the order it was observed. /// IAsyncEnumerable ReadKeyMaterialAsync(CancellationToken ct); /// /// Replay every captured OPC UA chunk from buffered storage. May /// be called any number of times after . /// IAsyncEnumerable ReadCapturedFramesAsync( long? maxFrames, CancellationToken ct); } /// /// Domain-specific exception thrown by the diagnostics pipeline so /// MCP tools can surface a clear, single-line message to the caller /// without exposing internals. /// public sealed class PcapDiagnosticsException : IOException { /// /// Constructs a new diagnostics exception with the supplied /// default message. /// public PcapDiagnosticsException() : base("An OPC UA packet-capture diagnostics error occurred.") { } /// /// Constructs a new diagnostics exception with the supplied /// message. /// public PcapDiagnosticsException(string message) : base(message) { } /// /// Constructs a new diagnostics exception with the supplied /// message and inner exception. /// public PcapDiagnosticsException(string message, Exception innerException) : base(message, innerException) { } /// /// Constructs a new diagnostics exception with the supplied /// message and HRESULT. /// /// The diagnostic message; may be null. /// The HRESULT to associate with the exception. public PcapDiagnosticsException(string? message, int hresult) : base(message, hresult) { } } }