package require Itcl 3.3 package require telnet 2.0.0 itcl::class TelnetClient { public variable host "" public variable port 23 public variable user "admin" public variable password "password" public variable timeout 10 public variable debug 0 private variable my_sock "" private variable out_buffer "" public variable xwait "" common xtimeout constructor {args} {} destructor { disconnect } public method connect {args} public method send {args} public method disconnect {} private method get_data {} private method wait_complete {} private method timeout {} private method reset_timeout {} private method wait_or_timeout {} } # Lowercase access procedure proc telnetclient {args} { uplevel ::TelnetClient $args } itcl::body TelnetClient::constructor {args} { eval configure $args if {($ip == "") || ($port == "")} { error "IP and Port must be specified" } } itcl::body TelnetClient::connect {args} { if {![catch {telnet::open $host $port} conn]} { set my_sock $conn fconfigure $my_sock -blocking false -buffering none -translation auto -eofchar {} flush $my_sock fileevent $my_sock readable [itcl::code $this get_data] wait_or_timeout if {[regexp -nocase {(username|login|user)\s?:} $out_buffer]} { set login [send "$user"] if {[regexp -nocase {(password)\s?:} $login]} { set passdRes [send "$password"] if {[regexp {(.>)} $passdRes]} { return 0 } else { close $conn error "Error: Unexpected System Prompt" } } else { close $conn error "Error: Unexpectd Password Prompt" } } else { close $conn error "Error: Unexpected Login Prompt" } } else { error "Error: Connection Refused" } } itcl::body TelnetClient::get_data {} { if {[eof $my_sock]} { close $my_sock set connected 0 } else { if {![catch {telnet::read $my_sock} data]} { switch -regexp $data { # Add login and password patterns as needed {([Uu]sername|[Ll]ogin|[Pp]assword)\s?:} { append out_buffer $data wait_complete return } # Change this value to your Telnet Prompt {.>} { append out_buffer $data wait_complete return } default { append out_buffer $data reset_timeout } } } else { wait_complete close $mySocked return } } } itcl::body TelnetClient::timeout {} { catch {after cancel $xwait} set xtimeout($this) 1 puts "Timeout of after [expr {$timeout * 1000}] seconds" return } itcl::body TelnetClient::wait_or_timeout {} { set xwait [after [expr {$timeout * 1000}] [itcl::code $this timeout]] vwait [itcl::scope xtimeout($this)] return } itcl::body tti::TelnetClient::reset_timeout {} { catch {after cancel $xwait} set xwait [after [expr {$timeout * 1000}] [itcl::code $this timeout]] return } itcl::body TelnetClient::wait_complete {} { catch {after cancel $xwait} wres set xtimeout($this) 1 return } itcl::body TelnetClient::send {data} { set out_buffer "" if {![eof $my_sock]} { if {![catch {telnet::write $my_sock "$data\r"} err]} { flush $my_sock fileevent $my_sock readable [itcl::code $this get_data] wait_or_timeout return $out_buffer } else { error "$err" } } else { error "Error: Connection Closed" } } itcl::body TelnetClient::disconnect {} { catch { close $my_sock } }