Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read data from Telnet session

Tags:

go

telnet

I'm trying to create a tool to connect to a network device by Telnet and send some commands (Expect-like with certain additional requirements) using go-telnet.

To the moment I managed to create a connection and send commands with something like this:

func main() {
    var loginBuffer = [6]byte{'r', 'o', 'o', 't', '\r', '\n'}
    var login = loginBuffer[:]

    conn, err := telnet.DialTo("10.10.10.2:23")
    if nil != err {
        fmt.Println(err)
    }
    defer conn.Close()

    conn.Write(login)
}

Using Wireshark I can see the device responding, however I cannot read any response data. Guess I'm using Read() in a wrong way, not sure.

Would appreciate a working example or an explanation of how to capture and process response data in this case.

like image 748
Alexander Avatar asked Jun 06 '26 00:06

Alexander


1 Answers

Thanks everyone, who spared their time to answer my question. I managed to identify the problem:

  1. Every time I created a read buffer it was too big (1024 bytes) so the program was waiting for it to fill up. Now I'm using a cycle reading to a 1 byte buffer.

  2. It seems, I also needed some criterion for the function to stop reading and proceed with sending commands.

Here is the working piece of code:

// Thin function reads from Telnet session. "expect" is a string I use as signal to stop reading
func ReaderTelnet(conn *telnet.Conn, expect string) (out string) {
    var buffer [1]byte
    recvData := buffer[:]
    var n int
    var err error

    for {
        n, err = conn.Read(recvData)
        fmt.Println("Bytes: ", n, "Data: ", recvData, string(recvData))
        if n <= 0 || err != nil || strings.Contains(out, expect) {
            break
        } else {
            out += string(recvData)
        }
    }
    return out
}

//convert a command to bytes, and send to Telnet connection followed by '\r\n' 
func SenderTelnet(conn *telnet.Conn, command string) {
    var commandBuffer []byte
    for _, char := range command {
        commandBuffer = append(commandBuffer, byte(char))
    }

    var crlfBuffer [2]byte = [2]byte{'\r', '\n'}
    crlf := crlfBuffer[:]

    fmt.Println(commandBuffer)

    conn.Write(commandBuffer)
    conn.Write(crlf)
}

func main() {
    conn, err := telnet.DialTo("10.10.10.2:23")
    if nil != err {
        fmt.Println(err)
    }

    fmt.Print(ReaderTelnet(conn, "Login"))
    SenderTelnet(conn, "root")
    fmt.Print(ReaderTelnet(conn, "Password"))
    SenderTelnet(conn, "root")
    fmt.Print(ReaderTelnet(conn, ">"))
}
like image 56
Alexander Avatar answered Jun 10 '26 07:06

Alexander