phalanx-php / argos
Network discovery, probing, and device management for Phalanx
Requires
- php: ^8.4
- mlocati/ip-lib: ^1.22
- phalanx-php/aegis: ^0.5
- react/async: ^4.3
- react/child-process: ^0.6
- react/datagram: ^1.10
- react/dns: ^1.13
- react/event-loop: ^1.5
- react/promise: ^3.2
- react/socket: ^1.16
Suggests
- clue/mdns-react: Required for mDNS zeroconf discovery
- clue/multicast-react: Required for mDNS and SSDP discovery (multicast UDP)
- clue/ssdp-react: Required for SSDP/UPnP device discovery
This package is not auto-updated.
Last update: 2026-04-28 08:47:58 UTC
README
Phalanx Argos
Part of the Phalanx async PHP framework.
Network discovery, probing, and device management as Phalanx tasks. Scan subnets, probe ports, wake machines, and discover services--all through the same scope-driven concurrency model as the rest of Phalanx.
Table of Contents
- Installation
- Quick Start
- Subnet Addressing
- Probe Strategies
- Task Reference
- Discovery
- Value Objects
- Configuration
Installation
composer require phalanx/argos
Note
Requires PHP 8.4 or later.
Dependencies: phalanx/aegis, mlocati/ip-lib, react/datagram, react/socket, react/dns, and react/child-process.
Optional: clue/multicast-react, clue/mdns-react, clue/ssdp-react for mDNS and SSDP discovery.
Quick Start
<?php use Phalanx\Application; use Phalanx\Argos\NetworkServiceBundle; use Phalanx\Argos\Task\ScanSubnet; use Phalanx\Argos\Subnet; [$app, $scope] = Application::starting() ->providers(new NetworkServiceBundle()) ->compile() ->boot(); $hosts = $scope->execute(new ScanSubnet( Subnet::from('192.168.1.0/24'), )); foreach ($hosts as $result) { if ($result->reachable) { echo "{$result->ip} is up ({$result->latencyMs}ms)\n"; } } $scope->dispose(); $app->shutdown();
Subnet Addressing
Subnet wraps mlocati/ip-lib for CIDR range handling. It supports both IPv4 and IPv6 and exposes addresses as a lazy generator--iterating a /16 doesn't allocate 65,536 strings upfront.
<?php use Phalanx\Argos\Subnet; $net = Subnet::from('10.0.0.0/24'); // 256 addresses $net = Subnet::from('fd00::/64'); // IPv6 works the same way foreach ($net->addresses() as $ip) { // lazy -- yields one address at a time }
Probe Strategies
ProbeStrategy is a factory that produces the right probe task for a given method. Swap scan strategies without changing calling code:
<?php use Phalanx\Argos\ProbeStrategy; // TCP connect probe on port 443 with 2s timeout $probe = ProbeStrategy::tcp(port: 443, timeout: 2.0); // UDP probe with a custom payload $probe = ProbeStrategy::udp(port: 53, payload: "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00"); // ICMP ping with 1s timeout $probe = ProbeStrategy::ping(timeout: 1.0);
Pass a strategy to ScanSubnet to control how each host is probed:
<?php use Phalanx\Argos\ProbeStrategy; use Phalanx\Argos\Subnet; use Phalanx\Argos\Task\ScanSubnet; // Scan for web servers instead of pinging $hosts = $scope->execute(new ScanSubnet( Subnet::from('192.168.1.0/24'), probe: ProbeStrategy::tcp(port: 80, timeout: 1.0), concurrency: 50, ));
Task Reference
All tasks live in the Phalanx\Argos\Task namespace. Each is an invokable class with serializable constructor args.
PingHost
ICMP ping via child process. Implements HasTimeout and Retryable.
<?php use Phalanx\Argos\Task\PingHost; $result = $scope->execute(new PingHost('192.168.1.1')); // ProbeResult { ip: '192.168.1.1', reachable: true, latencyMs: 1.2, method: 'ping' }
ProbePort
TCP connect probe. Implements HasTimeout.
<?php use Phalanx\Argos\Task\ProbePort; $result = $scope->execute(new ProbePort('192.168.1.1', port: 22)); // ProbeResult { ip: '192.168.1.1', reachable: true, latencyMs: 3.4, method: 'tcp', port: 22 }
ProbeUdp
UDP probe with payload. Implements HasTimeout.
<?php use Phalanx\Argos\Task\ProbeUdp; $result = $scope->execute(new ProbeUdp('192.168.1.1', port: 53, payload: $dnsQuery));
WakeHost
Send a Wake-on-LAN magic packet via UDP broadcast.
<?php use Phalanx\Argos\Task\WakeHost; $scope->execute(new WakeHost(mac: '00:11:22:33:44:55'));
ScanSubnet
Scan a CIDR range with bounded concurrency via $scope->map().
<?php use Phalanx\Argos\Subnet; use Phalanx\Argos\Task\ScanSubnet; $results = $scope->execute(new ScanSubnet( Subnet::from('10.0.0.0/24'), concurrency: 100, ));
ScanPorts
Scan multiple ports on a single host.
<?php use Phalanx\Argos\Task\ScanPorts; $results = $scope->execute(new ScanPorts( ip: '192.168.1.1', ports: [22, 80, 443, 3306, 5432, 8080], ));
WakeAndWait
Send a WOL packet, then retry-probe until the host comes up.
<?php use Phalanx\Argos\Task\WakeAndWait; $result = $scope->execute(new WakeAndWait( mac: '00:11:22:33:44:55', ip: '192.168.1.50', ));
IdentifyDevice
Concurrent ping + port scan to fingerprint a device.
<?php use Phalanx\Argos\Task\IdentifyDevice; $host = $scope->execute(new IdentifyDevice('192.168.1.1')); // Host { ip, mac, hostname, services, metadata }
ResolveHostname
Async DNS resolution via react/dns.
<?php use Phalanx\Argos\Task\ResolveHostname; $ip = $scope->execute(new ResolveHostname('example.com'));
Discovery
Discovery tasks require optional dependencies. Install them as needed.
SSDP/UPnP Discovery
Requires clue/ssdp-react.
<?php use Phalanx\Argos\Discovery\DiscoverSsdp; $devices = $scope->execute(new DiscoverSsdp(timeout: 5.0));
mDNS/Zeroconf Discovery
Requires clue/mdns-react.
<?php use Phalanx\Argos\Discovery\DiscoverMdns; $services = $scope->execute(new DiscoverMdns(serviceType: '_http._tcp.local', timeout: 3.0));
Value Objects
ProbeResult -- readonly result from any probe task:
| Property | Type | Description |
|---|---|---|
ip |
string |
Target IP address |
reachable |
bool |
Whether the host responded |
latencyMs |
?float |
Round-trip time in milliseconds |
method |
string |
Probe method used (ping, tcp, udp) |
port |
?int |
Port probed (null for ICMP) |
responseData |
?string |
Raw response data (UDP probes) |
Host -- readonly device identity:
| Property | Type | Description |
|---|---|---|
ip |
string |
IP address |
mac |
?string |
MAC address if resolved |
hostname |
?string |
Hostname if resolved |
services |
array |
Open ports / detected services |
metadata |
array |
Additional discovery data |
Configuration
NetworkConfig controls defaults for all network tasks:
<?php use Phalanx\Argos\NetworkConfig; use Phalanx\Argos\NetworkServiceBundle; $bundle = new NetworkServiceBundle(new NetworkConfig( defaultTimeout: 3.0, defaultConcurrency: 50, pingBinary: '/usr/bin/ping', broadcastAddress: '192.168.1.255', wolPort: 9, ));
NetworkServiceBundle registers DatagramFactory, Connector, and NetworkConfig into the service graph.