37 lines
1.8 KiB
TypeScript
37 lines
1.8 KiB
TypeScript
import type { RosIpRoute } from "../types/server.js"
|
|
|
|
export type OspfRouteKind = "O" | "O IA" | "O E1" | "O E2"
|
|
|
|
/** RouterOS /ip/route → тип OSPF-маршрута UI, либо null если маршрут не OSPF. */
|
|
export function parseOspfRouteType(r: RosIpRoute): OspfRouteKind | null {
|
|
const ospfFlag = r.ospf === "true" || r.ospf === "yes"
|
|
const raw = `${r["ospf-type"] ?? ""} ${r.type ?? ""}`.toLowerCase()
|
|
const looksOspf = ospfFlag || raw.includes("ospf") || Boolean(r["ospf-type"])
|
|
if (!looksOspf) return null
|
|
if (raw.includes("inter")) return "O IA"
|
|
if (raw.includes("e1") || raw.includes("type-1") || raw.includes("ext-1") || raw.includes("nssa-ext-type-1")) {
|
|
return "O E1"
|
|
}
|
|
if (raw.includes("e2") || raw.includes("type-2") || raw.includes("ext-2") || raw.includes("nssa-ext-type-2")) {
|
|
return "O E2"
|
|
}
|
|
return "O"
|
|
}
|
|
|
|
export function parseOspfGateway(r: RosIpRoute): { nextHop: string; via: string } {
|
|
const gw = (r.gateway ?? r["immediate-gw"] ?? "").trim()
|
|
const [ip, iface = ""] = gw.split("%")
|
|
return {
|
|
nextHop: ip || gw || "—",
|
|
via: iface || (r.interface ?? "—"),
|
|
}
|
|
}
|
|
|
|
/** Only an explicit known subtype proves the intra/inter/external class. */
|
|
export function parseOspfCatalogRouteType(route: RosIpRoute): OspfRouteKind | "Unknown" | null {
|
|
if (parseOspfRouteType(route) === null) return null
|
|
const kinds: Record<string, OspfRouteKind> = { "intra-area": "O", internal: "O", "inter-area": "O IA", "ext-type-1": "O E1", "external-type-1": "O E1", "type-1": "O E1", "ext-1": "O E1", e1: "O E1", "nssa-ext-type-1": "O E1", "ext-type-2": "O E2", "external-type-2": "O E2", "type-2": "O E2", "ext-2": "O E2", e2: "O E2", "nssa-ext-type-2": "O E2" }
|
|
const raw = (route["ospf-type"] ?? route.type ?? "").trim().toLowerCase().replace(/^ospf[- ]/, "")
|
|
return kinds[raw] ?? "Unknown"
|
|
}
|