---
name: identify_port_service
kind: function
lang: py
domain: cybersecurity
version: "1.0.0"
purity: pure
signature: "def identify_port_service(port: int, proto: str = 'tcp') -> dict"
description: "Mapea un número de puerto (TCP/UDP) a su servicio IANA well-known más una descripción corta, usando una tabla estática embebida (~120 puertos comunes en pentest/OSINT). Función pura, sin red ni I/O: dado un puerto abierto detectado por un scanner, dice qué servicio se ESPERA típicamente ahí por convención (ssh en 22, https en 443, mysql en 3306, postgresql en 5432, rdp en 3389, redis en 6379, mongodb en 27017, etc.), no lo verifica en vivo. Complementa a scan_tcp_ports/scan_port_tcp y grab_service_banner para enriquecer informes de reconocimiento de red."
tags: [recon, cybersecurity, port-service, port, service, iana, well-known, ports, network, osint]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: true
tests: ["test_port_22_es_ssh", "test_port_443_es_https", "test_port_3306_es_mysql", "test_port_53_udp_es_dns", "test_puerto_fuera_de_rango_es_invalid", "test_puerto_desconocido_known_false", "test_proto_invalido_es_invalid", "test_proto_se_normaliza_mayusculas", "test_determinismo_misma_entrada_misma_salida"]
test_file_path: "python/functions/cybersecurity/identify_port_service_test.py"
file_path: "python/functions/cybersecurity/identify_port_service.py"
params:
  - name: port
    desc: "Número de puerto a identificar, rango válido 0-65535. Fuera de rango devuelve service 'invalid'."
  - name: proto
    desc: "Protocolo de transporte: 'tcp' o 'udp' (default 'tcp'). Se normaliza a minúsculas; cualquier otro valor devuelve service 'invalid'."
output: "dict con {port: int, proto: str, service: str, description: str, known: bool}. service='ssh'/'https'/... y known=True si hay match en la tabla; service='unknown', description='', known=False si el puerto/proto es válido pero no está catalogado; service='invalid' si el puerto está fuera de rango 0-65535 o el protocolo no es tcp/udp."
---

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from cybersecurity.identify_port_service import identify_port_service

identify_port_service(22)
# -> {"port": 22, "proto": "tcp", "service": "ssh",
#     "description": "Secure Shell", "known": True}

identify_port_service(53, "udp")
# -> {"port": 53, "proto": "udp", "service": "dns",
#     "description": "Domain Name System", "known": True}

identify_port_service(99999)
# -> {"port": 99999, "proto": "tcp", "service": "invalid",
#     "description": "", "known": False}
```

Invocación directa via `fn run`:

```bash
./fn run identify_port_service_py_cybersecurity
# imprime el JSON de varios puertos de muestra (22, 443, 53/udp, 3306, 99999)
```

## Cuando usarla

Cuando tienes un puerto abierto (por ejemplo de `scan_tcp_ports` / `scan_port_tcp_go_cybersecurity` o de un parseo de salida de `nmap_scan`) y quieres el servicio esperado por convención IANA **sin sondear en vivo** — para etiquetar resultados, generar resúmenes legibles o enriquecer informes de reconocimiento (recon/OSINT) de forma determinista y offline.

## Gotchas

- Devuelve el servicio **convencional** según IANA/nmap-services, **no verifica** que sea el que realmente corre en ese puerto. Un servicio puede escuchar en un puerto no estándar (p. ej. SSH en 2222, o un panel admin en 8443). Para confirmar el servicio real, sondea con `grab_service_banner` / `scan_port_tcp_go_cybersecurity` (que devuelve banner) o `nmap_scan` con detección de versión.
- La tabla cubre los puertos más comunes en pentest/OSINT, no es exhaustiva (no incluye todos los registros IANA). Un puerto válido pero no catalogado devuelve `service: "unknown"`, `known: False` — no es un error.
- `service: "invalid"` (puerto fuera de 0-65535 o proto distinto de tcp/udp) se distingue de `service: "unknown"` (puerto/proto válidos pero no en la tabla). Ambos tienen `known: False`.
