repository = $repository; } public function create(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $data = $request->getParsedBody(); $name = trim($data['name'] ?? ''); $cidr = trim($data['cidr'] ?? ''); if ($name === '' || $cidr === '') { $response->getBody()->write('Name and CIDR are required'); return $response->withStatus(400); } // Basic CIDR validation if (!$this->isValidCidr($cidr)) { $response->getBody()->write('Invalid CIDR format'); return $response->withStatus(400); } $range = new \Domovoy\Models\NetworkRange(); $range->name = $name; $range->cidr = $cidr; $range->enabled = true; $this->repository->save($range); return $response ->withHeader('Location', '/discovery') ->withStatus(302); } public function toggle(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $data = $request->getParsedBody(); $id = $data['id'] ?? null; if ($id !== null) { $range = $this->repository->findById((int)$id); if ($range !== null) { $range->enabled = !$range->enabled; $this->repository->save($range); } } return $response ->withHeader('Location', '/discovery') ->withStatus(302); } public function delete(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $data = $request->getParsedBody(); $id = $data['id'] ?? null; if ($id !== null) { $this->repository->delete((int)$id); } return $response ->withHeader('Location', '/discovery') ->withStatus(302); } private function isValidCidr(string $cidr): bool { if (!preg_match('#^(\d+\.\d+\.\d+\.\d+)/(\d{1,2})$#', $cidr, $matches)) { return false; } $ip = $matches[1]; $maskInt = (int)$matches[2]; if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { return false; } if ($maskInt < 8 || $maskInt > 32) { return false; } $long = ip2long($ip); if ($long === false) { return false; } $value = (int)sprintf('%u', $long); return $this->isInRange($value, '10.0.0.0', 8) || $this->isInRange($value, '172.16.0.0', 12) || $this->isInRange($value, '192.168.0.0', 16) || $this->isInRange($value, '169.254.0.0', 16) || $this->isInRange($value, '127.0.0.0', 8); } private function isInRange(int $ip, string $network, int $mask): bool { $networkLong = ip2long($network); if ($networkLong === false) { return false; } $networkValue = (int)sprintf('%u', $networkLong); $maskValue = (0xFFFFFFFF << (32 - $mask)) & 0xFFFFFFFF; return ($ip & $maskValue) === ($networkValue & $maskValue); } }