#!/usr/bin/env python3 import ssl import sys import json import argparse from datetime import datetime try: from librouteros import connect from librouteros.query import Key except ImportError: print("Error: librouteros module not found") print("Install with: pip install librouteros") sys.exit(1) def get_router_basic_data(host, username='grahamro', password='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', port=8729): """ Get basic router configuration data (simplified for older RouterOS) Args: host: IP address or hostname of the router username: Router username password: Router password port: API-SSL port (default: 8729) Returns: Dictionary containing basic router configuration """ print(f"=== Connecting to MikroTik Router ({host}) ===\n") # SSL context for secure connection ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE try: # Connect to router api = connect( username=username, password=password, host=host, port=port, ssl_wrapper=ctx.wrap_socket ) print("āœ“ Connected successfully\n") # Get unique subnets only (skip individual CGNAT IPs) print("=== IP Addresses (Unique Subnets) ===") ip_addresses = api('/ip/address/print') # Group by network to handle CGNAT blocks networks_seen = {} subnets = [] for addr in ip_addresses: if not addr.get('disabled', False): address = addr['address'] interface = addr.get('interface', 'unknown') network = addr.get('network', '') # For CGNAT interface, only keep one representative if interface == 'cgnat': if network not in networks_seen: networks_seen[network] = True print(f"CGNAT Network: {network}/25 (multiple IPs)") subnets.append({ 'address': f"{network}/25", 'network': network, 'interface': interface, 'comment': 'CGNAT pool' }) else: # Regular interfaces print(f"Interface: {interface}") print(f" Address: {address}") print(f" Network: {network}") print() subnets.append({ 'address': address, 'network': network, 'interface': interface, 'comment': '' }) # Get key interfaces only print("\n=== Key Interfaces ===") interfaces = api('/interface/print') active_interfaces = [] # Focus on non-dynamic interfaces for iface in interfaces: if not iface.get('disabled', False) and iface.get('running', False): name = iface['name'] itype = iface.get('type', 'unknown') # Skip PPPoE client interfaces if not name.startswith('<'): active_interfaces.append({ 'name': name, 'type': itype }) print(f"{name} ({itype})") # Close connection api.close() # Compile basic data router_data = { 'host': host, 'timestamp': datetime.now().isoformat(), 'subnets': subnets, 'interfaces': active_interfaces } print(f"\n=== Summary ===") print(f"Found {len(subnets)} unique subnets") print(f"Found {len(active_interfaces)} active interfaces") return router_data except Exception as e: print(f"āœ— Connection failed: {e}") return None def main(): parser = argparse.ArgumentParser(description='Retrieve basic configuration from a MikroTik router') parser.add_argument('host', help='IP address or hostname of the router') parser.add_argument('--username', '-u', default='grahamro', help='Router username') parser.add_argument('--password', '-p', default='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', help='Router password') parser.add_argument('--port', type=int, default=8729, help='API-SSL port (default: 8729)') parser.add_argument('--output', '-o', help='Output filename') args = parser.parse_args() # Get router data data = get_router_basic_data(args.host, args.username, args.password, args.port) if data: if args.output: with open(args.output, 'w') as f: json.dump(data, f, indent=2) print(f"\nData saved to: {args.output}") else: print("\n=== JSON Output ===") print(json.dumps(data, indent=2)) print("\nāœ“ Router data retrieved successfully") return 0 else: print("\nāœ— Failed to retrieve router data") return 1 if __name__ == "__main__": sys.exit(main())