(host: string)
| 65 | } |
| 66 | |
| 67 | function extractIPv4MappedHost(host: string): string | null { |
| 68 | const stripped = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host |
| 69 | const lower = stripped.toLowerCase() |
| 70 | for (const prefix of ['::ffff:', '::']) { |
| 71 | if (lower.startsWith(prefix)) { |
| 72 | const candidate = lower.slice(prefix.length) |
| 73 | if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(candidate)) return candidate |
| 74 | } |
| 75 | } |
| 76 | const hexMatch = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/) |
| 77 | if (hexMatch) { |
| 78 | const high = Number.parseInt(hexMatch[1] as string, 16) |
| 79 | const low = Number.parseInt(hexMatch[2] as string, 16) |
| 80 | if (high >= 0 && high <= 0xffff && low >= 0 && low <= 0xffff) { |
| 81 | const a = (high >> 8) & 0xff |
| 82 | const b = high & 0xff |
| 83 | const c = (low >> 8) & 0xff |
| 84 | const d = low & 0xff |
| 85 | return `${a}.${b}.${c}.${d}` |
| 86 | } |
| 87 | } |
| 88 | return null |
| 89 | } |
| 90 | |
| 91 | function isPrivateOrLoopbackIPv6(host: string): boolean { |
| 92 | const stripped = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host |
no test coverage detected