característica: Se introdujeron Endpoints API REST para búsqueda y verificación de IP con clasificación de tipo IP y eliminar el script de IP heredado.

This commit is contained in:
DANYDHSV 2025-11-26 12:16:49 -06:00
parent 3a061d8889
commit 0be508e749
8 changed files with 1300 additions and 50 deletions

173
CHANGELOG.md Normal file
View File

@ -0,0 +1,173 @@
# Changelog
Todos los cambios notables en este proyecto serán documentados en este archivo.
El formato está basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/),
y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/).
---
## [1.1.0] - 2025-11-26
### ✨ Añadido
#### API REST Completa
- **Endpoint `event.ip_request`**: Búsqueda de IPs disponibles en un segmento de red
- Acepta parámetro `segment` para especificar el tercer octeto (0-255)
- Retorna lista de IPs disponibles y en uso
- Filtra automáticamente IPs administrativas (1-30, 254)
- Incluye contadores de IPs disponibles, en uso y filtradas
- **Endpoint `event.ip_check`**: Verificación de estado de una IP específica
- Acepta parámetro `ip` con dirección completa (172.16.X.X)
- Retorna estado: disponible, en uso o desconocido
- Incluye información del tipo de IP (administrativa vs. cliente)
- Proporciona recomendaciones de uso
- **Soporte para webhooks**: Habilitado `supportsWebhookEvents: true` en manifest
- **Manejo de peticiones JSON**: Detección automática de Content-Type para API vs Frontend
#### Arquitectura y Código
- **Clase `ApiHandlers.php`**: Manejadores dedicados para eventos de API REST
- `handleApiRequest()`: Router principal de eventos
- `handleIpRequest()`: Procesamiento de búsqueda de IPs
- `handleIpCheck()`: Procesamiento de verificación de IPs
- **Clase `IpSearchService.php`**: Servicio de búsqueda de IPs con lógica de negocio
- `buscarIpsDisponibles()`: Búsqueda de IPs en segmento específico
- `obtenerIpsEnUso()`: Obtención de IPs desde API UNMS
- `isAdminIp()`: Método estático para detectar IPs administrativas
- `getIpType()`: Método estático para obtener información del tipo de IP
- **Sistema de filtrado de IPs**: Clasificación automática de IPs administrativas vs. cliente
- Rango administrativo: .1-.30 y .254
- Rango cliente: .31-.253
- Etiquetas visuales en frontend
- Filtrado automático en API REST
#### Documentación
- **README.md completo**: Documentación profesional del plugin
- Guía de instalación y configuración
- Documentación completa de API REST
- Ejemplos de uso en múltiples lenguajes (cURL, PHP, JavaScript, Python)
- Tabla de códigos de error
- Troubleshooting y soporte
- **CHANGELOG.md**: Archivo dedicado para control de versiones
### 🔄 Mejorado
- **Separación de responsabilidades**: Lógica de negocio separada en clases dedicadas
- **Manejo de errores mejorado**: Respuestas JSON estructuradas con códigos de error descriptivos
- **Sistema de logging**: Logs más detallados y organizados para debugging
- Registro de tipo de petición (HTML vs JSON)
- Logging de eventos API procesados
- Información de errores con stack traces
- **Compatibilidad dual**: Frontend HTML y API REST funcionan simultáneamente
- Detección automática del tipo de petición
- Sin interferencia entre modos
- **Validación de datos**: Validación robusta de parámetros en API
- Validación de formato de IP
- Validación de rangos de segmento
- Mensajes de error descriptivos
### 🔧 Técnico
- **Namespace PHP**: `SiipAvailableIps` para evitar conflictos
- **Manejo global de errores**: Error handler para convertir errores PHP en respuestas JSON
- **Configuración SSL**: Soporte para certificados autofirmados en desarrollo
- **Timeouts configurados**: Timeouts de conexión y ejecución para API UNMS
---
## [1.0.1] - 2025-11-25
### ✨ Añadido
- **Frontend web moderno**: Interfaz de usuario con diseño responsive y atractivo
- Diseño con gradientes y glassmorphism
- Tipografía Google Fonts (Inter)
- Animaciones suaves y micro-interacciones
- Modo oscuro integrado
- **Búsqueda de IPs por segmento**: Campo de entrada para tercer octeto
- **Función copiar al portapapeles**: Botón de copia rápida para cada IP
- Feedback visual al copiar
- Compatible con navegadores modernos
- **Estadísticas en tiempo real**: Contadores de IPs disponibles y en uso
- Tarjetas de estadísticas visuales
- Actualización dinámica tras búsqueda
- **Integración con API UNMS**: Conexión directa con UISP Network
- Obtención de IPs en uso desde dispositivos
- Soporte para HTTPS
- Manejo de errores de conexión
### 🔄 Mejorado
- **Conexión con API UNMS**: Optimización de peticiones HTTP
- Timeouts configurables
- Mejor manejo de errores de red
- Logging de respuestas
- **Búsqueda de IPs**: Algoritmo optimizado para comparación de rangos
- Ordenamiento de IPs por último octeto
- Cálculo eficiente de IPs disponibles
- Validación de segmentos (0-255)
### 🐛 Corregido
- Mejoras en la estabilidad de conexión con API UNMS
- Corrección de validación de segmentos fuera de rango
- Fix en ordenamiento de IPs en tabla de resultados
---
## [1.0.0] - 2025-11-25
### ✨ Lanzamiento Inicial
#### Funcionalidades Core
- **Búsqueda básica de IPs**: Funcionalidad principal del plugin
- Búsqueda en rangos 172.16.X.x
- Detección de IPs en uso
- Cálculo de IPs disponibles
- **Integración con UISP CRM**: Plugin nativo para UCRM
- Instalación vía interfaz de plugins
- Configuración desde panel de administración
- Acceso desde menú de reportes
- **Interfaz web básica**: Primera versión del frontend
- Formulario de búsqueda simple
- Tabla de resultados
- Diseño básico responsive
#### Configuración
- **Parámetros de configuración**:
- Dirección IP/dominio del servidor
- Token de API UCRM
- Token de API UNMS (opcional)
- Modo debug
- Nivel de logging
#### Integración
- **API UNMS**: Conexión con UISP Network para obtener IPs
- **Sistema de logs**: Archivo `plugin.log` para debugging
- **Compatibilidad**: UCRM 1.0.0+ y UNMS 1.0.0+
---
## Tipos de Cambios
- **✨ Añadido**: Para nuevas funcionalidades
- **🔄 Mejorado**: Para cambios en funcionalidades existentes
- **🐛 Corregido**: Para corrección de bugs
- **🔧 Técnico**: Para cambios técnicos internos
- **🗑️ Eliminado**: Para funcionalidades removidas
- **⚠️ Deprecado**: Para funcionalidades que serán removidas
- **🔒 Seguridad**: Para parches de seguridad
---
## Versionamiento
Este proyecto sigue [Semantic Versioning](https://semver.org/lang/es/):
- **MAJOR** (X.0.0): Cambios incompatibles con versiones anteriores
- **MINOR** (0.X.0): Nueva funcionalidad compatible con versiones anteriores
- **PATCH** (0.0.X): Correcciones de bugs compatibles con versiones anteriores
---
**Última actualización**: 26 de noviembre de 2025

529
README.md Normal file
View File

@ -0,0 +1,529 @@
# SIIP - Buscador de IP's Disponibles UISP
[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](manifest.json)
[![UCRM](https://img.shields.io/badge/UCRM-Compatible-green.svg)](https://uisp.com/)
[![UNMS](https://img.shields.io/badge/UNMS-Compatible-green.svg)](https://uisp.com/)
Plugin para UISP CRM (anteriormente UCRM) que permite buscar direcciones IP disponibles en la red UISP/UNMS y asignarlas a clientes, evitando duplicados y mejorando la gestión de direcciones IP.
---
## 📋 Tabla de Contenidos
- [Características](#-características)
- [Requisitos](#-requisitos)
- [Instalación](#-instalación)
- [Configuración](#-configuración)
- [Uso del Frontend Web](#-uso-del-frontend-web)
- [API REST](#-api-rest)
- [Endpoints Disponibles](#endpoints-disponibles)
- [Ejemplos de Uso](#ejemplos-de-uso)
- [Estructura del Proyecto](#-estructura-del-proyecto)
- [Filtrado de IPs Administrativas](#-filtrado-de-ips-administrativas)
- [Logs y Debugging](#-logs-y-debugging)
- [Changelog](#-changelog)
- [Soporte](#-soporte)
---
## ✨ Características
- 🔍 **Búsqueda de IPs disponibles** por segmento de red (172.16.X.x)
- 🌐 **Interfaz web moderna** con diseño responsive y atractivo
- 🔌 **API REST completa** para integraciones externas
- 📋 **Copiar al portapapeles** con un solo clic
- 🎯 **Filtrado inteligente** de IPs administrativas vs. IPs para clientes
- 📊 **Estadísticas en tiempo real** de IPs disponibles y en uso
- 🔐 **Integración nativa** con UISP CRM y UNMS
- 🪝 **Soporte para webhooks** y eventos personalizados
- 📝 **Sistema de logs detallado** para debugging
---
## 📦 Requisitos
- **UISP CRM** versión 1.0.0 o superior
- **UISP UNMS** versión 1.0.0 o superior (opcional)
- **PHP** 7.2 o superior
- **cURL** habilitado en PHP
- **Token de API** de UCRM
- **Token de API** de UNMS (opcional, para búsqueda de IPs)
---
## 🚀 Instalación
### Método 1: Instalación Manual
1. Descarga o clona este repositorio
2. Comprime la carpeta del plugin en formato `.zip`
3. En UISP CRM, ve a **Sistema → Plugins**
4. Haz clic en **"Subir nuevo plugin"**
5. Selecciona el archivo `.zip` y súbelo
6. Activa el plugin desde la lista de plugins
### Método 2: Instalación desde Git
```bash
cd /path/to/ucrm/data/plugins/
git clone <repository-url> siip-available-ips
cd siip-available-ips
composer install
```
---
## ⚙️ Configuración
Después de instalar el plugin, configura los siguientes parámetros:
### Parámetros Requeridos
| Parámetro | Descripción | Ejemplo |
|-----------|-------------|---------|
| **Dirección IP o dominio del servidor** | IP o dominio donde se ejecuta UISP CRM | `172.16.5.120` o `sistema.empresa.com` |
| **Token de la API UCRM** | Token de autenticación de UCRM (36 caracteres) | `3d3fa6c9-e268-6e8b-b4d5-aae394d99d7d` |
### Parámetros Opcionales
| Parámetro | Descripción | Uso |
|-----------|-------------|-----|
| **Token de la API UNMS** | Token de UNMS (34 caracteres) | Para búsqueda de IPs en dispositivos de red |
| **Debug Mode** | Modo de depuración | Habilita logs más detallados |
| **Enable debug logs** | Logs verbosos | Información adicional en logs |
### Cómo obtener los tokens:
#### Token UCRM:
1. Ve a **Sistema → Seguridad → Claves de aplicación**
2. Crea una nueva clave con permisos de lectura/escritura
3. Copia el token generado
#### Token UNMS:
1. Accede al módulo **UISP Network**
2. Ve a **Ajustes → Usuarios → API Tokens**
3. Genera un nuevo token
4. Copia el token generado
---
## 🖥️ Uso del Frontend Web
### Acceso
El frontend web está disponible en:
- **Menú UCRM**: `Reportes → Consultar IP's Disponibles`
- **URL directa**: `https://tu-servidor/plugins/siip-available-ips/public.php`
### Interfaz de Usuario
La interfaz incluye:
1. **Campo de búsqueda**: Ingresa el tercer octeto del segmento (ej: `5` para buscar en `172.16.5.x`)
2. **Botón "Buscar IPs"**: Ejecuta la búsqueda
3. **Tabla de resultados**: Muestra las IPs disponibles con:
- Dirección IP completa
- Tipo de IP (Cliente / Administración)
- Botón de copiar al portapapeles
4. **Estadísticas**: Muestra contadores de IPs disponibles y en uso
### Ejemplo de Uso
```
1. Ingresa "5" en el campo de búsqueda
2. Haz clic en "Buscar IPs"
3. Se mostrarán todas las IPs disponibles en el rango 172.16.5.x
4. Haz clic en el botón "Copiar" junto a la IP deseada
5. La IP se copia automáticamente al portapapeles
```
---
## 🔌 API REST
El plugin expone una API REST completa para integraciones externas, webhooks y automatizaciones.
### Configuración Base
- **URL Base**: `https://tu-servidor/plugins/siip-available-ips/public.php`
- **Método**: `POST`
- **Content-Type**: `application/json`
- **Autenticación**: No requerida (el plugin usa los tokens configurados internamente)
### Endpoints Disponibles
#### 1. Buscar IPs Disponibles
Busca todas las IPs disponibles en un segmento de red específico.
**Evento**: `event.ip_request`
**Request**:
```json
{
"type": "event.ip_request",
"segment": "5"
}
```
**Response (Éxito)**:
```json
{
"success": true,
"event": "event.ip_request",
"segment": "172.16.5.x",
"data": {
"available": [
"172.16.5.31",
"172.16.5.32",
"172.16.5.33"
],
"used": [
"172.16.5.1",
"172.16.5.2"
]
},
"count": {
"available": 223,
"used": 31,
"admin_filtered": 31
},
"message": "Se encontraron 223 IPs aptas para clientes en el segmento 172.16.5.x (31 IPs administrativas filtradas)"
}
```
**Parámetros**:
- `type` (string, requerido): Tipo de evento, debe ser `"event.ip_request"`
- `segment` (string, requerido): Tercer octeto del segmento (0-255)
**Notas**:
- Las IPs administrativas (1-30 y 254) son filtradas automáticamente
- Solo se devuelven IPs aptas para asignar a clientes (31-253)
---
#### 2. Verificar Estado de una IP
Verifica si una IP específica está disponible o en uso.
**Evento**: `event.ip_check`
**Request**:
```json
{
"type": "event.ip_check",
"ip": "172.16.5.100"
}
```
**Response (IP Disponible)**:
```json
{
"success": true,
"event": "event.ip_check",
"ip": "172.16.5.100",
"status": "available",
"available": true,
"used": false,
"ip_type": {
"type": "client",
"label": "Apta para cliente",
"recommended": true,
"description": "Recomendada para asignar a clientes"
}
}
```
**Response (IP en Uso)**:
```json
{
"success": true,
"event": "event.ip_check",
"ip": "172.16.5.1",
"status": "IP en uso y además para uso administrativo",
"available": false,
"used": true,
"ip_type": {
"type": "admin",
"label": "Administración",
"recommended": false,
"description": "No recomendada para clientes"
}
}
```
**Parámetros**:
- `type` (string, requerido): Tipo de evento, debe ser `"event.ip_check"`
- `ip` (string, requerido): Dirección IP completa en formato `172.16.X.X`
---
### Ejemplos de Uso
#### cURL - Buscar IPs Disponibles
```bash
curl -X POST https://tu-servidor/plugins/siip-available-ips/public.php \
-H "Content-Type: application/json" \
-d '{
"type": "event.ip_request",
"segment": "5"
}'
```
#### cURL - Verificar IP Específica
```bash
curl -X POST https://tu-servidor/plugins/siip-available-ips/public.php \
-H "Content-Type: application/json" \
-d '{
"type": "event.ip_check",
"ip": "172.16.5.100"
}'
```
#### PHP - Buscar IPs Disponibles
```php
<?php
$url = 'https://tu-servidor/plugins/siip-available-ips/public.php';
$data = [
'type' => 'event.ip_request',
'segment' => '5'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result);
?>
```
#### JavaScript/Node.js - Verificar IP
```javascript
const axios = require('axios');
const checkIp = async (ip) => {
try {
const response = await axios.post(
'https://tu-servidor/plugins/siip-available-ips/public.php',
{
type: 'event.ip_check',
ip: ip
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
};
checkIp('172.16.5.100');
```
#### Python - Buscar IPs Disponibles
```python
import requests
import json
url = 'https://tu-servidor/plugins/siip-available-ips/public.php'
payload = {
'type': 'event.ip_request',
'segment': '5'
}
response = requests.post(
url,
json=payload,
headers={'Content-Type': 'application/json'},
verify=False
)
result = response.json()
print(json.dumps(result, indent=2))
```
---
### Códigos de Error
| Código | Descripción | Solución |
|--------|-------------|----------|
| `Missing event type` | No se especificó el campo `type` | Incluye `"type"` en el JSON |
| `Unknown event type` | Tipo de evento no soportado | Usa `event.ip_request` o `event.ip_check` |
| `Missing segment` | Falta el campo `segment` | Incluye `"segment"` en el request |
| `Missing IP address` | Falta el campo `ip` | Incluye `"ip"` en el request |
| `Invalid IP format` | Formato de IP inválido | Usa formato `172.16.X.X` |
| `Plugin not configured` | Configuración incompleta | Verifica tokens en configuración del plugin |
| `IP search failed` | Error en búsqueda | Revisa logs del plugin |
---
## 📁 Estructura del Proyecto
```
siip-available-ips/
├── manifest.json # Configuración del plugin
├── composer.json # Dependencias PHP
├── main.php # Punto de entrada principal
├── public.php # Frontend web + API REST
├── README.md # Este archivo
├── src/ # Código fuente
│ ├── ApiHandlers.php # Manejadores de API REST
│ └── IpSearchService.php # Servicio de búsqueda de IPs
├── data/ # Datos del plugin
│ ├── config.json # Configuración (generado automáticamente)
│ └── plugin.log # Archivo de logs
└── vendor/ # Dependencias de Composer
```
### Archivos Principales
#### `public.php`
- Punto de entrada para frontend web y API REST
- Detecta automáticamente el tipo de petición (HTML vs JSON)
- Maneja errores globales y logging
#### `src/ApiHandlers.php`
Funciones para manejar peticiones API:
- `handleApiRequest()`: Router principal de eventos
- `handleIpRequest()`: Procesa `event.ip_request`
- `handleIpCheck()`: Procesa `event.ip_check`
#### `src/IpSearchService.php`
Clase de servicio para búsqueda de IPs:
- `buscarIpsDisponibles()`: Busca IPs en un segmento
- `obtenerIpsEnUso()`: Obtiene IPs desde API UNMS
- `isAdminIp()`: Determina si una IP es administrativa
- `getIpType()`: Obtiene información del tipo de IP
---
## 🎯 Filtrado de IPs Administrativas
El plugin implementa un sistema inteligente de filtrado de IPs:
### Rangos de IPs
| Rango | Tipo | Uso | Recomendación |
|-------|------|-----|---------------|
| `.1 - .30` | Administrativa | Gateways, servidores, equipos de red | ❌ No asignar a clientes |
| `.31 - .253` | Cliente | Dispositivos de clientes finales | ✅ Apto para clientes |
| `.254` | Broadcast | Dirección de broadcast | ❌ No asignar |
### Comportamiento
- **Frontend Web**: Muestra todas las IPs con etiquetas de tipo
- **API REST**: Filtra automáticamente IPs administrativas
- **event.ip_check**: Indica el tipo de IP en la respuesta
---
## 📝 Logs y Debugging
### Ubicación de Logs
Los logs se guardan en:
```
/data/plugin.log
```
### Habilitar Debug Mode
1. Ve a la configuración del plugin
2. Activa **"Debug Mode"**
3. Activa **"Enable debug logs"**
4. Los logs incluirán información detallada de:
- Peticiones recibidas
- Respuestas de API UNMS
- Errores y excepciones
- Tiempos de ejecución
### Ejemplo de Log
```
[2025-11-26 11:30:15] >>> Petición recibida en public.php
[2025-11-26 11:30:15] Método: POST
[2025-11-26 11:30:15] Content-Type: application/json
[2025-11-26 11:30:15] Procesando evento API: event.ip_request
[2025-11-26 11:30:15] API: Buscando IPs en segmento 5
[2025-11-26 11:30:16] Respuesta HTTP: 200
[2025-11-26 11:30:16] IPs obtenidas exitosamente: 254 direcciones
[2025-11-26 11:30:16] Búsqueda de IPs en segmento 172.16.5.x - Disponibles: 223, En uso: 31
```
---
## 📜 Changelog
Para ver el historial completo de cambios y versiones, consulta el archivo **[CHANGELOG.md](CHANGELOG.md)**.
### Versión Actual: 1.1.0 (2025-11-26)
**Cambios destacados**:
- ✨ API REST completa con endpoints `event.ip_request` y `event.ip_check`
- 🔌 Soporte para webhooks y eventos personalizados
- 🎯 Filtrado automático de IPs administrativas
- 📚 Documentación completa con ejemplos en múltiples lenguajes
[Ver changelog completo →](CHANGELOG.md)
---
## 🆘 Soporte
### Problemas Comunes
#### Error: "Plugin not configured"
**Solución**: Verifica que hayas configurado correctamente los tokens de API en la configuración del plugin.
#### Error: "Error al conectar con la API de UISP"
**Solución**:
- Verifica que el servidor UNMS esté accesible
- Comprueba que el token de API UNMS sea válido
- Revisa los logs para más detalles
#### No se muestran IPs disponibles
**Solución**:
- Verifica que el segmento ingresado sea válido (0-255)
- Comprueba que existan dispositivos en ese segmento en UNMS
- Revisa los logs con debug mode activado
### Contacto
- **Sitio web**: [https://siip.mx](https://siip.mx)
- **Autor**: SIIP Internet
---
## 📄 Licencia
Este plugin es propiedad de **SIIP Internet**. Todos los derechos reservados.
---
## 🙏 Agradecimientos
- Equipo de UISP/Ubiquiti por la plataforma
- Comunidad de desarrolladores de plugins UCRM
---
**Versión**: 1.1.0
**Última actualización**: 26 de noviembre de 2025

View File

@ -39,3 +39,247 @@ IPs obtenidas exitosamente: 3098 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type:
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"13"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary6cbbdcac9240b1f8937236c9d112a787
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 13
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48793 bytes
IPs obtenidas exitosamente: 3098 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"117"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary7b1ac14e8b058e23f4947656491d5038
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 117
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48793 bytes
IPs obtenidas exitosamente: 3098 direcciones
Búsqueda de IPs en segmento 172.16.117.x - Disponibles: 50, En uso: 204
Resultado de búsqueda: {"success":true,"ipsDisponibles":50,"ipsEnUso":204}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"118"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary658a77374dd484eccecd0aff8be2683c
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 118
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48793 bytes
IPs obtenidas exitosamente: 3098 direcciones
Búsqueda de IPs en segmento 172.16.118.x - Disponibles: 254, En uso: 0
Resultado de búsqueda: {"success":true,"ipsDisponibles":254,"ipsEnUso":0}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"13"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundaryf0fe3eda5f3c2940ddc7bc14b7f17a72
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 13
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48760 bytes
IPs obtenidas exitosamente: 3096 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: []
GET data: []
Content-Type: application/json
User Agent: curl/7.53.1
>>> Petición API JSON detectada
Raw input length: 55 bytes
JSON parseado correctamente: {"type":"event.ip_request","segment":13}
Procesando evento API: event.ip_request
API: Buscando IPs en segmento 13
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48760 bytes
IPs obtenidas exitosamente: 3096 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type: application/json
User Agent: PostmanRuntime/7.49.1
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type:
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"13"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundarye5c616c1af6248b5a47402549548a751
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 13
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48760 bytes
IPs obtenidas exitosamente: 3096 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: []
GET data: []
Content-Type: application/json
User Agent: bruno-runtime/2.13.2
>>> Petición API JSON detectada
Raw input length: 49 bytes
JSON parseado correctamente: {"type":"event.ip_request","segment":13}
Procesando evento API: event.ip_request
API: Buscando IPs en segmento 13
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48760 bytes
IPs obtenidas exitosamente: 3096 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"54"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary760324c1fddb52943c44f65bcfecbf9d
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 54
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48760 bytes
IPs obtenidas exitosamente: 3096 direcciones
Búsqueda de IPs en segmento 172.16.54.x - Disponibles: 53, En uso: 201
Resultado de búsqueda: {"success":true,"ipsDisponibles":53,"ipsEnUso":201}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type:
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"13"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary6a3bb83aaad5136b35d1d031633c43ce
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 13
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48807 bytes
IPs obtenidas exitosamente: 3099 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
Resultado de búsqueda: {"success":true,"ipsDisponibles":152,"ipsEnUso":102}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: POST
POST data: []
GET data: []
Content-Type: application/json
User Agent: bruno-runtime/2.13.2
>>> Petición API JSON detectada
Raw input length: 49 bytes
JSON parseado correctamente: {"type":"event.ip_request","segment":13}
Procesando evento API: event.ip_request
API: Buscando IPs en segmento 13
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48807 bytes
IPs obtenidas exitosamente: 3099 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 152, En uso: 102
API: Filtrando IPs administrativas. Total disponibles: 152, Aptas para clientes: 135
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type:
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"12"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundary3c043be49dc41eaeecf09ef1c525672b
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 12
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48823 bytes
IPs obtenidas exitosamente: 3100 direcciones
Búsqueda de IPs en segmento 172.16.12.x - Disponibles: 134, En uso: 120
Resultado de búsqueda: {"success":true,"ipsDisponibles":134,"ipsEnUso":120}
<<< Finalizando handler de búsqueda AJAX
=== NUEVA PETICIÓN ===
Método: GET
POST data: []
GET data: []
Content-Type:
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
Acceso a la interfaz pública de búsqueda de IPs
=== NUEVA PETICIÓN ===
Método: POST
POST data: {"action":"search","segment":"13"}
GET data: []
Content-Type: multipart/form-data; boundary=----geckoformboundaryb636200e57bd870b75c2713be943cc3c
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0
>>> Entrando al handler de búsqueda AJAX
Configuración cargada: {"ipserver":"sistema.siip.mx","hasUnmsToken":true,"hasApiToken":true}
Buscando IPs en segmento: 13
URL de API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Iniciando conexión a API: https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true
Respuesta HTTP: 200
Longitud de respuesta: 48875 bytes
IPs obtenidas exitosamente: 3103 direcciones
Búsqueda de IPs en segmento 172.16.13.x - Disponibles: 153, En uso: 101
Resultado de búsqueda: {"success":true,"ipsDisponibles":153,"ipsEnUso":101}
<<< Finalizando handler de búsqueda AJAX

View File

@ -5,7 +5,7 @@
"displayName": "SIIP - Buscador de IP's Disponibles UISP",
"description": "Este plugin permite buscar IP's disponibles en UISP (UNMS) y asignarlas a los clientes en UCRM. Evitando así la asignación de IP's duplicadas y mejorando la gestión de direcciones IP en la red.",
"url": "https://siip.mx",
"version": "1.0.1",
"version": "1.1.0",
"ucrmVersionCompliancy": {
"min": "1.0.0",
"max": null

View File

@ -25,6 +25,7 @@ chdir(__DIR__);
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/src/IpSearchService.php';
require_once __DIR__ . '/src/ApiHandlers.php';
use Ubnt\UcrmPluginSdk\Service\PluginLogManager;
use Ubnt\UcrmPluginSdk\Service\PluginConfigManager;
@ -41,7 +42,41 @@ $log->appendLog('GET data: ' . json_encode($_GET));
$log->appendLog('Content-Type: ' . ($_SERVER['CONTENT_TYPE'] ?? 'no definido'));
$log->appendLog('User Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'no definido'));
// Manejar peticiones AJAX
// ============================================================================
// API REST - Manejar peticiones JSON (Postman, Webhooks, etc.)
// ============================================================================
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
$isJsonRequest = stripos($contentType, 'application/json') !== false;
if ($isJsonRequest && $_SERVER['REQUEST_METHOD'] === 'POST') {
$log->appendLog('>>> Petición API JSON detectada');
$rawInput = file_get_contents('php://input');
$log->appendLog('Raw input length: ' . strlen($rawInput) . ' bytes');
$jsonData = json_decode($rawInput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$log->appendLog('ERROR: JSON inválido - ' . json_last_error_msg());
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'error' => 'Invalid JSON',
'message' => json_last_error_msg()
]);
exit;
}
$log->appendLog('JSON parseado correctamente: ' . json_encode($jsonData));
// Procesar petición API
handleApiRequest($jsonData, $log);
exit;
}
// ============================================================================
// FRONTEND HTML - Manejar peticiones AJAX del formulario
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'search') {
$log->appendLog('>>> Entrando al handler de búsqueda AJAX');
@ -495,6 +530,27 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs');
color: #4facfe;
}
.ip-type-badge {
padding: 6px 12px;
border-radius: 6px;
font-size: 0.8rem;
font-weight: 600;
display: inline-block;
text-align: center;
}
.ip-type-admin {
background: rgba(245, 87, 108, 0.2);
border: 1px solid rgba(245, 87, 108, 0.4);
color: #ff6b6b;
}
.ip-type-client {
background: rgba(79, 209, 197, 0.2);
border: 1px solid rgba(79, 209, 197, 0.4);
color: #4fd1c5;
}
.footer {
text-align: center;
color: var(--text-secondary);
@ -596,6 +652,7 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs');
<tr>
<th>#</th>
<th>Dirección IP</th>
<th>Tipo de IP</th>
<th>Acción</th>
</tr>
</thead>
@ -704,10 +761,16 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs');
// Llenar tabla
data.data.forEach((ip, index) => {
const ipType = getIpType(ip);
const row = document.createElement('tr');
row.innerHTML = `
<td>${index + 1}</td>
<td><span class="ip-address">${ip}</span></td>
<td>
<span class="ip-type-badge ip-type-${ipType.type}">
${ipType.label}
</span>
</td>
<td>
<button class="btn-copy" onclick="copyToClipboard('${ip}', this)">
📋 Copiar
@ -724,6 +787,28 @@ $log->appendLog('Acceso a la interfaz pública de búsqueda de IPs');
showError(data.message, 'success');
}
// Función para clasificar el tipo de IP
function getIpType(ip) {
const parts = ip.split('.');
const lastOctet = parseInt(parts[3]);
// IPs administrativas: 1-30 y 254
if ((lastOctet >= 1 && lastOctet <= 30) || lastOctet === 254) {
return {
type: 'admin',
label: 'Administración',
recommended: false
};
}
// IPs aptas para clientes: 31-253
return {
type: 'client',
label: 'Apta para cliente',
recommended: true
};
}
function showError(message, type = 'error') {
const alertClass = type === 'success' ? 'alert-success' : 'alert-error';
const icon = type === 'success' ? '✓' : '⚠';

View File

@ -1,48 +0,0 @@
<?php
if ($argc != 2) {
echo "Uso: php obtener_ip_segmento_api.php <segmento>\n";
exit(1);
}
$segmento = $argv[1];
$api_url = "https://sistema.siip.mx/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true";
$token = "393eb3d0-9b46-4a47-b9b4-473e4e24a89c";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'accept: application/json',
"x-auth-token: $token"
]);
$result = curl_exec($ch);
if ($result === false) {
echo "Error llamando a la API\n";
exit(1);
}
curl_close($ch);
$ips_en_uso = json_decode($result, true);
$segmento_prefix = "172.16.$segmento.";
$segment_ips = [];
foreach ($ips_en_uso as $ip) {
if (strpos($ip, $segmento_prefix) === 0) {
$segment_ips[] = $ip;
}
}
usort($segment_ips, function($a, $b) {
return intval(explode('.', $a)[3]) - intval(explode('.', $b)[3]);
});
$todas = [];
for ($i=1; $i<=254; $i++) {
$todas[] = "172.16.$segmento.$i";
}
$libres = array_values(array_diff($todas, $segment_ips));
echo "IPs disponibles en el segmento 172.16.$segmento.x:\n";
foreach ($libres as $ip) {
echo "$ip\n";
}

216
src/ApiHandlers.php Normal file
View File

@ -0,0 +1,216 @@
<?php
/**
* Funciones de manejo de API REST para el plugin SIIP Available IPs
*/
/**
* Maneja las peticiones API REST basadas en eventos
*/
function handleApiRequest($data, $log) {
header('Content-Type: application/json');
try {
// Validar que exista el tipo de evento
if (empty($data['type'])) {
echo json_encode([
'success' => false,
'error' => 'Missing event type',
'message' => 'The "type" field is required'
]);
return;
}
$eventType = $data['type'];
$log->appendLog("Procesando evento API: $eventType");
// Manejar diferentes tipos de eventos
switch ($eventType) {
case 'event.ip_request':
handleIpRequest($data, $log);
break;
case 'event.ip_check':
handleIpCheck($data, $log);
break;
default:
echo json_encode([
'success' => false,
'error' => 'Unknown event type',
'message' => "Event type '$eventType' is not supported",
'supported_events' => [
'event.ip_request',
'event.ip_check'
]
]);
}
} catch (Exception $e) {
$log->appendLog('Error en API request: ' . $e->getMessage());
echo json_encode([
'success' => false,
'error' => 'Internal error',
'message' => $e->getMessage()
]);
}
}
/**
* Maneja el evento event.ip_request - Buscar IPs disponibles en un segmento
*/
function handleIpRequest($data, $log) {
// Validar segmento
if (!isset($data['segment'])) {
echo json_encode([
'success' => false,
'error' => 'Missing segment',
'message' => 'The "segment" field is required for event.ip_request'
]);
return;
}
$segment = $data['segment'];
$log->appendLog("API: Buscando IPs en segmento $segment");
// Cargar configuración
$configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
$config = $configManager->loadConfig();
if (empty($config['ipserver']) || empty($config['unmsApiToken'])) {
echo json_encode([
'success' => false,
'error' => 'Plugin not configured',
'message' => 'Plugin configuration is incomplete'
]);
return;
}
// Buscar IPs
$apiUrl = "https://{$config['ipserver']}/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true";
$apiToken = $config['unmsApiToken'];
$ipService = new \SiipAvailableIps\IpSearchService($apiUrl, $apiToken, $log);
$resultado = $ipService->buscarIpsDisponibles($segment);
// Formatear respuesta para API
if ($resultado['success']) {
// Filtrar IPs administrativas - Solo devolver IPs aptas para clientes (31-253)
$clientAvailableIps = array_filter($resultado['data'], function($ip) {
return !\SiipAvailableIps\IpSearchService::isAdminIp($ip);
});
$clientAvailableIps = array_values($clientAvailableIps); // Reindexar array
$log->appendLog("API: Filtrando IPs administrativas. Total disponibles: " . count($resultado['data']) . ", Aptas para clientes: " . count($clientAvailableIps));
echo json_encode([
'success' => true,
'event' => 'event.ip_request',
'segment' => $resultado['segment'],
'data' => [
'available' => $clientAvailableIps,
'used' => $resultado['used']
],
'count' => [
'available' => count($clientAvailableIps),
'used' => count($resultado['used']),
'admin_filtered' => count($resultado['data']) - count($clientAvailableIps)
],
'message' => sprintf(
'Se encontraron %d IPs aptas para clientes en el segmento %s (%d IPs administrativas filtradas)',
count($clientAvailableIps),
$resultado['segment'],
count($resultado['data']) - count($clientAvailableIps)
)
]);
} else {
echo json_encode([
'success' => false,
'error' => 'IP search failed',
'message' => $resultado['message']
]);
}
}
/**
* Maneja el evento event.ip_check - Verificar si una IP específica está disponible
*/
function handleIpCheck($data, $log) {
// Validar parámetros
if (!isset($data['ip'])) {
echo json_encode([
'success' => false,
'error' => 'Missing IP address',
'message' => 'The "ip" field is required for event.ip_check'
]);
return;
}
$ipToCheck = $data['ip'];
$log->appendLog("API: Verificando disponibilidad de IP $ipToCheck");
// Extraer segmento de la IP
$parts = explode('.', $ipToCheck);
if (count($parts) !== 4 || $parts[0] !== '172' || $parts[1] !== '16') {
echo json_encode([
'success' => false,
'error' => 'Invalid IP format',
'message' => 'IP must be in format 172.16.X.X'
]);
return;
}
$segment = $parts[2];
// Cargar configuración y buscar
$configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
$config = $configManager->loadConfig();
if (empty($config['ipserver']) || empty($config['unmsApiToken'])) {
echo json_encode([
'success' => false,
'error' => 'Plugin not configured',
'message' => 'Plugin configuration is incomplete'
]);
return;
}
$apiUrl = "https://{$config['ipserver']}/nms/api/v2.1/devices/ips?suspended=false&management=true&includeObsolete=true";
$apiToken = $config['unmsApiToken'];
$ipService = new \SiipAvailableIps\IpSearchService($apiUrl, $apiToken, $log);
$resultado = $ipService->buscarIpsDisponibles($segment);
if ($resultado['success']) {
$isAvailable = in_array($ipToCheck, $resultado['data']);
$isUsed = in_array($ipToCheck, $resultado['used']);
$ipType = \SiipAvailableIps\IpSearchService::getIpType($ipToCheck);
// Determinar status con información de tipo de IP
$status = 'unknown';
if ($isAvailable) {
$status = $ipType['type'] === 'admin'
? 'IP disponible pero para uso administrativo'
: 'available';
} elseif ($isUsed) {
$status = $ipType['type'] === 'admin'
? 'IP en uso y además para uso administrativo'
: 'used';
}
echo json_encode([
'success' => true,
'event' => 'event.ip_check',
'ip' => $ipToCheck,
'status' => $status,
'available' => $isAvailable,
'used' => $isUsed,
'ip_type' => $ipType
]);
} else {
echo json_encode([
'success' => false,
'error' => 'IP check failed',
'message' => $resultado['message']
]);
}
}

View File

@ -8,6 +8,13 @@ class IpSearchService
private $apiToken;
private $logger;
// Rangos de IPs administrativas (no recomendadas para clientes)
const ADMIN_IP_RANGES = [
'start' => 1,
'end' => 30,
'broadcast' => 254
];
public function __construct($apiUrl, $apiToken, $logger = null)
{
$this->apiUrl = $apiUrl;
@ -15,6 +22,50 @@ class IpSearchService
$this->logger = $logger;
}
/**
* Determina si una IP es administrativa (no recomendada para clientes)
*
* @param string $ip Dirección IP completa (ej: 172.16.13.5)
* @return bool True si es IP administrativa
*/
public static function isAdminIp($ip)
{
$parts = explode('.', $ip);
if (count($parts) !== 4) {
return false;
}
$lastOctet = (int)$parts[3];
return ($lastOctet >= self::ADMIN_IP_RANGES['start'] && $lastOctet <= self::ADMIN_IP_RANGES['end'])
|| $lastOctet === self::ADMIN_IP_RANGES['broadcast'];
}
/**
* Obtiene el tipo de IP (administrativa o cliente)
*
* @param string $ip Dirección IP completa
* @return array ['type' => 'admin'|'client', 'label' => string, 'recommended' => bool]
*/
public static function getIpType($ip)
{
if (self::isAdminIp($ip)) {
return [
'type' => 'admin',
'label' => 'Administración',
'recommended' => false,
'description' => 'No recomendada para clientes'
];
}
return [
'type' => 'client',
'label' => 'Apta para cliente',
'recommended' => true,
'description' => 'Recomendada para asignar a clientes'
];
}
/**
* Busca IPs disponibles en un segmento de red específico
*