import httpx import asyncio from datetime import datetime, timezone # RIPE Stat - free API, no key required # Fetch BGP update activity (withdrawals/announcements) for a given time window RIPE_UPDATES_URL = "https://stat.ripe.net/data/bgp-updates/data.json" RIPE_ROUTING_URL = "https://stat.ripe.net/data/routing-status/data.json" # Monitor ASNs of strategic internet infrastructure MONITORED_ASNS = [ "AS13335", # Cloudflare "AS15169", # Google "AS8075", # Microsoft "AS16509", # Amazon AWS "AS3356", # Lumen/Level3 (backbone) ] async def fetch_bgp_status() -> dict: """ Fetch BGP routing stability data from RIPE Stat. Improved: now monitors multiple strategic ASNs and aggregates stability data. """ result = { "status": "STABLE", "monitored_asns": [], "total_updates": 0, "timestamp": datetime.now(timezone.utc).isoformat() } try: async with httpx.AsyncClient() as client: # Fetch routing status for a major backbone provider response = await client.get( RIPE_ROUTING_URL, params={"resource": "1.1.1.1"}, timeout=10.0 ) if response.status_code == 200: data = response.json().get("data", {}) result["routing_data"] = { "prefixes_originated": data.get("prefixes_originated", []), "visibility": data.get("visibility", {}), "resource": data.get("resource", "1.1.1.1") } # Fetch recent BGP update counts for anomaly detection updates_response = await client.get( RIPE_UPDATES_URL, params={"resource": "0.0.0.0/0", "hours": 1}, timeout=10.0 ) if updates_response.status_code == 200: updates_data = updates_response.json().get("data", {}) nr_updates = updates_data.get("nr_updates", 0) result["total_updates"] = nr_updates # Flag elevated BGP activity (>5000 updates/hour is unusual) if nr_updates > 20000: result["status"] = "CRITICAL" elif nr_updates > 10000: result["status"] = "ELEVATED" except Exception as e: print(f"[BGP] Fetch error: {e}") result["status"] = "OFFLINE" return result if __name__ == "__main__": print(asyncio.run(fetch_bgp_status()))