ssh result seems to only be 16bits in python with paramiko

824 views Asked by At

im using paramiko in python 2.7 to connect to a cisco router, send a command and then parse the output of the command in a for loop. the problem seems to be that the returning result is limited to 65535 characters (16bits). I printed the output and pasted it in an editor to count the characters and thats wht it gave me. Im sure im doing this very wrong because im learning python as I go hehe. here is the code:

            import sqlite3
            import paramiko
            import time
            import re

            def disable_paging(remote_conn):
                '''Disable paging on a Cisco router'''
                remote_conn.send("terminal length 0\n")
                time.sleep(1)
                output = remote_conn.recv(10000)
                return output

            if __name__ == '__main__':
                username = 'user'
                password = 'password'
                db = sqlite3.connect('cmts-priv.sqlite')
                cursor = db.cursor()
                cursor.execute('''SELECT ID, ip, hostname, uptime, active, cmtstype FROM cmts''')
                all_rows = cursor.fetchall()

                print "Producing report. This takes a few seconds so be patient and do not refresh\n"
                for row in all_rows:

                    if (row[4] == 1):


                        print "Docsis 1.x modems for : " + row[2]
                        print"\n"
                        remote_conn_pre = paramiko.SSHClient()
                        remote_conn_pre.set_missing_host_key_policy(
                             paramiko.AutoAddPolicy())
                        ip=row[1]
                        remote_conn_pre.connect(ip, username=username, password=password)
                        remote_conn = remote_conn_pre.invoke_shell()

                        disable_paging(remote_conn)
                        remote_conn.send("\n")
                        remote_conn.send("show cable modem docsis version | inc 1\.[10] 1\.[10]\n")
                        time.sleep(5)

                        output = remote_conn.recv(100000000)
                        output = output.split("\n")
                        remote_conn_pre.close()

                        #print output
                        for i in output:
                            if "0013.11" not in i and "0015.96" not in i and "0015.a2" not in i and "0015.a3" not in i and "0015.a4" not in i and "0015.ce" not in i and "0015.cf" not in i and "0015.d0" not in i:
                                X = '([0-9a-fA-F]{4}\.[0-9a-fA-F]{4}\.[0-9a-fA-F]{4})'
                                c = re.compile(X).finditer(i)
                                if c:
                                    for y in c:
                                        print i[y.start(): y.end()]
                        print "\n=============================\n"

The result this would give to the output variable would be as follow:
00a0.7373.2a14 C4/0/U1 online 11 1.0 1.0 tdma NB
00a0.7372.ed18 C4/0/U1 online 12 1.0 1.0 tdma NB
00a0.7373.2af2 C4/0/U0 online 20 1.1 1.1 tdma NB
.....
with about 3500 results per router
Then i extract the macs after i filter the ones i dont want and output them in a list. the problem is the result im getting back from the router seems to stop at 16bits when i actually would get much more. it stops at about 1/6th compared to if i produce the output directly in the router cli. I tried to play with timeouts and the sleep and the recv buffer. i just cant figure this one out :( of and the sqlite db stores a few things bbecuase i use it for a few scripts. what im getting with row[1] is the ip of the router to feed it to the connect string. Im sure a bunch of you will say im complicating my life as hell but like i said i am learning all of this from google searches hehe and then trying to understand it. this will evolve for sure but for now im really stuck in a pickle with this partial and incomplete result im getting from my routers. help :(

1

There are 1 answers

4
Buddy On BEST ANSWER

You need to put a loop around your recv, something like:

buff = ''
while not buff.endswith(':~# '):
    resp = chan.recv(9999)
    buff += resp
    print(resp)

See this example: https://gist.github.com/rtomaszewski/3397251