const { ARIN_CC, APNIC_CC, LACNIC_CC, AFRINIC_CC } = require("../../data/rir-country-codes"); // Derive RIR and country through a cascade of fallback sources: RIPE Stat // rir-stats-country, RDAP port43, RDAP self-link, bgp.he.net country_code, // then a country-code-to-RIR table as a last resort. function deriveRirAndCountry(rirEntries, rirData, rdapData, bgpHeData) { let rir = ""; let country = ""; // RIPE Stat rir-stats-country uses 'location' field (not 'country' or 'rir') if (Array.isArray(rirEntries) && rirEntries.length > 0) { country = rirEntries[0]?.location || rirEntries[0]?.country || ""; rir = rirEntries[0]?.rir || ""; } if (!rir && rirData?.data) { const rirField = rirData.data.rirs || []; if (rirField.length > 0) rir = rirField[0]?.rir || ""; } // Derive RIR from rdapData.port43 (e.g. "whois.ripe.net" → "RIPE") if (!rir && rdapData && rdapData.port43) { const p43 = (rdapData.port43 || "").toLowerCase(); if (p43.includes("ripe")) rir = "RIPE"; else if (p43.includes("arin")) rir = "ARIN"; else if (p43.includes("apnic")) rir = "APNIC"; else if (p43.includes("lacnic")) rir = "LACNIC"; else if (p43.includes("afrinic")) rir = "AFRINIC"; } // Also derive RIR from RDAP links (URL of the RDAP endpoint that responded) if (!rir && rdapData && rdapData.links) { const selfLink = (rdapData.links.find(l => l.rel === "self") || {}).href || ""; if (selfLink.includes("ripe")) rir = "RIPE"; else if (selfLink.includes("arin")) rir = "ARIN"; else if (selfLink.includes("apnic")) rir = "APNIC"; else if (selfLink.includes("lacnic")) rir = "LACNIC"; else if (selfLink.includes("afrinic")) rir = "AFRINIC"; } // bgp.he.net country_code fallback (for unannounced/reserve ASNs) if (!country && bgpHeData && bgpHeData.country_code) { country = bgpHeData.country_code; } // Last resort: derive RIR from country code (common assignments) if (!rir && country) { if (ARIN_CC.has(country)) rir = "ARIN"; else if (APNIC_CC.has(country)) rir = "APNIC"; else if (LACNIC_CC.has(country)) rir = "LACNIC"; else if (AFRINIC_CC.has(country)) rir = "AFRINIC"; else rir = "RIPE"; // Europe + rest = RIPE NCC } return { rir, country }; } module.exports = { deriveRirAndCountry };