reyjrar has asked for the wisdom of the Perl Monks concerning the following question:

Ok, so this maybe someone else would be able to help me out here.
been working with getting information off of Cisco routers, and for this, I've been using Net::Telnet and Net::Telnet::Cisco. They were working great until yesterday when I was asked to interface with route servers that do not prompt for login. These servers don't fall under my companies control, and thus I cannot push for a standard, so I'm forced to deal with what I have.
The end result, will be a web page, with some checkboxes for each route server, and a text box to enter commands you want to run on the router comma delimited, you hit submit, it returns a listing or routers with each commands output listed below. I have hte web interface done, now I'm just stuck on the most important part, getting the correct data, here's what's happening.. well.. using Net::Telnet and Net::Telnet::Cisco I've found that the out generated by simply creating the object and issuing a command is N/A, that I have to run a command twice to "open the conenction" for instance:
my $router = new Net::Telnet::Cisco(Host => $ip); my @output = $router->cmd("sh users"); print @output;
yields nothing to the screen, I figured out why though.. the terminal length setting was 25, the cisco default so I:
$router->cmd("terminal length 0");
still nothing.. the script timed out waiting for the prompt to return. so I just out on a limb:
$router->cmd("terminal length 0"); $router->cmd("terminal length 0"); my @output = $router->cmd("sh users"); print @output;
now I have something, so I thought, "Great, lets put this into production". so I did.. the results, are incredibly inconsistant, obviously because this was a bad work around. so I think "hey, I've worked with sockets before, I'll just write my own interface to this tricky situation!" so I did.. but I've been toying with the issuing multiple commands to routers using send() and recv() and autoflushing the socket, no luck and I've tried it many different ways, one of which I though should work:
foreach my $server (@SERVERS) { my ($sname,$sdom); if($server =~ /^([^.]+)(.+)/) { $sname = $1; $sdom = $2; $sdom =~ s/\./\\\./g; } print "\n\n---> Trying $server .... "; socket(ROUTER,AF_INET,SOCK_STREAM,getprotobyname('tcp')); my $sin = sockaddr_in(23,inet_aton($server)); connect(ROUTER,$sin); # or die "$server needs a kick!\n"; print "Connected.\n"; bind(ROUTER,$sin); # below insight provided by Net::Telnet.pm select((select(ROUTER), $|=1)[$[]); #don't buffer writes # end insight. send(ROUTER, "\n", ''); #doing to get a prompt +, establish connection my $task= scalar @CMDS; my $line=""; my $get_output=0; my $i=0; my %OUT=(); while(recv(ROUTER,$line,$LENGTH,'')) { local $_ = lc($line); if(/^$sname($sdom)?\>/) { #we have a prompt if(!$task) { #we're done! send(ROUTER, $close, ''); last; } else { send(ROUTER, $CMDS[$i], ''); $i++; $task--; $get_output=1; next; } } elsif($get_output) { #we're between two pro +mpts and interested in the output push @{ $OUT{$CMDS[$i-1]} }, $line; print $line; } } close ROUTER; }
what happens here is even though the prompt matched previously, it isn't matching again, and is getting printed at the "elsif($get_output)", thus never issuing the next command and only getting to the first server cuz it halts the recv() ..... I can't see how this could happen, but perhaps others could slap me in the right direction.

Any help would be greatly appreciated,

-brad..

Replies are listed 'Best First'.
Re: Interesting Dilemma
by Fastolfe (Vicar) on Nov 29, 2000 at 01:39 UTC
    Are you logging in first? The Net::Telnet::Cisco documentation has a 'login' statement between your object creation and the point where you're executing your first command.
      that choked for me if I tried to $router->login() or if I $router->('', '') or if I $router->login(undef, undef).. I'll go back and try it one more time though..

      UPDATE: Yeah, the $router->login(); works, but yields the same inconsistancies as doing it with two $router->cmd()'s

      not sure what that means..
      -brad..
Re: Interesting Dilemma
by geektron (Curate) on Nov 29, 2000 at 05:33 UTC
    for commands that don't require a log-in, use IPC::Open2 or IPC::Open3. i use it frequently for things like rcp and rsh ( on Cisco routers ). i don't know specifically which commands you're trying. . .

    IPC::Open* will handle most of the socket connection stuff for you.

    or you could try to use Expect.pm if the router is giving you prompts. . .

    what happens when you execute the commands from your shell? that should give you some indication of what's going on. it's also possible that your webdaemon doesn't have permissions to execute commands on the router. occasionally i'll have to use sudo -u poweruser cmd to get anything done on the routers.

Re: Interesting Dilemma
by repson (Chaplain) on Nov 29, 2000 at 04:12 UTC
    First of all you didn't mention whether you can run the commands through a normal telnet client on the machine you are running the program. Then make sure you are not forgetting to send any characters eg \r ands \n, these are neccessary at the end of lines to send the buffer. You might also like to try IO::Socket, instead of using direct socket calls. This module is part of the standard distribution and provides an OO and to many a more intuitive and simpler interface to sockets.
Re: Interesting Dilemma (packet capture)
by ybiC (Prior) on Nov 29, 2000 at 02:11 UTC
    I've yet to delve into socket programming, so can't comment on the code.

    But... if it's an option, a filtered packet capture using something like Sniffer, tcpdump, or sniffit could easily yield clues to the intermittant behavior.
        cheers,
        Don
        striving for Perl Adept
        (it's pronounced "why-bick")

Re: Interesting Dilemma
by mnperez (Sexton) on Nov 29, 2000 at 13:09 UTC
    Is there a reason you can't use Net::SNMP to get some of this information? Not sure about the route-servers, but I know that most everything you can get from the Cisco CLI you can get via SNMP also. Something to think about.
Re: Interesting Dilemma
by reyjrar (Hermit) on Nov 29, 2000 at 22:25 UTC
    Well, everything works fine when I telnet into the router and issue the commands from the command line.. so that's not the problem. The specs for this project also don't allow me to use SNMP for right now atleast. I'm looking into using IPC::Open2.
    but I guess that I'm trying to figure out is why the prompt isn't matching in this case..

    thanks again!

    -brad..