"""Telnet option constants exported from the deprecated telnetlib module.""" # std imports from typing import Dict # Exported from the telnetlib module, which is marked for deprecation in version # 3.11 and removal in 3.13 LINEMODE = b'"' NAWS = b"\x1f" NEW_ENVIRON = b"'" BINARY = b"\x00" SGA = b"\x03" ECHO = b"\x01" STATUS = b"\x05" TTYPE = b"\x18" TSPEED = b" " LFLOW = b"!" XDISPLOC = b"#" IAC = b"\xff" DONT = b"\xfe" DO = b"\xfd" WONT = b"\xfc" WILL = b"\xfb" SE = b"\xf0" NOP = b"\xf1" TM = b"\x06" DM = b"\xf2" BRK = b"\xf3" IP = b"\xf4" AO = b"\xf5" AYT = b"\xf6" EC = b"\xf7" EL = b"\xf8" EOR = b"\x19" GA = b"\xf9" SB = b"\xfa" LOGOUT = b"\x12" CHARSET = b"*" SNDLOC = b"\x17" theNULL = b"\x00" ENCRYPT = b"&" AUTHENTICATION = b"%" TN3270E = b"(" XAUTH = b")" RSP = b"+" COM_PORT_OPTION = b"," SUPPRESS_LOCAL_ECHO = b"-" TLS = b"." KERMIT = b"/" SEND_URL = b"0" FORWARD_X = b"1" PRAGMA_LOGON = b"\x8a" SSPI_LOGON = b"\x8b" PRAGMA_HEARTBEAT = b"\x8c" EXOPL = b"\xff" X3PAD = b"\x1e" VT3270REGIME = b"\x1d" TTYLOC = b"\x1c" SUPDUPOUTPUT = b"\x16" SUPDUP = b"\x15" DET = b"\x14" BM = b"\x13" XASCII = b"\x11" RCP = b"\x02" NAMS = b"\x04" RCTE = b"\x07" NAOL = b"\x08" NAOP = b"\t" NAOCRD = b"\n" NAOHTS = b"\x0b" NAOHTD = b"\x0c" NAOFFD = b"\r" NAOVTS = b"\x0e" NAOVTD = b"\x0f" NAOLFD = b"\x10" __all__ = ( "AARDWOLF", "ABORT", "ACCEPTED", "AO", "ATCP", "AUTHENTICATION", "AYT", "BINARY", "BM", "BRK", "CHARSET", "CMD_EOR", "COM_PORT_OPTION", "DET", "DM", "DO", "DONT", "EC", "ECHO", "EL", "ENCRYPT", "EOF", "EOR", "ESC", "EXOPL", "FORWARD_X", "GA", "GMCP", "IAC", "INFO", "IP", "IS", "KERMIT", "LFLOW", "LFLOW_OFF", "LFLOW_ON", "LFLOW_RESTART_ANY", "LFLOW_RESTART_XON", "LINEMODE", "LOGOUT", "MCCP2_COMPRESS", "MCCP3_COMPRESS", "MCCP_COMPRESS", "MSDP", "MSDP_ARRAY_CLOSE", "MSDP_ARRAY_OPEN", "MSDP_TABLE_CLOSE", "MSDP_TABLE_OPEN", "MSDP_VAL", "MSDP_VAR", "MSP", "MSSP", "MSSP_VAL", "MSSP_VAR", "MXP", "NAMS", "NAOCRD", "NAOFFD", "NAOHTD", "NAOHTS", "NAOL", "NAOLFD", "NAOP", "NAOVTD", "NAOVTS", "NAWS", "NEW_ENVIRON", "NOP", "PRAGMA_HEARTBEAT", "PRAGMA_LOGON", "RCP", "RCTE", "REJECTED", "REQUEST", "RSP", "SB", "SE", "SEND", "SEND_URL", "SGA", "SNDLOC", "SSPI_LOGON", "STATUS", "SUPDUP", "SUPDUPOUTPUT", "TELOPT_92", "SUPPRESS_LOCAL_ECHO", "SUSP", "TLS", "TM", "TN3270E", "TSPEED", "TTABLE_ACK", "TTABLE_IS", "TTABLE_NAK", "TTABLE_REJECTED", "TTYLOC", "TTYPE", "USERVAR", "VALUE", "VAR", "VT3270REGIME", "WILL", "WONT", "X3PAD", "XASCII", "XAUTH", "XDISPLOC", "ZMP", "theNULL", "name_command", "name_commands", "name_option", "option_from_name", ) EOF, SUSP, ABORT, CMD_EOR = (bytes([const]) for const in range(236, 240)) IS, SEND, INFO = (bytes([const]) for const in range(3)) VAR, VALUE, ESC, USERVAR = (bytes([const]) for const in range(4)) LFLOW_OFF, LFLOW_ON, LFLOW_RESTART_ANY, LFLOW_RESTART_XON = (bytes([const]) for const in range(4)) REQUEST, ACCEPTED, REJECTED, TTABLE_IS, TTABLE_REJECTED, TTABLE_ACK, TTABLE_NAK = ( bytes([const]) for const in range(1, 8) ) MCCP_COMPRESS, MCCP2_COMPRESS, MCCP3_COMPRESS = (bytes([85]), bytes([86]), bytes([87])) GMCP = bytes([201]) MSDP = bytes([69]) MSSP = bytes([70]) MSP = bytes([90]) MXP = bytes([91]) TELOPT_92 = bytes([92]) ZMP = bytes([93]) AARDWOLF = bytes([102]) ATCP = bytes([200]) # MSDP sub-command bytes (used within SB MSDP payloads) MSDP_VAR = bytes([1]) MSDP_VAL = bytes([2]) MSDP_TABLE_OPEN = bytes([3]) MSDP_TABLE_CLOSE = bytes([4]) MSDP_ARRAY_OPEN = bytes([5]) MSDP_ARRAY_CLOSE = bytes([6]) # MSSP sub-command bytes (used within SB MSSP payloads) MSSP_VAR = bytes([1]) MSSP_VAL = bytes([2]) #: List of globals that may match an iac command option bytes _DEBUG_OPTS: Dict[bytes, str] = { value: key for key, value in globals().items() if key in ( "LINEMODE", "LMODE_FORWARDMASK", "NAWS", "NEW_ENVIRON", "ENCRYPT", "AUTHENTICATION", "BINARY", "SGA", "ECHO", "STATUS", "TTYPE", "TSPEED", "LFLOW", "XDISPLOC", "IAC", "DONT", "DO", "WONT", "WILL", "SE", "NOP", "DM", "TM", "BRK", "IP", "ABORT", "AO", "AYT", "EC", "EL", "EOR", "GA", "SB", "EOF", "SUSP", "ABORT", "CMD_EOR", "LOGOUT", "CHARSET", "SNDLOC", "MCCP_COMPRESS", "MCCP2_COMPRESS", "MCCP3_COMPRESS", "GMCP", "MSDP", "MSSP", "MSP", "MXP", "TELOPT_92", "ZMP", "AARDWOLF", "ATCP", "ENCRYPT", "AUTHENTICATION", "TN3270E", "XAUTH", "RSP", "COM_PORT_OPTION", "SUPPRESS_LOCAL_ECHO", "TLS", "KERMIT", "SEND_URL", "FORWARD_X", "PRAGMA_LOGON", "SSPI_LOGON", "PRAGMA_HEARTBEAT", "EXOPL", "X3PAD", "VT3270REGIME", "TTYLOC", "SUPDUPOUTPUT", "SUPDUP", "DET", "BM", "XASCII", "RCP", "NAMS", "RCTE", "NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", "NAOLFD", ) } #: Reverse mapping of option names to option bytes _NAME_TO_OPT: Dict[str, bytes] = {name: opt for opt, name in _DEBUG_OPTS.items()} def option_from_name(name: str) -> bytes: """ Return option bytes for a given option name. :param name: Option name (e.g., "NAWS", "TTYPE") :returns: Option bytes :raises KeyError: If name is not a known telnet option """ return _NAME_TO_OPT[name.upper()] def name_command(byte: bytes) -> str: """Return string description for (maybe) telnet command byte.""" return _DEBUG_OPTS.get(byte, repr(byte)) #: IAC command bytes that should display as hex when used as option codes. #: Servers with output-filter bugs can send e.g. ``IAC WONT 0xFC`` where #: 0xFC is the WONT command byte itself. Displaying "WONT WONT" is #: confusing, so :func:`name_option` renders these as ``b'\\xfc'``. _IAC_CMD_BYTES: frozenset[bytes] = frozenset( {IAC, DO, DONT, WILL, WONT, SB, SE, NOP, DM, BRK, IP, AO, AYT, EC, EL, GA} ) def name_option(byte: bytes) -> str: """ Return string description for a telnet option byte. Unlike :func:`name_command`, IAC command bytes (DO, DONT, WILL, WONT, etc.) are displayed as ``repr(byte)`` rather than their command names when they appear in the option-byte position. """ if byte in _IAC_CMD_BYTES: return repr(byte) return _DEBUG_OPTS.get(byte, repr(byte)) def name_commands(cmds: bytes, sep: str = " ") -> str: """Return string description for array of (maybe) telnet command bytes.""" return sep.join([name_command(bytes([byte])) for byte in cmds])