6

On Debian Jessie, using php5.6 and telnet version:

$ dpkg -l | grep telnet
ii  telnet                         0.17-36                      amd64        The telnet client

I have written a php script to listen on port 23 for incoming tcp connections. For testing, I telnet into it, however I have noticed that it actually makes a difference wither I telnet into it like this:

$ telnet localhost 23

vs like this:

$ telnet localhost

But according to man telnet, it should not make a difference:

port Specifies a port number or service name to contact. If not specified, the telnet port (23) is used.

If I do not specify the port, then I get some weird noise on the line. Or maybe its not noise? But if I do specify the port then I do not get this noise on the line. The noise is the following set of ascii characters:

<FF><FD><03><FF><FB><18><FF><FB><1F><FF><FB><20><FF><FB><21><FF><FB><22><FF><FB><27><FF><FD><05>

And just in case this is due to a bug in my server-side code, here is a cut down version of the script, which does exhibit the noise (though I don't think there are any bugs in the code, I just include this because someone is bound to ask):

#!/usr/bin/php
<?php

set_time_limit(0); // infinite execution time for this script
define("LISTEN_ADDRESS", "127.0.0.1");

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 30, 'usec' => 0)); // timeout after 30 sec
socket_bind($sock, LISTEN_ADDRESS, 23); // port = 23
socket_listen($sock);
echo "waiting for a client to connect...\n";

// accept incoming requests and handle them as child processes
// block for 30 seconds or until there is a connection.
$client = socket_accept($sock); //get the handle to this client
echo "got a connection. client handle is $client\n";

$raw_data = socket_read($client, 1024);
$human_readable_data = human_str($raw_data);
echo "raw data: [$raw_data], human readable data: [$human_readable_data]\n";

echo "closing the connection\n";
socket_close($client);
socket_close($sock);

function human_str($str)
{
    $strlen = strlen($str);
    $new_str = ""; // init
    for($i = 0; $i < $strlen; $i++)
    {
        $new_str .= sprintf("<%02X>", ord($str[$i]));
    }
    return $new_str;
}

?>

And the output from the script (from connecting like so: telnet localhost) is:

waiting for a client to connect...
got a connection. client handle is Resource id #5
raw data: [�������� ��!��"��'��], human readable data: [<FF><FD><03><FF><FB><18><FF><FB><1F><FF><FB><20><FF><FB><21><FF><FB><22><FF><FB><27><FF><FD><05>]
closing the connection

But when connecting like telnet localhost 23 (and issuing the word hi) the output is:

waiting for a client to connect...
got a connection. client handle is Resource id #5
raw data: [hi
], human readable data: [<68><69><0D><0A>]
closing the connection

So my question is whether this is expected behavior from the telnet client, or whether this is noise? It is very consistent - its always the same data - so it could be some kind of handshake?

Here is the "noise" string again with spaces and without spaces, in case its more useful:

FFFD03FFFB18FFFB1FFFFB20FFFB21FFFB22FFFB27FFFD05
FF FD 03 FF FB 18 FF FB 1F FF FB 20 FF FB 21 FF FB 22 FF FB 27 FF FD 05
Toby Speight
  • 8,460
  • 3
  • 26
  • 50
mulllhausen
  • 2,648
  • 9
  • 36
  • 42
  • 2
    Are you trying to implement the [telnet](https://tools.ietf.org/html/rfc854) protocol or not? – David Schwartz Apr 04 '17 at 13:58
  • 2
    @EJP The fact that telnet *is* a protocol and not just raw TCP is not all that well-known anymore. To be quite honest, I was surprised to learn that myself, 'way back in 1995; I'd first encountered `telnet`, the command, as a debugging utility for SMTP! – zwol Apr 04 '17 at 14:35
  • @zwol: For this very reason I never use telnet to debug network protocols. Over the years I've written and re-written several raw tcp chat utilities (didn't we all write one when learning network programming?). My current go-to tool is https://github.com/slebetman/tcpchat because it's the one where I've implemented both client and server modes – slebetman Apr 04 '17 at 15:18
  • 2
    `IAC DO SUPPRESS-GO-AHEAD; IAC WILL TERMINAL-TYPE; IAC WILL NAWS; IAC WILL TERMINAL-SPEED; IAC WILL TOGGLE-FLOW-CONTROL; IAC WILL LINEMODE; IAC WILL NEW-ENVIRON; IAC DO STATUS` – hobbs Apr 04 '17 at 18:19

2 Answers2

39

telnet is not netcat. The telnet protocol is more than raw TCP. Among other things it can have a number of options, and the "noise" you're seeing is the negotiation of these options between your client and the server. When you specify a port you don't see any noise because according to the manual:

When connecting to a non-standard port, telnet omits any automatic initiation of TELNET options. When the port number is preceded by a minus sign, the initial option negotiation is done.

So apparently your implementation of telnet disables option negotiation when you specify a port (even when the port is 23), and re-enables it when the port is preceded by a minus sign.

On a more general note, it's generally safe to forget about telnet these days. Use netcat instead if you need a simple plain TCP client (or server, for that matter).

Satō Katsura
  • 13,138
  • 2
  • 31
  • 48
7

It is highly probable that your telnet command initiates a TELNET session if you don't specify any port, and initiates a raw TCP connection if any port specified.

telnet was originally designed to let distant users log into a system. So the protocol (see RFC 854 - first version of it) is designed such that telnet client negotiates different things with the server just after the connection has been initiated.