Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#!/usr/bin/perl # # Purpose: Dial the OOB on a cisco router # and determine the OOB if the # OOB line is up and functioning # properly # # Code by Brad Lhotsky <brad@divisionbyzero.net> # Based off code by jcwren on http://perlmonks.org # # Note: The modem (US Robotics 56k v.90 Fax Sportster) # had no support for advanced error messages such # as "ring no answer" and various other "higher # level" error messages so I am using my own methods # to report what error messages get generated. # $|++; use strict; # always use Device::SerialPort; # so we can communicat +e with modem use IPC::ShareLite; # for sharing memory use POSIX "sys_wait_h"; # for flags for waitpi +d use Time::HiRes qw(gettimeofday); # for more error handl +ing using times use Time::localtime; # for logging date for +mat crap. use Getopt::Std; # to get command line +options ################### # Defaults, for my # sanity more than # anything else my $DEF_DEV = '/dev/cua1'; # set this for fun my $DEF_USR = ''; # should be a "read only" use +r my $DEF_PWD = ''; # see above my $DEF_RTR = 3; # for sanity my $DEF_TMO = 90; # for sanity ################### # configs. my %OPTS = (); # options hash getopts("d:l:nr:t:u:p:hva", \%OPTS); # get options help() if $OPTS{'h'}; my $DEVICE = $OPTS{'i'} || $DEF_DEV; # serial port ext. mod +em is on my $NOISEDIAL = $OPTS{'n'}; # Turn on/off the mode +m speaker my $BAUD = 9600; # our initial baud rat +e my $MINBAUD = 9600; # if we find a baud le +ss than this, bitch my $USERNAME = ($OPTS{'u'} || $DEF_USR) . "\n"; # username for the rou +ter my $PASSWORD = ($OPTS{'p'} || $DEF_PWD)."\n"; # password for the rou +ter my $MAX_RETRY = $OPTS{'r'} || $DEF_RTR; # number of times we r +etry my $LOG = $OPTS{'l'}; # log file my $TIMEOUT = $OPTS{'t'} || $DEF_TMO; # how long before we d +etermine failure my $DIALPREFIX = 91; # to get an outside li +ne if($LOG) { open LOG, ">>$LOG" or die "couldn't open debug.out: $!\n"; select(LOG); $|++; select('stdout'); } ################### # Globals. my %FAILED = (); my @GOOD = (); #################### # Modem commands # that might be fun. my $MODEM_HANGUP = "ATH1\n"; # modem hangup, clear the line +. my $MODEM_QUIET = "ATM0\n"; # silence the speaker my $MODEM_SOUND = "ATM1\n"; # unsilence the speaker #################### # assemble our list # of modems to dial my $LIST = $ARGV[0]; die "usage: $0 sitefile ($ -h for more info)\n" unless -e $LIST; my %SITES = (); # Global sites hash. open(CFG, "<$LIST") or die "could not open $LIST: $!\n"; my $TOTALNUM = 0; while(local $_ = <CFG>) { s/^\s+//; s/\s+$//; next if !$_ || /^#/; ($_, undef) = split /\s*#\s*/; next if !$_; my ($site,$number) = split/\s*:\s*/; next unless $site && $number; next if exists $SITES{$site}; # no duplicates over writing c +rap. $SITES{$site} = $number; $TOTALNUM++; } close CFG; die "$LIST: empty configuration file!\n" unless $TOTALNUM; logthis("SYSTEM","Loaded $TOTALNUM numbers to check!"); foreach my $site (sort keys %SITES) { print "Testing $site ... " unless $OPTS{'v'}; my $share = new IPC::ShareLite( -key => 6969, -create => 'yes', -destroy => 'no', -size => 1024) or die "Couldn' +t share memory: $!\n"; my $SUCCESS = 0; my $REASON = ""; # using this method of forking # is the only way to "next" in a loop using # alarm and trapping SIG_ALRM # many thanks to mikfire for this idea my $pid = fork(); if($pid == 0) { # we're the child, do the grunt work exit OOBtest($site,$SITES{$site}); } elsif(defined $pid) { # wait for the child to finish my $tmp = waitpid($pid,''); # Success/failure returned through OOBtest() # gets thrown in $? so lets check it. $SUCCESS = $?; } else { die "fork error: $!\n"; } if(!$SUCCESS) { $REASON = $share->fetch() || "Unknown failure conditio +n"; $FAILED{$site} = $REASON; } else { push @GOOD,$site; } print "done.\n" unless $OPTS{'v'}; } # EOForeach for(sort keys %FAILED) { print "FAILED: $_ : " . $FAILED{$_} . "\n"; } for(sort @GOOD) { print "GOOD: $_\n"; } ################################# # here's where the work is done. sub OOBtest { my ($site,$number) = @_; # we'll use this hash to determine whether # or not we miss any steps along the way my %STAGES = ( "connect" => 0, "login" => 0, "password" => 0, "prompt" => 0 ); my @STAGES = ("connect", "login", "password", "prompt"); my $share = new IPC::ShareLite( -key => 6969, -create => 'no', -destroy => 'no', -size => 1024) or die "couldn' +t share memory: $!\n"; $share->store('NONE'); my $ob = new Device::SerialPort ($DEVICE, 1); die "Couldn't access $DEVICE: $!\n" unless $ob; $SIG{"ALRM"} = sub { select undef, undef, undef, 0.5; if($share->fetch ne 'NONE') { my $newmsg = $share->fetch() . + ", Timeout after $TIMEOUT seconds"; $share->store($newmsg); } else { $share->store("Timeout after $ +TIMEOUT seconds"); } logthis($site,"FATAL ERROR: Connection + Timedout after $TIMEOUT seconds"); $ob->close; select undef, undef, undef, 0.5; undef $ob; select undef, undef, undef, 0.5; exit 0; }; alarm($TIMEOUT); ################### # setup device select undef, undef, undef, 0.5; # sleep for half a sec +ond $ob->baudrate($BAUD); $ob->parity('none'); $ob->databits(8); $ob->stopbits(1); $ob->handshake('none'); $ob->stty_icrnl(1); $ob->stty_ocrnl(1); $ob->stty_onlcr(1); $ob->stty_opost(1); $ob->write_settings; select undef, undef, undef, 0.5; # sleep for half a sec +ond $ob->write($MODEM_HANGUP); # clear the line select undef, undef, undef, 1.5; # sleep for one and ha +lf a second my $buff = $ob->input; if($buff =~ /OK/) { logthis($site,"INIT: Modem hangup sent, line cleared." +); } else { logthis($site,"INIT ERROR: Modem did not respond to ha +ngup"); } if(!$NOISEDIAL && !$OPTS{'a'}) { $ob->write($MODEM_QUIET); # silence the +modem select undef, undef, undef, 1.5; # sleep for on +e and half a second my $buff = $ob->input; if($buff =~ /OK/) { logthis($site,"INIT: Modem sound off."); } else { logthis($site,"INIT ERROR: Modem did not respo +nd to sound off"); } } else { $ob->write($MODEM_SOUND); # make some no +ise select undef, undef, undef, 1.5; # sleep for on +e and half a second my $buff = $ob->input; if($buff =~ /OK/) { logthis($site,"INIT: Modem sound on."); } else { logthis($site,"INIT ERROR: Modem did not respo +nd to sound on"); } } select undef, undef, undef, 0.5; # sleep for half a sec +ond my $dial = $OPTS{'a'} ? "ATDP $DIALPREFIX$number\n" : "ATDT $D +IALPREFIX$number\n"; logthis($site,"DIAL STR: $dial"); ######################## # Setup the environment my $RETRY = 0; my $DONE = 0; my $TOTALIN = 0; my $TOTALOUT = 0; my $SUCCESS = 0; my $ERROR = ""; my $DIAL_TIME = gettimeofday; $ob->write($dial); select undef, undef, undef, 0.5; # sleep for half a sec +ond while(!$DONE) { # this next bit of code is purely # for my own amusement. my ($inbytes,$outbytes) = (0,0); (undef, $inbytes, $outbytes, undef) = $ob->status or warn "could not get port status!\n"; $TOTALIN += $inbytes; $TOTALOUT += $outbytes; # end amusement if(my $line = $ob->input) { $line =~ s/[\r\n\cM]//mg; if($line =~ /CONNECT\s+(\d+)/i) { # We have initialized! $STAGES{"connect"}++; # Check other end's baudrate and # adjust if need be. if($1 != $BAUD) { if($1 < $MINBAUD) { $share->store("Baudrat +e of $1 is less than minimum ($MINBAUD)"); } logthis($site,"CONN: baudrate +is now $1"); $ob->baudrate($1); $ob->write_settings; # pause momentarily select undef, undef, undef, 1. +2; } # now we have to "press enter a few ti +mes" $ob->write("\n\n"); } elsif($line =~ /(NO CARRIER)/i || $line =~ / +(BUSY)/i) { # we failed, keep trying! my $err = $1; if($RETRY > $MAX_RETRY) { if($line =~ /(BUSY)/i) { logthis($site,"DIAL ER +ROR: Remote line busy"); $share->store("Line wa +s busy"); } else { # using the time betwe +en dialing to determine # local or remote lack + of a carrier my $diff = gettimeofda +y - $DIAL_TIME; $diff *= 100; logthis($site,"DIAL DI +FF: $diff"); if($diff > 800) { $share->store( +"Local modem had no free line"); } else { $share->store( +"No answer from remote modem"); } } logthis($site,"FATAL ERROR: Re +ached maximum retry for $site"); $DONE++; last; } $share->store("line status $err (retry + $RETRY of $MAX_RETRY)"); logthis($site,"ERROR: line status $err + (retry $RETRY of $MAX_RETRY)"); $RETRY++; my $diff = (gettimeofday - $DIAL_TIME) +*100; if($diff > 800) { if($line =~ /BUSY/i) { logthis($site,"DIAL ER +ROR: Remote line was busy"); } else { logthis($site,"DIAL ER +ROR: Remote modem did not pickup"); } } else { if($line =~ /BUSY/i) { logthis($site,"DIAL ER +ROR: Remote line was busy"); } else { logthis($site,"DIAL ER +ROR: Local modem had no free line"); } } $ob->write($MODEM_HANGUP); logthis($site,"REDIAL: clearing line") +; select undef, undef, undef, 1.5; $DIAL_TIME = gettimeofday; $ob->write($dial); select undef, undef, undef, 0.5; logthis($site,"REDIAL ($RETRY of $MAX_ +RETRY): dialing $number"); } elsif($line =~ /sername\:/i || $line =~ /ogi +n\:/i) { # got login prompt $STAGES{"login"}++; # attempt to login $ob->write($USERNAME); logthis($site,"CONN: sent username"); } elsif($line =~ /assword\:/i) { # password prompt $STAGES{"password"}++; $ob->write($PASSWORD); logthis($site,"CONN: sent password"); } elsif($line =~ /[\w().-]*[\$#>]/) { # prompt # which is all we were looking for! $STAGES{"prompt"}++; logthis($site,"CONN: Got to our prompt +!"); $DONE++; last; } } select undef, undef, undef, 0.5; # sleep for ha +lf a second. } logthis($site,"Closing serial port."); sleep 1; $ob->close; sleep 1; undef $ob; logthis($site,"Total bytes transferred: $TOTALIN (in), $TOTALO +UT (out)","Session closed."); my $stageError = 0; for(keys %STAGES) { $stageError++ if !$STAGES{$_}; } if($stageError) { my $logmsg = "FAILED CONNECTION STAGES: "; if($share->fetch eq 'NONE') { $share->store("FAILED CONNECTION STAGES: "); } else { my $new = $share->fetch() . ", FAILED CONNECTI +ON STAGES:"; $share->store($new); } foreach my $stage (@STAGES) { if(!$STAGES{$stage}) { $logmsg .= " $stage"; my $new = $share->fetch() . " $stage"; $share->store($new); } } logthis($site,$logmsg); return 0; } return 1; } sub logthis { my $site = shift; my @msgs = @_; my $date = ctime(); foreach my $msg (@msgs) { $msg =~ s/[\r\n\cM]//g; $LOG && print LOG "$date - $site - $msg\n"; print "$date - $site - $msg\n" if $OPTS{'v'}; } } sub help { print <<" EOHELP"; OOB Test Dialer v0.1 -------------------- Code by: Brad Lhotsky <brad\@divisionbyzero.net> Distributed under the same license as perl itself, use at your own risk, and fight UCITA. usage: $0 [-anhv] [-l logfile] [-r maxretry] [-d device] \ [-t timeout (in seconds)] [-u username] [-p password] +\ filewithnumbers options: h - display this message d <device> - interface, typically /dev/cuaN of /dev/tt +ySN where N is the port number. default: $DEF_DEV l <logfile> - file to append information to default: off v - display all log info to STDOUT (can be used with - +l) default: off n - noisy dialing (turn modem speaker on) default: off a - annoying (enable pulsa dialing) default: off t <timeout> - timeout in seconds default: $DEF_TMO r <number> - number of retries per number default: $DEF_RTR u <username> - username to login p <password> - password to login EOHELP exit 0; }

In reply to Out of Band Access Testing by reyjrar

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (4)
    As of 2015-07-07 04:26 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (87 votes), past polls