Итерация 2: сканирование сети
- Phinx миграции: network_ranges, scan_jobs, discovered_hosts, audit_log - Models: NetworkRange, ScanJob, DiscoveredHost - Repositories с CRUD для всех сущностей - NetworkScanner: ping sweep + TCP connect + ARP table + reverse DNS - PingScanner, TcpPortScanner (curl_multi для параллелизма), ArpTableReader - HostFingerprintService: vendor detection + confidence scoring - ScanJobRunner + CLI worker (bin/run-scan-worker.php) - Discovery UI: управление диапазонами, запуск скана, таблица находок - NetworkRangeController с валидацией CIDR - Обновлён public/index.php с DI конфигурацией для новых сервисов
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Domovoy\Services\Discovery;
|
||||
|
||||
class ArpTableReader
|
||||
{
|
||||
/**
|
||||
* Read ARP table from system.
|
||||
* Returns array keyed by IP => ['mac' => '...', 'vendor' => '...']
|
||||
*/
|
||||
public function read(): array
|
||||
{
|
||||
$entries = [];
|
||||
|
||||
// Try ip neigh first (modern Linux)
|
||||
$output = [];
|
||||
$exitCode = 0;
|
||||
exec('ip neigh show 2>/dev/null', $output, $exitCode);
|
||||
if ($exitCode === 0) {
|
||||
foreach ($output as $line) {
|
||||
if (preg_match('/^(\d+\.\d+\.\d+\.\d+)\s+.*lladdr\s+([0-9a-f:]+)/i', $line, $m)) {
|
||||
$entries[$m[1]] = ['mac' => strtolower($m[2]), 'vendor' => null];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: arp -a
|
||||
if (empty($entries)) {
|
||||
exec('arp -a 2>/dev/null', $output, $exitCode);
|
||||
if ($exitCode === 0) {
|
||||
foreach ($output as $line) {
|
||||
if (preg_match('/\((\d+\.\d+\.\d+\.\d+)\)\s+at\s+([0-9a-f:]+)/i', $line, $m)) {
|
||||
$entries[$m[1]] = ['mac' => strtolower($m[2]), 'vendor' => null];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user