Search code examples
pythontelnettelnetlib

Python's telnetlib "read_until()" not receiving expected string


New to python but I am attempting to automate opening a telnet session (using the inbuilt "telnetlib" library) into a router, executing a simple command ("spc"), print output to the local console and then leaving.

#!/usr/bin/python

import sys
import telnetlib

HOST="54.18.5.0"
PORT=55555

tn=telnetlib.Telnet(HOST, PORT)

tn.read_until("Escape character is \'^]\'.")
tn.write("\u001d")
tn.read_until("telnet>")
tn.write("mode char" + "\n")

tn.write("spc\n")

print tn.read_all()

My problem seems to lie with the "read_until" function. When I run the above script, it will hang until a keyboard interrupt at which point I get the following messages:

CTraceback (most recent call last):
File "./telnetMR.py", line 11, in <module>
tn.read_until("Escape character is \'^]\'.")
File "/usr/lib64/python2.7/telnetlib.py", line 294, in read_until
return self._read_until_with_poll(match, timeout)
File "/usr/lib64/python2.7/telnetlib.py", line 318, in _read_until_with_poll
else 1000 * call_timeout)

I am assuming that "read_until()" is not receiving anything and is therefore waiting around until the timeout but I cannot understand why.

(I have written this same script using "expect" which works just fine but I would like to see if I can get it working in python for efficiency... so any comments regarding sending the octal string are appreciated but that is not what this question is for).

Thank you.


Solution

  • Your "problem" is that

    tn.write("\u001d")
    tn.read_until("telnet>")
    

    is something that you would do from the shell/command line, that's a feature of the command line client. That's why expect works, because it launches that client.

    In this case, using the telnetlib, "you" are the "client", so you have to "speak telnet" to the server, that means you'll have to sent some IAC + [DO|DONT|WILL|WONT] + ... sequence, the same thing that the command line does when you do mode char, there's this other thread talking about what the sequence should/could be, but you could also use tcpdump (or similar tools) to check what the command line client is sending when calling mode char, (just to be 100% sure).

    Sending it's a matter of doing something like:

    tm.sock.send(telnetlib.IAC+telnetlib.DO+ ...) # ... whatever the sequence is