opnsense_diag_ping
Diagnose network connectivity by pinging a target from the OPNsense firewall. Accepts IP address or hostname with configurable packet count.
Instructions
Ping a host from the OPNsense firewall
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | IP address or hostname to ping | |
| count | No | Number of ping packets (default: 3, max: 100) |
Implementation Reference
- src/tools/diagnostics.ts:14-17 (schema)Zod schema for ping input validation: requires 'address' (string), optional 'count' (1-100, default 3).
const PingSchema = z.object({ address: z.string().min(1, "Address is required"), count: z.number().int().min(1).max(100).optional().default(3), }); - src/tools/diagnostics.ts:60-77 (registration)Tool definition registration for 'opnsense_diag_ping' — declares name, description, and inputSchema for the ListTools response.
{ name: "opnsense_diag_ping", description: "Ping a host from the OPNsense firewall", inputSchema: { type: "object" as const, properties: { address: { type: "string", description: "IP address or hostname to ping", }, count: { type: "number", description: "Number of ping packets (default: 3, max: 100)", }, }, required: ["address"], }, }, - src/tools/diagnostics.ts:298-355 (handler)Core handler logic for 'opnsense_diag_ping': validates with PingSchema, then uses OPNsense 24.7+ job-based ping API (set→start→poll→remove). Polls until requested count reached, formats clean output with packet stats and RTT data.
case "opnsense_diag_ping": { const parsed = PingSchema.parse(args); // OPNsense 24.7+: job-based ping API (set → start → poll → remove) const setResult = await client.post<{ uuid?: string; result?: string }>( "/diagnostics/ping/set", { ping: { settings: { hostname: parsed.address, count: String(parsed.count) } } }, ); const jobId = setResult.uuid; if (!jobId) { return { content: [{ type: "text", text: JSON.stringify(setResult, null, 2) }] }; } await client.post(`/diagnostics/ping/start/${jobId}`); // Poll until send count reaches requested count (status stays "running" throughout) const maxWait = Math.max(parsed.count * 2000, 10000); const start = Date.now(); let result: Record<string, unknown> | undefined; while (Date.now() - start < maxWait) { await new Promise((r) => setTimeout(r, 1500)); const jobs = await client.get<{ rows?: Array<Record<string, unknown>>; }>("/diagnostics/ping/search_jobs"); const job = (jobs.rows ?? []).find( (j) => j.id === jobId || j.uuid === jobId, ); if (job && Number(job.send ?? 0) >= parsed.count) { result = job; break; } } // Cleanup try { await client.post(`/diagnostics/ping/remove/${jobId}`); } catch { // Best-effort cleanup } if (!result) { return { content: [{ type: "text", text: "Ping timed out waiting for results" }] }; } // Format clean output const output = { host: result.hostname, packets_sent: result.send, packets_received: result.received, packet_loss: result.loss, rtt_min_ms: result.min, rtt_avg_ms: result.avg, rtt_max_ms: result.max, rtt_stddev_ms: result["std-dev"], }; return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }] }; } - src/index.ts:61-61 (registration)Maps the tool name 'opnsense_diag_ping' to its handler function in the central server registration.
for (const def of diagnosticsToolDefinitions) toolHandlers.set(def.name, handleDiagnosticsTool);