diff --git a/docs/opc-publisher/commandline.md b/docs/opc-publisher/commandline.md index e044635700..cc1f6ceb0d 100644 --- a/docs/opc-publisher/commandline.md +++ b/docs/opc-publisher/commandline.md @@ -859,21 +859,11 @@ Diagnostic options --cap, --capturedevice, --CaptureDevice=VALUE The capture device to use to capture network traffic. - Available devices on this system: - `Local Area Connection* 10` - `Local Area Connection* 9` - `Local Area Connection* 8` - `vEthernet (Default Switch)` - `Bluetooth Network Connection` - `Local Area Connection* 2` - `Local Area Connection* 1` - `Ethernet` - `Wi-Fi` - `\Device\NPF_Loopback` - Default: `null` (disabled). + Network capture is not supported on this system. --cpf, --capturefile, --CaptureFileName=VALUE The file name to capture traffic to. - A device must be selected using `--cd`. + A device must be selected using `--cd` if + capture capability is supported on this system. Default: `opcua.pcap`. ``` diff --git a/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs b/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs index ae8b9651ea..40bbdb9f8d 100644 --- a/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs +++ b/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs @@ -476,10 +476,10 @@ public CommandLine(string[] args, CommandLineLogger? logger = null) "Explicitly enable or disable exporting prometheus metrics directly on the standard path.\nDefault: `disabled` if Otlp collector is configured, otherwise `enabled`.\n", (bool? b) => this[Configuration.Otlp.EnableMetricsKey] = b?.ToString() ?? "True" }, { $"cap|capturedevice=|{OpcUaClientConfig.CaptureDeviceKey}=", - $"The capture device to use to capture network traffic.\nAvailable devices on this system:\n `{string.Join("`\n `", OpcUaClientCapture.AvailableDevices)}`\nDefault: `null` (disabled).\n", + $"The capture device to use to capture network traffic.\n{SupportsCapture(OpcUaClientCapture.AvailableDevices)}\n", (string s) => this[OpcUaClientConfig.CaptureDeviceKey] = s }, { $"cpf|capturefile=|{OpcUaClientConfig.CaptureFileNameKey}=", - $"The file name to capture traffic to.\nA device must be selected using `--cd`.\nDefault: `{OpcUaClientConfig.CaptureFileNameDefault}`.\n", + $"The file name to capture traffic to.\nA device must be selected using `--cd` if capture capability is supported on this system.\nDefault: `{OpcUaClientConfig.CaptureFileNameDefault}`.\n", (string s) => this[OpcUaClientConfig.CaptureFileNameKey] = s }, // testing purposes @@ -617,6 +617,16 @@ void SetStoreType(string s, string storeTypeKey, string optionName) throw new OptionException("Bad store type", optionName); } } + + private static string SupportsCapture(IReadOnlyList devices) + { + if (devices.Count == 0) + { + return "Network capture is not supported on this system."; + } + return $"Available devices on your system:\n `{string.Join("`\n `", devices)}`\nDefault: `null` (disabled)."; + } + private readonly CommandLineLogger _logger; } diff --git a/src/Azure.IIoT.OpcUa.Publisher/src/Azure.IIoT.OpcUa.Publisher.csproj b/src/Azure.IIoT.OpcUa.Publisher/src/Azure.IIoT.OpcUa.Publisher.csproj index b4bfec1b08..0d37aac3da 100644 --- a/src/Azure.IIoT.OpcUa.Publisher/src/Azure.IIoT.OpcUa.Publisher.csproj +++ b/src/Azure.IIoT.OpcUa.Publisher/src/Azure.IIoT.OpcUa.Publisher.csproj @@ -4,6 +4,12 @@ true enable + + SHARPPCAP + + + + @@ -11,7 +17,6 @@ - diff --git a/src/Azure.IIoT.OpcUa.Publisher/src/Stack/Services/OpcUaClientCapture.cs b/src/Azure.IIoT.OpcUa.Publisher/src/Stack/Services/OpcUaClientCapture.cs index 6821bcdaee..bea516cc6c 100644 --- a/src/Azure.IIoT.OpcUa.Publisher/src/Stack/Services/OpcUaClientCapture.cs +++ b/src/Azure.IIoT.OpcUa.Publisher/src/Stack/Services/OpcUaClientCapture.cs @@ -8,8 +8,10 @@ namespace Azure.IIoT.OpcUa.Publisher.Stack.Services using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; +#if SHARPPCAP using SharpPcap; using SharpPcap.LibPcap; +#endif using System.Collections.Generic; using System.Linq; using System.IO; @@ -27,6 +29,7 @@ public static IReadOnlyList AvailableDevices { get { +#if SHARPPCAP try { return LibPcapLiveDeviceList.Instance @@ -34,6 +37,7 @@ public static IReadOnlyList AvailableDevices .ToArray(); } catch +#endif { return Array.Empty(); } @@ -62,6 +66,7 @@ public void Start() return; } +#if SHARPPCAP _logger.LogInformation("Using SharpPcap {Version}", Pcap.SharpPcapVersion); var device = FindDeviceByName(deviceName); if (device == null) @@ -73,15 +78,21 @@ public void Start() _device?.Dispose(); _device = new CaptureDevice(this, device, _options.Value.CaptureFileName); +#else + _logger.LogWarning("SharpPcap is not included in this build."); +#endif } /// public void Dispose() { +#if SHARPPCAP _device?.Dispose(); _device = null; +#endif } +#if SHARPPCAP /// /// Find device by name /// @@ -173,6 +184,7 @@ public void Dispose() } private CaptureDevice? _device; +#endif private readonly IOptions _options; private readonly ILogger _logger; }