Search code examples
perlcharacter-encodingtelnet

How do i send just a CR, not a CR NUL in Perl with Net::Telnet?


I need to communicate with an appliance via the telnet protocol. It turns out that it can not handle CR-NUL or CR-LF sequences as output record separators, only straight CR. Otherwise it will interpret the character following the CR as belonging to the next command, which then results in errors. So i set Output_record_separator to CR, but then see in the communication dump (in the Dump_Log), that not just a CR (0x0d) was sent, but a CR NUL (0x0d 0x00). I can send single chars, though: if i send just a LF, only a LF (ox0a) is send.

This code shows the problem:

#!/usr/bin/env perl
use strict;
use warnings;

use Net::Telnet;

my $host = "192.168.2.223";
my $port = 5000;


my $telnet = new Net::Telnet ( 
    Timeout                 => 20, 
    Errmode                 => 'die',
    Port                    => $port,
    Dump_Log                => '/tmp/debug',
    Output_record_separator => "\015",
    Input_record_separator  => "\n\r",
    Prompt                  => '/1_.*0/',
    Binmode                 => 1,
);

$telnet->open($host);
$telnet->put("\015");
$telnet->put("\012");

which results in this:

tail: /tmp/debug: file truncated
> 0x00000: 0d 00                                               ..

> 0x00000: 0a                                                  .

How can i make Net::Telnet send just CR, without adding more stuff?


Solution

  • Set Telnetmode to 0. If Telnetmode is on then CR is translated to CR + 0x00.

    From the Net::Telnet source:

    ## Convert all CR (not followed by LF) to CR NULL.
    while (($pos = index($$string, "\015", $pos)) > -1) {
    $nextchar = substr $$string, $pos + 1, 1;
    
    substr($$string, $pos, 1) = "\015\000"
        unless $nextchar eq "\012";
    

    You can turn the mode on and off using $telnet->telnetmode(...):

    telnetmode - turn off/on telnet command interpretation
    $mode = $obj->telnetmode;
    $prev = $obj->telnetmode($mode);

    This method controls whether or not TELNET commands in the data stream are recognized and handled. The TELNET protocol uses certain character sequences sent in the data stream to control the session. If the port you're connecting to isn't using the TELNET protocol, then you should turn this mode off. The default is on.

    If no argument is given, the current mode is returned.

    If $mode is 0 then telnet mode is off. If $mode is 1 then telnet mode is on.