#!/usr/bin/env python3 """Read-only extra dump: wireless, dns, pools, walled-garden.""" import socket HOST = "192.168.88.1" PORT = 8728 USER = "admin" PASSWORD = "" def encode_len(n: int) -> bytes: if n < 0x80: return bytes([n]) if n < 0x4000: n |= 0x8000 return bytes([(n >> 8) & 0xFF, n & 0xFF]) raise RuntimeError("len") def write_sentence(sock, words): for word in words: b = word.encode() sock.sendall(encode_len(len(b)) + b) sock.sendall(b"\x00") def read_len(sock): c = sock.recv(1) if not c: raise ConnectionError("closed") n = c[0] if n & 0x80 == 0: return n if n & 0xC0 == 0x80: n &= ~0xC0 b = sock.recv(1) return (n << 8) + b[0] raise RuntimeError("len") def read_sentence(sock): words = [] while True: n = read_len(sock) if n == 0: break data = b"" while len(data) < n: chunk = sock.recv(n - len(data)) if not chunk: raise ConnectionError("closed") data += chunk words.append(data.decode("utf-8", "replace")) return words def talk(sock, words): write_sentence(sock, words) out = [] while True: s = read_sentence(sock) if not s: break out.append(s) if s[0] in ("!done", "!trap", "!fatal"): break return out def login(sock): r = talk(sock, ["/login", f"=name={USER}", f"=password={PASSWORD}"]) chal = None for s in r: for w in s: if w.startswith("=ret="): chal = w[5:] if chal: import hashlib, binascii h = hashlib.md5() h.update(b"\x00" + PASSWORD.encode() + binascii.unhexlify(chal)) r = talk(sock, ["/login", f"=name={USER}", "=response=00" + h.hexdigest()]) if not any(s and s[0] == "!done" for s in r): raise RuntimeError(r) def main(): sock = socket.create_connection((HOST, PORT), 8) login(sock) for cmd in [ ["/interface/wireless/print"], ["/interface/wireless/security-profiles/print"], ["/ip/dns/print"], ["/ip/pool/print"], ["/ip/dhcp-server/network/print"], ["/ip/hotspot/user/profile/print"], ["/ip/firewall/filter/print"], ["/system/identity/print"], ]: print("\n====", cmd[0], "====") for s in talk(sock, cmd): print(" ".join(s)) sock.close() if __name__ == "__main__": main()