Repository navigation
Feature: Improve IP / Port Scanner and various fixes / improvements - #3660
Merged
Merged
Conversation
Replace the positional constructors (14 / 6 parameters) of IPScannerOptions and PortScannerOptions with init-only properties set via object initializer. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The per-host lambda in ScanAsync is split into DiscoverAsync (ping, port scan and NetBIOS concurrently -> reachable) and EnrichAsync (DNS PTR, MAC address and vendor -> result), with ResolveHostnameAsync / ResolveMACAddressAsync as own methods. Prepares progressive results (enrich as soon as a host answers). No behaviour change. Port Scanner: nothing to split (per port probe -> result, PTR already runs concurrently). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The PTR record is fully qualified (e.g. "server.example.com."). The IP Scanner only trimmed it for custom commands and "Add profile", so the grid, the export and other features (DNS Lookup, Remote Desktop, ...) got the hostname with the trailing dot. It is now trimmed once when the result is created, in the IP Scanner and the Port Scanner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DNS hostname (without the NetBIOS fallback of Hostname) was only exported to JSON. Add it to CSV and XML, right after Hostname (JSON moved to the same position). Port Scanner: no separate DNS hostname, nothing to change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n scan (C5) Columns, Copy menu entries and the row details (IP Scanner) were bound to the current settings. After changing a setting the shown results got columns without data (e.g. MAC address enabled after the scan) or lost columns with data, the row details showed "Port scan is disabled" for scanned ports. The view models keep the options of the shown scan (ScanOptions, until the first scan the settings when the tab was opened) and the views bind to them via the BindingProxy (DataGrid columns are not in the visual tree). Port Scanner: Hostname column and Copy > Hostname. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ner) Split the combined "IP Scanner / Port Scanner" section and the "also in the ..." / "the same applies to ..." remarks into separate entries in the section of each tool (IP Scanner, Port Scanner, Ping Monitor, Traceroute). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The trailing dot was only trimmed in the IP Scanner and Port Scanner (C2). Ping Monitor, Traceroute, Connections and the Network Connection widget still showed "server.example.com.". Trim it once in DNSClient.ResolvePtrAsync instead and remove the per-tool trims (IP Scanner, Port Scanner, Ping Monitor title / notification). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Trimming the trailing dot turned a single-label PTR name like "gateway." into "gateway". DNSClientHelper.IsBareHostname treats that as a bare hostname, so with "Add DNS suffix" enabled, DNS Lookup and every other tool that resolves it (e.g. when opened from the IP Scanner) queried "gateway.<suffix>" instead. New DNSClientHelper.TrimTrailingDot only trims fully qualified names with more than one label, used by DNSClient.ResolvePtrAsync. Unit tests added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since C5 the columns, Copy menu and row details were a snapshot of the settings when the tab was opened until the first scan - before, they followed the settings live. While no results are shown (and no scan is running), the view models now refresh ScanOptions when a setting that affects them changes (IP Scanner: resolve hostname, port scan, NetBIOS, MAC address; Port Scanner: resolve hostname). The snapshot no longer allocates the ICMP buffer (up to 65500 bytes per tab), it is only created for a scan. The settings handler is removed when the tab is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With init properties (R1) a forgotten option silently became 0 / false (e.g. MaxHostThreads = 0 -> Parallel.ForEachAsync throws), the positional constructor caught this at compile time. Mark all options of IPScannerOptions and PortScannerOptions as required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C4 inserted the DNSHostname column after Hostname, which moved every following column by one - scripts / spreadsheets that read the CSV by position would read the wrong values. Add it as last column instead (XML and JSON are read by name and keep it after Hostname). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IsReachable was a computed property that went through the port list again on every read (about 4 times per host). Compute it once in the initializer like IsAnyPortOpen. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ently (review #7) EnrichAsync ran the PTR lookup and the MAC address lookup (neighbor table, local interfaces, OUI) one after the other, although they don't depend on each other. Start both and await them together - a host is finished after the slower one instead of after both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew A) Since the PTR name keeps the dot of a single-label name (review #1, so other tools don't append the DNS suffix), the removed per-tool trims (C2, review #3) made custom commands ({{Hostname}}), the profile name of "Add profile" and the Ping Monitor title / notification use "gateway." instead of "gateway" (main). For custom commands this is more than cosmetic: Windows resolves a name with a trailing dot via DNS only (no suffix search, no LLMNR / NetBIOS). Trim the dot again in these places (display / external programs); the value passed to other NETworkManager tools keeps it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ScanOptions kept the full IPScannerOptions of the last scan for the lifetime of the tab (ports array, ICMP buffer - up to ~320 KB for 1-65535 / 65500 bytes) only to read four flags, and CreateScanOptions(null) created options for display that claimed a port scan without ports. New IPScannerResultOptions record with the four flags the view binds to (hostname, port scan, NetBIOS, MAC address), created from the options of the scan or from the settings. CreateScanOptions is only used for a scan again. Port Scanner unchanged: PortScannerOptions only holds six scalar values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ScanOptions only followed the settings if a setting changed while no results were shown. An empty result could still keep the columns of the previous scan: Results.Clear() ran long before the options of the new scan were set, and a scan that was canceled during the preparation or found nothing didn't update them either. The handler also listed the relevant settings by hand (easy to miss when a column is added). UpdateScanOptionsIfNoResults is called after the results are cleared, when a scan is complete and on any settings change (IP Scanner + Port Scanner). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ew C) IPScanner and PortScanner had an identical private ResolveHostnameAsync (PTR lookup, stop waiting on cancellation, empty string on error). Replace both with DNSClient.ResolvePtrOrEmptyAsync. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HostDiscovery caches IsAnyPortOpen / IsReachable at construction. As a positional record, a "with" expression would copy these cached values instead of recomputing them, and the generated equality / ToString members are unused. Use a private sealed class with read-only properties. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EnrichAsync checked discovery.NetBIOSInfo with ?. three times, but it is never null (an empty NetBIOSInfo if NetBIOS is disabled or there was no answer) and HostDiscovery.IsReachable already dereferences it. Keep the ?? fallbacks for its values, which may be null. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CSV export got DNSHostname as last column (review #5), but the XML export still inserted it after Hostname (moving the following elements) and the JSON export moved the existing property next to Hostname. XML: last element, JSON: back to its previous position - no existing column / element / property changes its position compared to the last release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3, step 23) IPScannerHostInfo is observable (PropertyChangedBase, setters internal to the model). Hostname / MACAddress / Vendor are computed from their sources (DNS -> NetBIOS, neighbor table -> NetBIOS), so a value that arrives later updates them. The scanner raises HostFound right after the discovery (ping, port scan, NetBIOS) and the DNS hostname and MAC address / vendor as HostUpdated when they arrive (replaces HostScanned). The scanner never changes a host itself: the view model buffers HostFound and HostUpdated in one list (order kept, an update always after its host) and applies them on the UI thread in the existing 150 ms flush. A host is only finished (progress) when all its lookups are finished, and ScanComplete is raised only after every host body returned - the view model flushes the remaining updates before the scan ends. Events of a scanner other than the running one are ignored and logged (guard only, can't happen). Export copies the rows on the UI thread (Clone), since they may still change during a scan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…4, P9) ScanHostAsync replaces DiscoverAsync / HostDiscovery: ping, port scan and NetBIOS run concurrently and are processed as they finish (Task.WhenAny). The port scan signals the first answering port (open or refused) right away. On the first answer the host is raised in HostFound - with placeholders for the probes that are still running (IsPingPending / IsPortScanPending / IsNetBIOSPending) - counted as up, and the DNS hostname and MAC address lookups start (P9). Every probe that finishes afterwards is raised as HostUpdated. Unreachable hosts are counted / raised (show unreachable) when all probes are finished. A host still only finishes (progress, and the scan with it) when every probe and lookup is finished: a finally waits for all of them, also when a probe was canceled or failed. View: Ping status, Port status and NetBIOS reachable show "..." while their probe is running (new PendingToStringConverter); the ping details and "No open ports found" are hidden until the ping / port scan is finished. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The view models stored the progress value of the ProgressChanged event args. Events of different hosts / ports raised at the same time can arrive in a different order, so an older (smaller) value could overwrite a newer one - also the last one, so the result could end with e.g. 255 of 256 hosts scanned. Step 24 raises ProgressChanged also when a host is found, which makes this more likely. The scanners expose HostsScanned / PortsScanned; the view models read all counters from the scanner on every event and once more in ScanComplete (final values). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New Time column after Ping status with the round trip time of the ping reply
("-/-" without a reply, "..." while the ping is running - optional third value
of PingTimeToStringConverter, existing users unchanged). Sorting by time uses a
custom comparer: hosts without a ping reply (time 0) are always last, in both
directions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… tools (phase 3, step 27, C1)
The hostname shown in the result falls back to the NetBIOS computer name. That
name was passed to other tools (Port Scanner, Remote Desktop, PuTTY, ...) and to
DNS Lookup / RDAP > Hostname, where it may not be resolvable via DNS. Other
tools now get the DNS hostname, otherwise the IP address; DNS lookup / RDAP >
Hostname are only enabled with a DNS hostname. Custom commands keep
{{Hostname}} = shown hostname (documented).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ep 28, C3) The context menu for multiple selected results only had Export. New Copy submenu (same strings and style as the single-row Copy menu), one value per line in the order shown in the grid, without duplicates: - IP Scanner: IP address, Hostname, MAC address (visibility like the single-row menu / the columns of the shown scan) - Port Scanner: IP address, Hostname, Port, IP address:Port (IPEndPoint format, IPv6 in brackets) The grid order helper is shared with the export (GetSelectedResultsInGridOrder). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Search box right of the Result header (SearchTextBox, width 250, delayed filter like the Firewall - GlobalStaticConfiguration.SearchDispatcherTimerTimeSpan): - IP Scanner: IP address, hostname, MAC address, vendor, shown ports (number or service). Live filtering on Hostname / MACAddress / Vendor / Ports, so a host found before its hostname or MAC address arrived is filtered again. - Port Scanner: IP address, hostname, port, protocol, service, description, status (also translated). Results don't change after they were added. Enter in the search box filters right away (ApplySearch) and is handled, so it doesn't trigger the scan button (IsDefault) and clear the results. Counters always count all hosts / ports; Export > all exports the filtered results (documented). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le (phase 3, step 30, M2) IP Scanner context menu: - Web Console: opens the host (DNS hostname, otherwise the IP address - C1) via https if 443 is open, otherwise the first open of 80 / 8443 / 8080, http on the default port if none is open or the port scan is still running/disabled. - Wake on LAN: sends the magic packet to the MAC address (WakeOnLANRequest), only enabled with a MAC address. Port Scanner: Web Console for an open web port (80, 443, 8080, 8443). New WebConsoleUrlHelper (URL from host + ports: scheme, default ports left out, IPv6 in brackets with an encoded zone id) with unit tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ep 31, M4) Context menu Rescan (single and multiple rows, disabled while a scan runs), new string "Rescan". IP Scanner: scans the IP addresses of the selected rows again with the options of the shown scan (kept as _lastScanOptions, so the columns stay valid) and new option ReportAllHosts (every host is raised, also if unreachable now, without showing all ports like ShowAllResults). The scanner creates new results; their values are copied into the existing rows (IPScannerHostInfo.CopyFrom, selection and expanded details stay) and their updates are applied to these rows (IPScannerHostUpdatedArgs.ApplyTo). Rows are matched by the new scanned IPAddress of IPScannerHostInfo (PingInfo has the reply address). Up / down are counted from the rows during the rescan, the progress of the last scan is restored afterwards. Port Scanner: the rows of the selected hosts are removed and scanned again with the ports and options of the last scan; open / closed = counters of the other hosts + the ones of the rescan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g Monitor (phase 3, step 33, T1)
The counters were built from the number and a separate word ("{0} {1}" with
Strings.Up / Down / Open / Closed / Paused), so translations couldn't change
the word order. New strings XUp / XDown / XOpen / XClosed / XPaused ("{0} Up"
etc., same English text) used as StringFormat in the IP Scanner and Port
Scanner and as format of PingMonitorGroupSummaryConverter (Ping Monitor group
header). The old strings stay (used elsewhere).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dot of the hostname (final final review #6) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew #7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al review #8) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t after resolving the hostnames (B8) Only "The following hostnames could not be resolved" is shown instead of also "No reachable hosts found" / "No open ports found", and the input is not added to the history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ot only on an upgrade A settings file edited (or restored) after the upgrade to the current version kept a buffer of e.g. 65535, which makes .NET's Ping throw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tings, not only on an upgrade" This reverts commit a47e4b1. The buffer is lowered inline in UpgradeToLatest again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…idths in a loop and hang the window DataGridHelper.FillRemainingWidth: a horizontal scrollbar can make the vertical one appear, the narrower fill column removes both, the wider one shows the horizontal scrollbar again ... Each update is queued with Loaded priority (before input), so the window hangs without an exception. Going back to the wider width of two updates ago within 500 ms (without a size change of the grid) keeps the narrower width. Seen once in a Port Scanner run 1-65535 (stuck in the middle, no exception); cause not confirmed with a stack trace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The custom commands grid allowed selecting several rows, but Edit / Delete only used one of them. Like the profiles: MultiSelectDataGrid with the selected commands, a context menu with Delete for several rows, Del deletes all selected after a confirmation that lists them, Edit (F2, context menu) only with exactly one selected command. New strings DeleteCustomCommands / DeleteCustomCommandsMessage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ad of Status (breaking, PS-C3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…at once Like the custom commands of the IP Scanner: MultiSelectDataGrid, context menu with Delete for several rows, Del deletes all selected after a confirmation that lists them, Edit only with exactly one. The first port profile is still selected on open and after deleting. New strings DeletePortProfiles / DeletePortProfilesMessage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, Computer Management, Event Viewer and System Information Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ost in the group header Rescan in the row context menu rescanned all ports of the selected hosts (e.g. all 65535 to check one port). Now: - Rows: Rescan scans only the selected ports (PortScanner.ScanPortsAsync, per host only its ports) and updates their state in place (PortInfo.State observable); selection, collapsed groups and the scroll position stay. Every rescanned port is reported (a port closed now keeps its row with the new state, like a host down now in the IP Scanner), without ping before the scan and hostname resolution. Counters from base + rows (also after a cancel), closed / timed out per host and the open count of the group header updated (OpenPortsPerHostVersion). - Group header: context menu Rescan host - all ports of the shown scan, rows replaced (previous host rescan). PortScannerOptions is a record (with for the rescan options). New string RescanHost. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…faster with all hosts expanded) Every expanded row created 3 ListViews with a MahApps ListViewItem (own Grid, selection / hover triggers) per value and per port - all transparent, nothing selectable. Ping details and NetBIOS are one Grid with rows now, the ports an ItemsControl with the same item template. Same layout (min. row height 25 like the list items), the values are still TextBoxes (selectable, Copy context menu). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the visible part can be scrolled into ScrollUnit Item scrolled by whole rows: a partly visible expanded row (row details, e.g. with Expand host view) could only be skipped, not scrolled into. Virtualization (Recycling) stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctedItem})
InvalidCastException 'MS.Internal.NamedObject' to IPStatus: a recycled row
container (virtualization, more often with pixel scrolling and expanded rows) passes
{DisconnectedItem} / UnsetValue to the MultiBinding. The converter cast the values
without a type check; returns an empty string for other values now. Used by the IP
Scanner (Time column, row details) and Traceroute.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Info became observable Type-qualified bindings ((network:PortScannerPortInfo.State) etc.) pass no property name to PropertyChangedEventManager.AddHandler for an INotifyPropertyChanged source (PortInfo since b740659) -> ArgumentNullException 'key'. Plain paths like the IP Scanner row details. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… closed ports shown) Break All: UI thread in the CustomSort comparer from AddResult / FlushResultsBuffer. WPF inserts every added row into its group of the sorted, grouped view with a linear search of the group (CollectionViewGroupInternal.FindIndex) - with all 65535 ports of a host in one group about 2 billion comparisons on the UI thread. Like the rescan (ReplaceResults): above MaxRowChangesOneByOne (added rows x all rows) the buffered rows are added with one reset (sorted and grouped once). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… results were added ArgumentException "Width and Height must be non-negative" from VirtualizingStackPanel.SyncUniformSizeFlags (WPF, virtualization with grouping and collapsed groups) while a row was added during a scan - also on main. The row is already in the results when the notification throws; the remaining rows (rescan: all rows of the hosts) are added with one reset, which rebuilds the view. Only this exception (thrown by the Size constructor) is caught, logged as warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s, Add profile and Copy > Open ports The group header menu (Rescan host) also has Ping Monitor, Traceroute, DNS lookup, RDAP, Remote Desktop, PowerShell, PuTTY, TigerVNC, SNMP, Add profile... and Copy > IP address / Hostname / Open ports (e.g. "22; 80; 443", only with an open port). Port-specific items (Web Console, port / state / service) stay in the row menu. The commands take the group as an optional parameter (GetHostRow: first row of the group, otherwise the selected result), so a right-click on a header doesn't change the selection. Open in tool: [application, group] via the new MultiValueToArrayConverter. New string OpenPorts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…igh as the input Same style as the resolve button of other inputs (size bound to the TextBox height). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ested creating it with the same name The profile refers to port profiles / DNS servers by their internal ID, a new one with the same name is not found. The message says to create it and then select it in the profile again (edit the profile). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the scan Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BornToBeRoot
added a commit
that referenced
this pull request
Oct 31, 2026
The changelog entry of #3660 (and the comments in the export) said DNSHostname is the last column / element - the columns of the IP Scanner discovery changes follow it now. It is after the columns of the last release, so their position doesn't change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mergify Bot
pushed a commit
that referenced
this pull request
Nov 1, 2026
* Feature: IP Scanner: Show which probe found a host (A1)
The probes a host answered (Ping, TCP, NetBIOS) are tracked as
IPScannerHostInfo.DetectedBy (updated when a later probe answers) and
shown in the tooltip of the status icon and as "Detected by" in the row
details. Exported as DetectedBy (last column / element).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Export empty values for disabled probes (A2a)
The export gets the options of the shown scan: the port status / ports and
the NetBIOS values are exported as empty values if the port scan / NetBIOS
was disabled, instead of their placeholders (e.g. PortStatus "Closed").
Preparation for A2 (ping can be disabled).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Option to disable the ping (A2)
New setting IPScanner_ICMPEnabled ("Ping hosts", default on). Without
ping, hosts are found by their ports or NetBIOS answer and an unreachable
host doesn't wait for the ping attempts. The ping columns, copy entries
and row details are hidden for a scan without ping (IPScannerResultOptions)
and the ping values are exported as empty values. The scan doesn't start
if ping, port scan and NetBIOS are all disabled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Neighbor Table: State shifted by one (A3a)
NeighborState started at 1, but NL_NEIGHBOR_STATE (MIB_IPNET_ROW2.State
from GetIpNetTable2) starts at 0 (NlnsUnreachable): Reachable entries
were shown as Stale, Permanent as Reachable, Unreachable as 0.
Preparation for A3 (IP Scanner reads the state).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Find hosts in the local subnet via ARP / NDP (A3)
New setting IPScanner_ARPEnabled ("Find hosts in the local subnet",
default on). A host in a local subnet that didn't answer any probe is
checked in the neighbor table (read after its probes were finished): a
Reachable entry means it answered the ARP request / neighbor
solicitation of the probes (DetectedBy ARP). Stale / Delay / Probe
entries from earlier traffic are resolved again with ResolveIpNetEntry2
(max. 4 at the same time, blocking). Answers with the MAC address of a
default gateway are ignored (proxy ARP).
The neighbor table snapshot now keeps the whole entry (state, interface)
and is read at most every 100 ms (hosts share the next read).
Unit tests for the decision (IPScannerNeighborCheck) and the
NeighborState values.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Choose the network interface for Detect local subnet (A4)
The Detect local subnet button is a drop-down: Detect local subnet (as
before), Subnet of network interface (IPv4 subnets of the operational
network interfaces, loaded when the menu is opened, link-local at the
end) and All local subnets (without link-local).
NetworkInterface.GetLocalSubnets + unit tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner / Port Scanner / Ping Monitor: Exclude IP addresses (A5)
An input starting with "!" excludes its IP addresses from the other
inputs (e.g. "10.0.0.0/24; !10.0.0.1; !10.0.0.200-254"): IP addresses,
ranges, subnets and hostnames like the other inputs. Exclusions are
checks, not expanded lists (no memory for large excluded ranges), and are
ignored by GetHostCount. MultipleHostsRangeValidator (tools, profiles,
run command) accepts them and requires at least one inclusion; the run
command treats a list with an exclusion as IP range.
Unit tests for the exclusions and the run command target kind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: OS guess from TTL (B1)
New column OS (guess): operating system guessed from the TTL of the ping
reply (initial TTL 64 = Linux / Unix, 128 = Windows, 255 = network
device; hops in the tooltip), computed from the existing ping result (no
traffic). Setting IPScanner_OSGuessEnabled ("Guess the operating system
from the TTL", default on) in the Ping section, column via
IPScannerResultOptions. Search, Copy and export (OSGuess, last column).
IPScannerOSGuessHelper + unit tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Mark own computer, default gateway, DNS and DHCP server (B2)
The roles of the hosts for the local computer (own IP addresses, default
gateways, DNS and DHCP servers of the operational network interfaces) are
read once per scan (IPScannerHostRoleHelper) and set on the host (Role).
New icon column after the status icon (most important role: this
computer, gateway, DNS, DHCP), all roles in the tooltip. Search and
export (Role, last column). The network interfaces are now always read
for a scan.
Unit tests for the roles.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: UdpRequest for NetBIOS (C1a)
The UDP request / answer part of NetBIOSResolver (send, receive the
datagram of the host until the timeout, exception-free) moves to
UdpRequest, so the mDNS resolver (C1) can use it as well. No change in
behaviour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Resolve mDNS hostname (C1)
New settings IPScanner_MDNSEnabled (default off) and IPScanner_MDNSTimeout
(2000 ms). For reachable hosts, a reverse lookup (PTR) is sent as unicast
query to UDP 5353 of the host (MDNSResolver, raw UDP via UdpRequest,
exception-free); the answer (legacy unicast response) is parsed incl.
name compression. Shown in the new mDNS hostname column and used as
Hostname (DNS -> mDNS -> NetBIOS); not passed to other tools (like
NetBIOS). Search and export (MDNSHostname, last column).
Unit tests for the query / response parsing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Read the title of web pages (C2)
New settings IPScanner_HttpTitleEnabled (default off) and
IPScanner_HttpTitleTimeout (2000 ms). After the port scan, reachable hosts
with an open web port (443, 80, 8443, 8080) get a GET / (HttpTitleResolver:
shared HttpClient, no proxy / cookies / credentials, certificate errors
accepted, max. 3 redirects on the same host, max. 64 KB, charset from the
header / meta tag); the title (or Server header) is shown in the new Web
title column with the URL as tooltip. Web Console in the context menu
opens the port that answered. Search and export (WebTitle, WebURL).
Unit tests for the title / charset parsing and the web port order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Read the SNMP system information (C3)
New settings IPScanner_SNMPEnabled (default off), IPScanner_SNMPVersion
(v1 / v2c, default v2c), IPScanner_SNMPCommunity (default "public", saved
as plain text - warning in the settings and docs) and
IPScanner_SNMPTimeout (2000 ms). For reachable hosts, an SNMP GET of
sysName, sysDescr and sysLocation (SNMPSystemInfoResolver: request built
and parsed with SharpSnmpLib, sent via UdpRequest - exception-free) is
shown in the new SNMP name / description / location columns. Search and
export (SNMPName, SNMPDescription, SNMPLocation).
Unit tests for the request and the response parsing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Configurable ports for the web page title (C2b)
New setting IPScanner_HttpTitlePorts (default "443; 80; 8443; 8080") with
a restore-default button, like the ports of the port scan. The ports are
tried in this order, only if open in the port scan: http on 80 / 8080,
https and then http on any other port. Web Console opens the port and
scheme that answered (WebConsoleUrlHelper.CreateUrl with scheme).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: ARP / NDP settings section with help (A3b)
Find hosts in the local subnet and Resolve MAC address and vendor are in
one ARP / NDP section of the settings (the MAC address section is
removed), both with a help icon that explains the difference: finding
hosts that don't answer any probe (state of the neighbor entry) vs.
showing the MAC address / vendor of found hosts. Docs: comparison table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Labels for Detected by (A1b)
The probes a host answered are shown as labels in the row details (one
per probe, like the "ICMP" label of the Ping Monitor) instead of a
comma-separated text. IPScannerDetectionMethodToStringConverter returns
the list with ConverterParameter=List.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Show "..." while lookups are running (C4)
Pending flags for the DNS hostname, MAC address / vendor, mDNS hostname,
web title and SNMP system information (like ping, port scan and NetBIOS):
set when the host is added, cleared when the lookup / request is finished
(also without a result). The web title is pending until the port scan is
finished, cleared right away without an open web port. The columns show
"..." via PendingToStringConverter; Copy > Hostname / MAC address / Vendor
is disabled while pending.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Status code, Server and X-Powered-By of web pages (C2c)
HttpTitleResolver returns the status code, the title (only the title now)
and the Server / X-Powered-By headers (cleaned: no control characters,
max. 200 chars). The Web title column shows WebSummary (title, Server
header as fallback). Search and export (WebStatusCode, WebServer,
WebPoweredBy at the end).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Row details for hostnames, web page and SNMP (C5)
The columns show a short summary, the row details all values: new
sections in a second row (only if enabled for the shown scan) -
Hostnames (DNS, mDNS, NetBIOS name, shown with mDNS), Web (URL, status
code, title, Server, X-Powered-By) and SNMP (name, description,
location), with "..." while pending (OneWay bindings). The mDNS
hostname, SNMP description and SNMP location columns are removed (still
in the search and the export).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: SNMP answer marks a host as up (C3b)
The SNMP request is sent with the other probes to every IP address (like
NetBIOS) instead of only to found hosts: a host that answers is up
(IPScannerDetectionMethod.SNMP), also if it blocks the ping and all
ports. An answer with an error (e.g. noSuchName of v1) counts as answer
(empty values). The SNMP timeout is part of the host duration of the
start scheduler.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Row details in four columns with up / down labels (C5b)
Row details: Ping details / Hostnames | Ports | Web | NetBIOS / SNMP
(1* | 2* | 1* | 1*, ports and web span both rows). The "Detected by" row
is replaced by an Up / Down label in the header of each probe that can
find a host (ping, ports, NetBIOS, SNMP; IPScannerDetectionMethodToUpDown
converter, hidden while running). Sections of disabled settings show a
note like ports and NetBIOS (hostnames: DNS and mDNS disabled). The SNMP
location uses its own string (with a comment: physical location, not a
file location).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Hostname and MAC address pending until all sources are finished (C4b)
Hostname (DNS -> mDNS -> NetBIOS) and MAC address / vendor (neighbor table
-> NetBIOS) are shown as "..." until no source can change them any more:
new computed IsHostnamePending and IsMACAddressPending; the flag of the
neighbor lookup is IsNeighborMACAddressPending now. Columns and Copy
entries use the computed flags.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Status icons with details in the tooltip (C5c)
Status icons (green check / red cross, like the action of a rule in the
Firewall: the existing CheckRectangle / ErrorRectangle styles of the
Network Connection widget, chosen by the new SuccessStyleConverter)
instead of the Up / Down labels in the headers of the row details and of
the text in the Ping status, Port status and NetBIOS reachable columns
("..." while running). The tooltip shows the details
(IPScannerStatusToolTipConverter): ping status with time and TTL, open
ports with service (first 10), NetBIOS name and workgroup / domain,
Answered / No answer in the headers. Sorting and Copy are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Icon for the OS guess (B1b)
The OS (guess) column shows an icon before the text (Windows logo,
terminal for Linux / Unix, switch for a network device - not the router
icon of the gateway role) and "..." while the ping is running. The hops
stay in the tooltip; sorting, search, Copy and export are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Rename "Web title" to "Web" (C2d)
The feature reads the status code, the title and headers, not only the
title: the column and the settings section are called "Web", the setting
"Read web pages" (help text with all values). Code and settings (all
unreleased, no migration): HttpTitle* -> WebPage* (IPScanner_WebPage
Enabled / Ports / Timeout, WebPageResolver, WebPageInfo,
IsWebPagePending).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Realm of the login prompt and redirect target of web pages (C2e)
The realm of the WWW-Authenticate header (login prompt of a 401
response - routers, cameras and printers often name their model there,
WebPageResolver.ParseRealm) and the target of a redirect to another host
are read as well: row details (Web section), search, export (WebRealm,
WebRedirectURL at the end). The Web column shows the title, otherwise the
realm, the Server header or the redirect target.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: TLS certificate of web pages (C2f)
For https, the TLS certificate of the web server is read (subject,
issuer, end of the validity, self-signed - WebCertificateInfo): the
shared client uses an HttpClientHandler whose certificate callback gets
the request and stores the certificate in its options; every request
uses a new connection (Connection: close), so the callback also runs on a
rescan. Row details (Web section: certificate, issuer or "Self-signed",
valid until with "(expired)"), search and export
(WebCertificateSubject / Issuer / NotAfter / SelfSigned at the end).
Unit tests for WebCertificateInfo (self-signed, issued by a CA, expired).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Scan with SNMP as the only probe (R1)
Since C3b an SNMP answer marks a host as up, but Start() only accepted
ping, port scan or NetBIOS as a probe that can find hosts: an SNMP-only
scan was refused. SNMP counts now (message, docs, changelog); ARP / NDP
alone still doesn't (it needs the packets of the other probes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Invalid web page URL ended the scan (R2)
new Uri(url) in WebPageResolver.GetWebPageAsync was outside the
try/catch: a URL that can't be parsed threw through the enrichment of the
host and ended the whole scan with an error. It is in the try now, the
host just gets no web page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: ARP / NDP reported hosts that were gone as up (R3)
A neighbor entry that was already Reachable before the probes of a host
were sent is not resolved again by them (Windows keeps it Reachable for
about 15 - 45 s), so after the probes it doesn't prove an answer: e.g. a
device switched off right before a rescan was shown as up. The state
before the probes is read from the cached snapshot (no extra table
read); such an entry is verified like a Stale one
(IPScannerNeighborCheck.Check: wasReachableBefore -> Verify).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Lookups stayed "..." after Cancel (R4)
When a scan was canceled or failed, the pending flags of the running
lookups were never cleared: hostname, MAC address, mDNS and web page kept
showing "..." and Copy > Hostname / MAC address stayed disabled. The view
model calls IPScannerHostInfo.EndPendingLookups for every row then: the
lookups show no value, Hostname / MAC address no longer wait for NetBIOS.
The probes that decide if a host is up (ping, ports, NetBIOS, SNMP) stay
"..." (not finished), like before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: ARP verification still running after a canceled scan (R5)
On cancellation, the blocking ResolveIpNetEntry2 call was detached
(WaitAsync), so ScanComplete was raised while up to 4 verifications were
still flushing / resolving neighbor entries (a rescan could read a
table that was still changing). The host waits for the call now (max.
about 3 s) and then honors the cancellation, like the other probes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner / Ping Monitor: No message if all IP addresses are excluded (R6)
If the "!" exclusions remove every IP address of the input (e.g.
"10.0.0.1; !10.0.0.0/24"), the scan ended / nothing was added without
an explanation. A message is shown now ("All IP addresses are excluded");
the Ping Monitor keeps the input to correct it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Neighbor table lookups waited for the lock (R7)
GetNeighborEntryAsync held the semaphore while it waited up to 100 ms and
read the table, so MAC lookups of found hosts (usually answered from the
cache) queued behind the reads that the neighbor check of unreachable
hosts triggers about every 100 ms in a large local scan. The snapshot and
its timestamp are one immutable object now: the cache is looked up
without the lock, the wait happens before the lock, and the cache is
checked again after acquiring it (another host may have read the table).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: Gateways of the neighbor check once per scan (R8)
IsNeighborAsync rebuilt the gateway list from all network interfaces for
every unreachable host, also from interfaces that are not connected (the
role icon only uses connected ones). The gateways are taken from the
roles of the hosts now (computed once per scan, operational interfaces
only).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: One "host found" block (R9)
The ARP / NDP path copied the "host found" sequence of the first answer
(create the result, count it, raise HostFound / progress, start the
lookups). Both use the local function RaiseHostFound now, so a change
can't miss one of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Slow https attempt on plain http ports (R10)
On ports other than 80 / 8080, https is tried before http. A plain http
server that doesn't close the connection on the TLS handshake (some
embedded devices) cost the whole web page timeout before http was tried.
The https attempt waits at most 1 s on ports where https is only guessed
(not 443 / 8443, WebPageResolver.GetTimeout); no new setting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Feature: IP Scanner: Copy the values of the optional requests (R11)
Copy > mDNS hostname, Copy > Web > Title / URL / Server and Copy > SNMP >
Name / Description / Location, shown if the request was enabled for the
shown scan, disabled while the value is still "..." (like the other copy
entries).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: IP Scanner: Restructure the result documentation (R12)
The result section had grown into one block of text. Split into "How
hosts are found" (one table with all probes: ping, TCP, NetBIOS, SNMP,
ARP / NDP), "Result" (column table, "..." / "-/-" as a short list,
sorting, search, export) and "Row details" (layout and sections).
Updated the intro (SNMP, optional information), the hostname sources
(mDNS) and Expand host view; removed the duplicate description of the row
details and the changelog wording ("as before"). The NetBIOS details
don't contain the MAC address (old docs were wrong).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner / Ping Monitor: Exclude all addresses of a hostname (R13)
A "!hostname" exclusion was resolved to one address (A or AAAA, depending
on the IPv4 preference), so the other addresses of the host were still
scanned (e.g. the IPv4 address with IPv6 preferred). The exclusion now
resolves all A and AAAA records (new DNSClient.ResolveAllAAndAaaaAsync)
and excludes every address. "hostname/cidr" stays IPv4 only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner / Ping Monitor: No message if all IP addresses are excluded and a hostname failed (R14)
The "all IP addresses are excluded" message was only shown if every
hostname could be resolved - also an excluded hostname that could not be
resolved suppressed it (e.g. "10.0.0.1; !10.0.0.1; !typo.lan"), and the
Ping Monitor then cleared the input. HostRangeHelper.ResolveAsync returns
the number of hosts removed by the exclusions; the message is shown if no
host is left and something was excluded, after the "could not be
resolved" message. The Ping Monitor keeps the input whenever no host is
left.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Error reading the neighbor table ended the scan (R15)
An exception of GetIpNetTable2 (Win32Exception of NeighborTable.GetTable)
was not caught in GetNeighborEntryAsync. ARP / NDP is on by default and
every local host reads the table before its probes, so an IP helper error
aborted the whole scan. The error is logged once per scan and an empty
snapshot is stored (no entry: hosts are only found by their probes, no MAC
address from the table); the table is read again on the next miss.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Read web pages tried http on https ports (R16)
After https failed, http was tried on the same port, also on 443 / 8443:
for a device whose TLS handshake fails (e.g. TLS 1.0 only), the Web column
showed the error page for plain http on an https port (e.g. nginx "400 The
plain HTTP request was sent to HTTPS port") without a certificate. 443 /
8443 are only requested with https now, 80 / 8080 with http, other ports
with https and then http as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Title of web pages with a code page charset (R17)
Encoding.GetEncoding threw for charsets that are not built into .NET
(windows-1252, iso-8859-2, shift_jis, gb2312, ...) because the
CodePagesEncodingProvider was not registered - the page was decoded as
UTF-8 (e.g. "B�ro-Drucker"). WebPageResolver registers it in its static
constructor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Certificate of a web page after a redirect to http (R18)
The certificate was only replaced by https responses, so after a redirect
from https to http (e.g. https://host:8443/ -> http://host:8080/login) the
certificate of the first response was shown for the plain http page. The
certificate of the last response is used (null for http). The URL stays
the first URL on purpose (the Web Console opens the port that answered),
documented in WebPageInfo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: ARP / NDP used an old snapshot for the state before the probes (R19)
"Was Reachable before the probes" (R3) accepted a cached snapshot of the
neighbor table of any age. In a large local scan, an entry that was Stale
in a 30 s old snapshot may have been confirmed by other traffic since and
still be Reachable after the host left - it skipped the verification and
the host was shown as up. A snapshot older than 15 s (the minimum time
Windows keeps an entry reachable) is treated as unknown, so a Reachable
entry after the probes is verified. GetNeighborEntryAsync returns the
timestamp of the snapshot with the entry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: IP Scanner: DetectedBy is not the last export column anymore (R20)
The changelog said the export contains DetectedBy as the last column /
element - the columns of the other new values follow it now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: IP Scanner: DNSHostname is not the last export column anymore
The changelog entry of #3660 (and the comments in the export) said
DNSHostname is the last column / element - the columns of the IP Scanner
discovery changes follow it now. It is after the columns of the last
release, so their position doesn't change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: Changelog: PR number #3685 of the IP Scanner discovery changes
Replaces the [#PR] placeholders of the branch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Chore: Adjust skill
* Fix: IP Scanner: Double spaces in the SNMP description (B1)
The control characters of an SNMP value (e.g. the line breaks of a
multi-line sysDescr) were replaced by one space each, "\r\n" became two
spaces in the row details, the search and the export. Several spaces are
shown as one now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: Clone the host result with CopyFrom (R27)
Clone and CopyFrom listed the same values twice - every new value had to
be added to both. Clone creates the instance and uses CopyFrom. A unit test
sets every value and compares the clone, so a value missing in CopyFrom is
found. No behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: Result options from the scan options (R28)
CreateResultOptions mapped the settings to the flags a second time, next
to CreateScanOptions and IPScannerResultOptions(IPScannerOptions) - a new
probe had to be added in four places. It uses CreateScanOptions now. No
behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner / Ping Monitor: AddStatusMessage like the Port Scanner (R29)
"Show the message after the shown one" was written out three times in the
IP Scanner and twice in the Ping Monitor. Both use an AddStatusMessage
method like the Port Scanner. No behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner / Port Scanner / Ping Monitor: One parser for the host input (R21)
The host input was parsed four times (hosts to scan, exclusions, host
count, validator), each with its own list of regexes. A new format
accepted by the validator would have excluded nothing as exclusion.
HostRangeHelper.Parse returns the format and its values (HostRangeInput),
the four places switch on the format.
Same results for every valid input (unit tests unchanged, new tests for
the parser). For input the validator rejected anyway the host count is 0.
An IPv6 address that matches the regex but can't be parsed (e.g. a zone
id that is not an interface) is rejected by the validation now - the scan
failed with an exception before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: One field list for the CSV, XML and JSON export (R22)
The export listed the same ~40 fields four times (CSV header, CSV row,
XML, JSON) - a new value had to be added in four places, in the same
position. GetFields returns the values of a host in the order of the
columns, the three formats are created from it (the ports stay a list in
XML / JSON). Unit tests pin the column names and their order.
CSV and XML files are byte-identical to before (compared for hosts with
all values, unreachable and pending hosts, with all options on and off).
JSON: same keys and values, the key DNSHostname moved to the position it
has in CSV / XML (after Vendor instead of after Bytes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: Neighbor table of a scan in its own class (R23)
The snapshot of the neighbor table (lock, read interval, read errors), the
state before the probes, the proxy ARP gateways and the verification of
entries were mixed into the scanner. IPScannerNeighborCache (one instance
per scan, created with the roles of the hosts) holds them, the scanner
keeps the probes and the lookups (IPScanner.cs: 980 -> 750 lines). No
behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner: Shared styles for the row details (R24)
The six lists of the row details each repeated the same item style and
template (13 lines), and the 22 lines (label / value) each repeated the
same three-column grid. Two styles in the resources of the row details:
HostDetailsListView (no selection / hover, no border) and HostDetailsRow
(HeaderedContentControl: label as header, the TextBox as content). The
bindings of the values are unchanged. IPScannerView.xaml: about -200 lines.
No visual change intended - check on Windows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner / Ping Monitor: Excluded host scanned if its hostname could not be resolved (F1)
An exclusion whose hostname could not be resolved (e.g. a DNS timeout for
"!printer.corp.local") was ignored - the hosts it should exclude were
scanned anyway, only with the "could not be resolved" message. Nothing is
scanned in this case now (the Ping Monitor keeps the input).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Control characters in the mDNS hostname (F2)
The labels of an mDNS answer were taken as they are - a device answering
with a control character (e.g. 0x00) put it into the hostname, the search
and the export, and the XML export failed (invalid character). Control
characters are removed, like in the web page title and the SNMP values.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Export of web values without the port scan (F3)
Web pages are only read with the port scan (only open ports are
requested), the Web column and the Copy menu already check both settings.
The export only checked "Read web pages": with the port scan disabled it
wrote empty values ("requested, no page") instead of the empty values of a
disabled probe (null in JSON).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Local subnet of an adapter that is down (F4)
The check whether a host is in a local subnet (neighbor check, MAC address
from the neighbor table) used every network interface. An adapter that is
down but still has its static IPv4 address made hosts of that subnet (e.g.
reached via VPN) count as local: they got neighbor table reads and an
ARP / NDP check that can't find them. Only operational network interfaces
are used, like for the roles and the local subnets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: TTL in the tooltip of the ping status from the strings (F5)
The tooltip of the ping status ("Success (2 ms, TTL 64)") had "TTL" in the
code instead of the existing string, so it couldn't be translated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Web section of the row details empty without the port scan
The web pages are only read with the port scan. The column and the Copy menu
already checked both options, the row details showed an empty list instead of
the "Reading web pages is disabled" note.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Web and port scan settings disabled while the port scan is disabled
The web pages are only read from open ports of the port scan - Read web pages
and its settings are disabled without it (the help tooltip already explained
it). The ports, timeout and attempts of the port scan are disabled while the
port scan is disabled, like the settings of the other probes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Options button to turn the scan options on or off (F1)
A menu next to Scan with the probes and lookups (ping, hostname, port scan,
NetBIOS, ARP / NDP, MAC address, mDNS, web pages, SNMP), Show unreachable,
Expand host view and Open settings... The items are bound to the global
settings, so all tabs use the same values. The settings page (created once and
kept) follows changes made outside of it. Read web pages is only enabled with
the port scan, like in the settings. Disabled while a scan is running.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Menus: Checkmark of checkable menu items in Gray3 instead of the accent color
Like the icons and the submenu arrow of the menu items (used by the scan
options menu of the IP Scanner).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Connections / Listeners / Neighbor Table / WiFi: Auto refresh of 1 / 5 minutes every 1 / 5 hours
AutoRefreshTime.CalculateTimeSpan multiplied minutes and hours by 60 again
(new TimeSpan(0, value * 60, 0)), so the presets 1 min / 5 min refreshed only
every hour / 5 hours. Now TimeSpan.FromSeconds / FromMinutes / FromHours, with
unit tests for all units.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Shared auto refresh timer and control
AutoRefreshTimer: the logic copied into Connections, Listeners, Neighbor Table
and WiFi (stopped while refreshing so refreshes never overlap, paused while
the view is hidden, optional guard), plus the time until the next refresh for
a countdown. A change of the interval while refreshing no longer starts the
timer during the refresh.
AutoRefreshControl: the "Automatically update every" checkbox and the
interval combo box with its item template.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Connections: Shared auto refresh timer and control
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Listeners: Shared auto refresh timer and control
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Neighbor Table: Shared auto refresh timer and control
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: WiFi: Shared auto refresh timer and control
AutoRefreshTimeToStringConverter (a copy of TimeUnitToStringConverter, only
used here) is no longer needed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refresh icon: Spins until the reload is finished, completes its turn
The animation ran once (two turns in 2 s): a longer reload (e.g. the Firewall
rules) showed a standing icon while still loading, and the icon snapped back
to the start when the reload was finished. Now one turn per second, repeated
while reloading, the current turn is completed at the end.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* TaskHelper: Run an action with a minimum duration
For the manual refresh of the tools: the minimum time runs at the same time
as the action instead of before it, so a refresh takes max(action, minimum)
instead of minimum + action.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Connections: Minimum duration of a refresh runs while loading
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Listeners: Minimum duration of a refresh runs while loading
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Neighbor Table: Minimum duration of a refresh runs while loading
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Hosts File Editor: Retry of a locked hosts file waited twice
The catch waited 2.5 s and the next attempt waited again (5 s, the message
said 2 s from 2500 / 1000), and it waited after the last attempt. Now one wait
before the next attempt, the message shows 2.5 s, no wait after the last
attempt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hosts File Editor: Minimum duration of a refresh runs while loading
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Firewall: Minimum duration of a refresh runs while loading
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* WiFi: Minimum duration of reloading the adapters runs while loading
The wait after a disconnect (ScanAsync) stays: it gives Windows time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Dashboard: Minimum duration of the IP geolocation / DNS resolver check runs while requesting
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refresh status in the header: shared control and countdown format
RefreshStatusControl shows "Reloaded at 14:32", a countdown "Next refresh in
00:04" while an automatic refresh is planned, nothing while refreshing (the
refresh icon spins); the tooltip has the date and time. Trimmed first if the
header is narrow. DateTimeHelper.TimeSpanToCountdownString: mm:ss, h:mm:ss
from one hour (fixed width), with tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Connections: Refresh status in the header, countdown to the next refresh
The status line below the list ("Refreshing..." / "Reloaded at") is gone:
the refresh icon spins while refreshing, the header shows the time or the
countdown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Listeners: Refresh status in the header, countdown to the next refresh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Neighbor Table: Refresh status in the header, countdown to the next refresh
The status line below the list only shows errors (add / delete), without an
empty gap otherwise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Hosts File Editor: Refresh status in the header
The status line below the list only shows errors (e.g. a locked hosts file,
hidden again when a retry succeeds), without an empty gap otherwise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Firewall: Refresh status in the header
The status line below the list only shows errors (failed load, rules loaded
with errors, a failed action), without an empty gap otherwise. The loading
indicator of the first load stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* WiFi: Scan status in the header of the networks, countdown to the next scan
The status line below only shows errors and the connection status. No
"Searching for networks..." text and no pulse indicator, the search icon
spins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Changes since the last scan (E1)
A completed scan of the same input as the last completed scan in the tab is
compared with it: New (up now, not before), Gone (up before, not now - a down
row with the previous hostname / MAC is added) and MAC changed (other MAC,
previous one in the tooltip). Change column and counters only with a
comparison, "Last scan at" in the header. Canceled scans, a rescan of selected
hosts and another input don't compare / don't become the baseline. In the
search and the export (Change, PreviousMACAddress). IPScannerScanComparer
with tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Port Scanner: Changes since the last scan (E1)
A completed scan of the same hosts and (resolved) ports as the last completed
scan in the tab is compared with its open ports: Now open / No longer open in
the Change column, counters and "Last scan at" in the header. The open ports
of the last scan are always reported by the scanner (ReportPorts), so a port
that is no longer open has a row with its state also without "Show closed
ports"; a port of a host that was not scanned gets a timed out row. Search
and export (Change). PortScannerScanComparer with tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Repeat the scan automatically (E2)
"Automatically scan every" (1 min - 1 h, AutoRefreshTime.GetScanDefaults) in
the result header with the shared AutoRefreshTimer / AutoRefreshControl and a
countdown ("Next scan in"). Starts after a completed scan of the input, the
interval is the pause after a scan (the timer waits for ScanComplete).
A repeated scan keeps the rows: results are copied into the row of the host
(every host is reported, so a host that is down now updates its row), new hosts
are added, a canceled / failed repeat restores the rows. At the end the
comparison marks the changes, down rows without a change are removed (unless
unreachable hosts are shown). No confirmation, no history entry.
Stops after a cancel / error, a changed input or when the tab is closed; a
manual scan starts the interval again after it. Keeps running while hidden.
The checkbox is per tab, the interval is saved (IPScanner_AutoRefreshTime).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Port Scanner: Repeat the scan automatically (E2)
Like the IP Scanner: "Automatically scan every" with countdown, starts after a
completed scan, the interval is the pause after a scan. A repeated scan keeps
the rows: the scanner reports every port with a row (ReportPorts), its state
is updated in place (with the open ports of the host group), new open ports
are added, a port of a host that was not scanned becomes timed out. A
canceled / failed repeat restores the states. Ports that are not open without
a change are removed at the end (unless closed ports are shown). No
confirmation, no history entry. Interval saved (PortScanner_AutoRefreshTime).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Notification of the changes of a repeated scan
Settings Notification (popup, sound, display duration; default off, also the
Port Scanner settings): a repeated scan with changes shows one notification
(title tool + input, up to three changes one per line, otherwise the
counters) and / or plays a sound - only new hosts like a host that is up
(green, asterisk), a gone host / changed MAC like a host that is down (red,
exclamation), as in the Ping Monitor. Not for a manual scan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Port Scanner: Notification of the changes of a repeated scan
Like the IP Scanner: one notification per repeated scan with changes (up to
three ports with service, otherwise the counters) and / or a sound - only
ports open now like up, a port no longer open like down. Settings section
Notification on the settings page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Gone host of a repeated scan without the previous hostname / MAC
The row of a host that is down now takes the values of the down result (no MAC
address, often no hostname). MarkGone shows the hostname and MAC address of the
previous scan if the host has none now, like a gone row of a normal scan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: IP Scanner / Port Scanner: Shared repeat of the scan (ScanRepeater)
The repeat (checkbox, intervals, saved interval, timer that waits for the end
of the scan, armed after a completed scan, disarmed by a manual scan or a
changed input, closed with the tab) was copied into both view models.
ScanRepeater holds it once; behaviour unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner: Input changed during a scan was repeated anyway
The setter disarmed the repeat, but the end of the running scan armed it
again: the next repeat scanned the new input without its confirmation and
mixed it with the rows of the old input (e.g. a history entry selected while
scanning). A change during a scan now keeps that scan from being repeated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner / Port Scanner: A failed repeated scan is tried again
One failed repeated scan (e.g. a DNS timeout for a hostname of the input)
ended the repetition for good. It is tried again after the interval now (the
message is shown); only a cancel, a changed input or closing the tab stop it.
A failed manual scan still doesn't start the repetition.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner: Counters of a canceled repeated scan
A canceled / failed repeated scan restored the rows of the last scan, but the
counters (up / down, open / closed / timed out, scanned) kept the partial
values of the canceled scan, and the Port Scanner's closed / timed out ports
per host (group headers) were empty or partial. Both are restored now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner: Change of a rescanned host / port not updated
A rescan doesn't compare (it isn't a scan of the input), so a rescanned row
kept its old change (e.g. Gone for a host that is up again), and the Port
Scanner's rescanned hosts lost theirs (rows replaced). The rescanned rows are
compared with the same previous scan again (ApplyComparison, shared with the
scan); a rescan of Port Scanner hosts reports the ports that were open, so a
port that is no longer open keeps its row. Counters from the rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Port Scanner: Notification titled with the current instead of the scanned hosts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Row of an address no longer in the input stays after a repeated scan
CreateBaseline skipped gone placeholders, but the changes are reset before it
is called - the check never ran (removed, test adjusted). The case it was
meant for: a row whose IP address is no longer part of the input (e.g. a
hostname that resolves to another address now) is not scanned by a repeat and
stayed unchanged forever with "Show unreachable". Rows that were not reported
by a completed repeated scan are removed (shown as gone once).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Repeated scan reports only the down hosts with a row
ReportAllHosts made the scanner create and look up (DNS, neighbor table) a
result for every unreachable address of every repeat (e.g. ~65,000 for a
/16), most of them thrown away. ReportHosts reports only the hosts that have a
row, so their row is updated when they are down now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: Rows of the gone hosts looked up once, not searched per host
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Shared up / down notification (Ping Monitor, IP Scanner, Port Scanner)
NotificationManager.ShowStatusChange: icon, color and sound of up / down in
one place (were hard-coded in the Ping Monitor and copied into both scanners),
popup and sound optional. FormatChanges: up to three changes one per line,
otherwise the summary. Behaviour unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner / Port Scanner: Column "Since last scan" in the design of the import status
The header used Strings.Change, a verb elsewhere ("Change" buttons, German
"Ändern"): own string SinceLastScan (with a comment for the translators).
The cells use the design of the status of the profile import: 12 px icon and
the text in its color - New / Now open with a gray plus like "New" there,
Gone / No longer open red, MAC changed orange.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: Notifications: one model (NotificationInfo, NotificationStatus)
NotificationManager.Show(NotificationInfo, popup, sound) replaces Show(icon,
color, ...) and ShowStatusChange: the tool, the status, the title and the
message; the window maps the status to icon, color and sound in one place, with
the colors of the application (red #b95353 instead of "Red").
Four states (NotificationStatusHelper.FromChanges, with tests): up (only
additions), down (only removals), up and down (both - the icon half green /
half red, split along the diagonal; was red before), changed (e.g. a MAC
address, orange).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Notifications: Header with the tool that sent it
Header row with the icon and the translated name of the tool (like the
application list) and the time; below the status icon, the title (only the
target - no "IP Scanner · " prefix any more) and the message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Notifications: A click opens the tool and the tab that sent it
The click only showed the main window. Now it opens the tool of the
notification; the IP Scanner and Port Scanner select the tab of the scan
(ShowTabRequest, SelectTab - only the tool if the tab was closed or moved to
another window).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: Notifications with the tool in the header, status colors, click
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Changelog: Shorten / consolidate the entries of this branch
One entry per tool for the refresh changes (status in the header + faster
refresh), IP Scanner: status icons + row details and the Options button + the
disabled port scan settings merged; long entries (web pages, SNMP, local
subnet, mDNS) shortened - details are in the docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Exclusion of a hostname: a failed A or AAAA query excluded only some addresses (Copilot review)
A timeout / SERVFAIL of one query became an empty list, so a successful
query of the other family returned a partial result and the address that
should be excluded could be scanned. A failed query now rejects the
exclusion (nothing is scanned); NXDOMAIN still counts as no record.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner / Port Scanner: Counters below the Result header, header no longer overflows (Copilot review)
The counters (incl. the changes since the last scan), the last scan status,
the repeat and the search were in one right-aligned horizontal StackPanel:
wider than the view at 1024px (profiles open) and the status was measured
with infinite width, so it was never trimmed. The header is now a grid like
the other tools (status in the star column, trimmed first), the counters
have their own line below it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Notifications: One line per change "address · details · status", the status in its color
Ping Monitor, IP Scanner and Port Scanner use the same syntax: the IP
address (and hostname) first, then the details, the status last - no more
":" (e.g. "10.0.0.5 (server) · New", "10.0.0.5 (server) · 22/tcp (ssh) ·
No longer open" with the protocol, "10.0.0.1 · Up"). The status is shown in
the color of its status (up green, down red, changed orange); more than
three changes show one line per counter. Removes the unused strings
HostIsUp / HostIsDown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner: Repeated scan without a host to scan lost the counters / marked all ports timed out (review #2)
A repeated scan that ended before scanning (e.g. a hostname or an excluded
hostname could not be resolved once) kept the rows but not the counters
(reset by Start); the Port Scanner even set every port of the last scan to
timed out, because no port was reported. It is now discarded like a
canceled repeated scan: rows and counters of the last scan, tried again
after the interval.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner / Port Scanner: Repeat started a second scan while a manual scan waited for its confirmation (review #1)
IsRunning is only set after the "scan many IP addresses / ports" dialog,
so the repeat timer could start a repeated scan while it was open; after
the confirmation both scans ran (one cancellation token, mixed rows and
counters). The repeat now waits while the dialog is open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Row of a gone host without its role (review #5)
The baseline of a scan didn't keep the role, so the row added for a gone
default gateway / DNS server had no role icon, tooltip, search match and
exported role. The role of the previous scan is now kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: SNMP: SNMPv3 privacy provider and error codes in SNMPV3Helper
The privacy / authentication providers of SNMPv3 credentials and the error
codes of a report (usmStats) move from SNMPClient into a shared helper, so
the IP Scanner can use them for SNMPv3. Behaviour unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: SNMPv3 for the SNMP system information, error of a host in the row details / export
SNMPSystemInfoResolver takes the version and credentials (SNMPCredentials,
without the secrets in ToString). v3: a discovery request first (any v3
agent answers it with a report, also without valid credentials, so it
still finds the host), then the GET request with the user. Wrong
credentials are answered with a report: the error (unknown user,
authentication failed) is shown in the SNMP row details and exported as
SNMPError (last column). The host duration counts both v3 requests.
The settings stay v1 / v2c; the v3 credentials come from a profile / group
(next steps).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Profiles: SNMP override of the IP Scanner in profiles and groups
New fields IPScanner_OverrideSNMP, version, community, v3 security,
username, authentication / privacy provider and passwords in ProfileInfo
and GroupInfo; the community and the passwords are SecureStrings and saved
like the ones of the SNMP tool (encrypted profile file). Default off, so
existing profile files load unchanged.
Profiles.Application.IPScanner.GetSNMPCredentials: the profile before its
group, otherwise null (the settings). Tests for the order, the round trip
of the profile file and old profile files (the test project now references
NETworkManager.Profiles).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Profiles: SNMP override of the IP Scanner in the profile and group dialog
IP Scanner section of the profile dialog and a new IP Scanner tab in the
group dialog: "Version" overrides the SNMP version and credentials (v1 /
v2c with a community, v3 with security level, user, authentication and
privacy). One control (SNMPCredentialsControl) with its view model for
both dialogs; can't be saved with a missing community, username or
password (error icon of the tab). Passwords are only saved for the
selected version / security level and stay unchanged unless a new one is
entered; warning if the profile file is not encrypted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: A tab opened with a profile uses the SNMP version and credentials of the profile / group
AddTab(profile) resolves the override (the profile before its group,
otherwise the settings) and passes it to the tab, which uses it for every
scan, rescan and repeat - also if its input is changed later, like the
ports of a profile in the Port Scanner. The options menu of the tab shows
the source (new string SNMPVersionAndCredentialsOfX).
Docs: profile / group section of the IP Scanner, SNMP v3 (discovery,
error, SNMPError), changelog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Profiles: IP Scanner SNMP secrets in the order of the tools
In ProfileFileData and the serializable profile / group the IP Scanner
values come first (like in ProfileInfo / GroupInfo), before Remote
Desktop and SNMP. Only moved, behaviour unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Refactor: SNMP: Version and credentials of the profile and group dialog with SNMPCredentialsControl
The SNMP tool's override of the version and credentials in the profile and
group dialog uses the same control and view model as the IP Scanner
(SNMPCredentialsViewModel as SNMP_Credentials) instead of its own ~400
lines of XAML and 15 properties per dialog. The seven validation triggers
of the tab error icon and of the Save button are one condition (HasError).
Behaviour and saved values unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Ping Monitor / IP Scanner / Port Scanner: Notification popup on, sound off by default
IP Scanner / Port Scanner: the popup is on by default - it is only shown
for a scan repeated by "Automatically scan every", which has to be
enabled. Ping Monitor: the popup stays on, the sound is off by default.
Only the defaults change; existing settings are kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Roles of IPv6 link-local hosts matched across interfaces (Copilot review)
The roles were keyed without the IPv6 scope id: the local address
fe80::23%12 made fe80::23%7 on another interface the local computer, and
the gateway fe80::1%12 made fe80::1%3 a gateway - which also skipped the
proxy ARP check of the neighbor cache. The roles keep the scope id now:
an address with scope id only matches the same interface (or an address
configured without one), an address without scope id the roles on every
interface.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: IP Scanner: Tooltip of the port status said Closed for ports that timed out (Copilot review)
No open port doesn't mean the ports are closed (they may have timed out,
and the ports that are not open are hidden unless "Show unreachable" is
on). The tooltip shows "No open ports found!" like the row details.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IP Scanner: SNMP credentials of a profile / group in plain text only during a scan (Copilot review)
A tab kept the converted (plain text) passwords of the profile / group for
its whole lifetime, also without a scan or with SNMP disabled. It keeps a
protected copy now (SNMPSecureCredentials, SecureStrings); a scan or
rescan converts it only if the SNMP request is sent, and the options of
the last scan (kept for a rescan) drop it when the scan is completed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fix: Ping Monitor: Still canceling after a stop when no host was left (Copilot review)
Stop after the hostnames were resolved, with no host left (not resolved /
all excluded): IsCanceling stayed set and SetHost (profile, navigation)
was rejected as still canceling. Cleared like on the other paths.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes proposed in this pull request
Related issue(s)
To-Do
Contributing
By submitting this pull request, I confirm the following: