PureBasic
PureBasic
SSH Commands to a Cisco Switch
See more SSH Examples
Demonstrates establishing an SSH session with a Cisco switch (or similar device) and sending commands in a device console session. Each command is sent, and its output is read up to the device's next prompt.
Note: QuickShell allocates a PTY, which is what a network device console expects. The device presents an interactive prompt, and each command's output is read up to the next prompt.
Background: Network devices differ from general-purpose servers in that they expose a menu- or prompt-driven console rather than a Unix shell, so
exec requests are usually unavailable and driving the interactive console is the only option. That makes prompt matching the synchronization mechanism, and it is why a PTY is appropriate here despite the general advice to avoid one. Retrieving the received text between commands is essential: a prompt left in the buffer would make the next receive return immediately with the wrong output.Chilkat PureBasic Downloads
IncludeFile "CkSsh.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; Demonstrates establishing an SSH session with a Cisco switch (or similar device) and sending
; commands in a device console session.
;
; Note: QuickShell allocates a PTY, which is what a network device console expects. The device
; presents an interactive prompt, and each command's output is read up to the next prompt.
ssh.i = CkSsh::ckCreate()
If ssh.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
port.i = 22
success = CkSsh::ckConnect(ssh,"172.16.16.100",port)
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
; Normally you would not hard-code the password in source. You should instead obtain it
; from an interactive prompt, environment variable, or a secrets vault.
password.s = "mySshPassword"
success = CkSsh::ckAuthenticatePw(ssh,"mySshLogin",password)
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
; Start a shell session.
channelNum.i = CkSsh::ckQuickShell(ssh)
If channelNum < 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
; IMPORTANT: Set a read timeout before receiving until a match. ReadTimeoutMs defaults to 0,
; which means no limit -- without it, this call waits forever if the received data never
; contains a match.
CkSsh::setCkReadTimeoutMs(ssh, 15000)
caseSensitive.i = 1
; The switch presents a prompt ending in "#". Reading up to it confirms the session is ready.
success = CkSsh::ckChannelReceiveUntilMatch(ssh,channelNum,"#","utf-8",caseSensitive)
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
cmdOutput.s = CkSsh::ckGetReceivedText(ssh,channelNum,"utf-8")
If CkSsh::ckLastMethodSuccess(ssh) = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
Debug cmdOutput
; Send a command and read its output up to the next prompt.
success = CkSsh::ckChannelSendString(ssh,channelNum,"show clock" + Chr(10),"utf-8")
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
success = CkSsh::ckChannelReceiveUntilMatch(ssh,channelNum,"#","utf-8",caseSensitive)
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
; Retrieving the text also clears the receive buffer, which matters: if the prompt were left
; buffered, the next receive would match it immediately and return the wrong output.
cmdOutput = CkSsh::ckGetReceivedText(ssh,channelNum,"utf-8")
If CkSsh::ckLastMethodSuccess(ssh) = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
Debug cmdOutput
; Additional commands follow the same send / read-to-prompt / retrieve pattern.
success = CkSsh::ckChannelSendString(ssh,channelNum,"show version" + Chr(10),"utf-8")
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
success = CkSsh::ckChannelReceiveUntilMatch(ssh,channelNum,"#","utf-8",caseSensitive)
If success = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
cmdOutput = CkSsh::ckGetReceivedText(ssh,channelNum,"utf-8")
If CkSsh::ckLastMethodSuccess(ssh) = 0
Debug CkSsh::ckLastErrorText(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndIf
Debug cmdOutput
CkSsh::ckDisconnect(ssh)
CkSsh::ckDispose(ssh)
ProcedureReturn
EndProcedure