From 7f548110ffc4e3e8a7881270963e4f1deb20b630 Mon Sep 17 00:00:00 2001 From: Olaf Baumert Date: Tue, 3 Jun 2025 11:04:25 +0000 Subject: [PATCH] feat: Add automatic decimal AS number conversion for SCION AS entries - Implement scion_as_to_decimal() function in both add-as and add-as-batch scripts - Automatically converts SCION AS format (ISD:AS:Instance) to decimal when in BGP range - Handles both ISD:AS:Instance format and colon-separated hex format - Follows SCION AS numbering specification from https://github.com/scionproto/scion/wiki/ISD-and-AS-numbering --- add-as | 43 +++++++++++++++++++++++-------------------- add-as-batch | 43 +++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/add-as b/add-as index e00975c..6f9c296 100755 --- a/add-as +++ b/add-as @@ -12,34 +12,37 @@ def scion_as_to_decimal(as_id): if ':' not in as_id: return as_id - # Parse SCION format (ISD:AS:Instance or AS parts in hex) + # Parse SCION format parts = as_id.split(':') - # For ISD:AS:Instance format, extract the AS part - if len(parts) == 3: - # ISD:AS:Instance format - AS is the middle part + # Check if this looks like ISD:AS:Instance format (first part is single digit ISD) + if len(parts) == 3 and len(parts[0]) == 1 and parts[0].isdigit(): + # ISD:AS:Instance format - convert the AS part (middle) and instance (last) try: - # Convert hex AS to decimal + # AS is 16-bit hex, instance is 16-bit hex + # Combine them as 32-bit number: AS << 16 | Instance as_num = int(parts[1], 16) - if 0 <= as_num <= 0xFFFFFFFF: # BGP AS range - return str(as_num) + instance = int(parts[2], 16) + total = (as_num << 16) | instance + + if 0 <= total <= 0xFFFFFFFF: # BGP AS range + return str(total) except ValueError: pass return "" - # For colon-separated hex format (e.g., 0:1:f) - if len(parts) <= 3: - try: - # Convert each hex part and combine - total = 0 - for i, part in enumerate(parts): - total = total * 65536 + int(part, 16) - - # Check if in BGP AS range - if 0 <= total <= 0xFFFFFFFF: # 2^32 - 1 - return str(total) - except ValueError: - pass + # For standard colon-separated hex format (e.g., 0:1:f) + # Each part is up to 16 bits + try: + total = 0 + for part in parts: + total = (total << 16) + int(part, 16) + + # Check if in BGP AS range + if 0 <= total <= 0xFFFFFFFF: # 2^32 - 1 + return str(total) + except ValueError: + pass return "" diff --git a/add-as-batch b/add-as-batch index 871d20c..0c56d58 100755 --- a/add-as-batch +++ b/add-as-batch @@ -17,34 +17,37 @@ def scion_as_to_decimal(as_id): if ':' not in as_id: return as_id - # Parse SCION format (ISD:AS:Instance or AS parts in hex) + # Parse SCION format parts = as_id.split(':') - # For ISD:AS:Instance format, extract the AS part - if len(parts) == 3: - # ISD:AS:Instance format - AS is the middle part + # Check if this looks like ISD:AS:Instance format (first part is single digit ISD) + if len(parts) == 3 and len(parts[0]) == 1 and parts[0].isdigit(): + # ISD:AS:Instance format - convert the AS part (middle) and instance (last) try: - # Convert hex AS to decimal + # AS is 16-bit hex, instance is 16-bit hex + # Combine them as 32-bit number: AS << 16 | Instance as_num = int(parts[1], 16) - if 0 <= as_num <= 0xFFFFFFFF: # BGP AS range - return str(as_num) + instance = int(parts[2], 16) + total = (as_num << 16) | instance + + if 0 <= total <= 0xFFFFFFFF: # BGP AS range + return str(total) except ValueError: pass return "" - # For colon-separated hex format (e.g., 0:1:f) - if len(parts) <= 3: - try: - # Convert each hex part and combine - total = 0 - for i, part in enumerate(parts): - total = total * 65536 + int(part, 16) - - # Check if in BGP AS range - if 0 <= total <= 0xFFFFFFFF: # 2^32 - 1 - return str(total) - except ValueError: - pass + # For standard colon-separated hex format (e.g., 0:1:f) + # Each part is up to 16 bits + try: + total = 0 + for part in parts: + total = (total << 16) + int(part, 16) + + # Check if in BGP AS range + if 0 <= total <= 0xFFFFFFFF: # 2^32 - 1 + return str(total) + except ValueError: + pass return ""