Skip to content

Feature: IP scanner discovery (mDNS, ARP/NDP, SNMP, Web) - #3685

Open
BornToBeRoot wants to merge 127 commits into
mainfrom
feature/ip-scanner-discovery
Open

BornToBeRoot wants to merge 127 commits into
mainfrom
feature/ip-scanner-discovery

Conversation

@BornToBeRoot

Copy link
Copy Markdown
Owner

Description

See commits

Related issue

Ref #3609
Ref #149

Type of change

  • 🐛 Bug fix
  • ✨ New feature / improvement
  • 📖 Documentation / website
  • 🧹 Refactoring / maintenance (no functional change)

BornToBeRoot and others added 30 commits October 30, 2026 20:31
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>
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>
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>
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>
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>
…bnet (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>
…es (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>
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>
… 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>
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>
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>
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>
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>
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>
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>
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>
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>
…s (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>
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>
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>
…s (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>
…es 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>
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>
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>
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>
… 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>
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>
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>
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>
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>
BornToBeRoot and others added 10 commits November 1, 2026 02:41
… 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>
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>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt 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>
…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>
…tus)

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>
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>
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>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Failed A or AAAA lookups can silently produce partial exclusions, allowing IP addresses intended to be excluded to be scanned.

2 open issues
1 file not reviewed
  • Source/NETworkManager.Localization/Resources/Strings.Designer.cs: Generated file

Review effort: Balanced

BornToBeRoot and others added 13 commits November 1, 2026 14:47
…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>
…o 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>
…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>
…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>
…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>
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>
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>
…n 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>
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>
…alog

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>
…dentials 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>
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>
…og 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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Removing IPv6 scope IDs conflates hosts and gateway roles across interfaces and can incorrectly bypass proxy checks.

4 open issues
2 resolved since last review
1 file not reviewed
  • Source/NETworkManager.Localization/Resources/Strings.Designer.cs: Generated file

Review effort: Balanced

Comment on lines +30 to +32
var key = IPAddressHelper.WithoutScopeId(ipAddress);

roles[key] = roles.GetValueOrDefault(key) | role;
var openPorts = ports.Where(x => x.State == PortState.Open).ToList();

if (openPorts.Count == 0)
return ResourceTranslator.Translate(ResourceIdentifier.PortState, PortState.Closed);
Security = security,
Username = username ?? string.Empty,
AuthenticationProvider = authenticationProvider,
Auth = ToString(auth),
StatusMessage =
$"{Strings.TheFollowingHostnamesCouldNotBeResolved} {string.Join(", ", hosts.hostnamesNotResolved)}";
IsStatusMessageDisplayed = true;
IsRunning = false;
…d 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>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants