Enable Telnet?

Is there a way to enable telnet on the YUN? I have it working with SSH, however, I would like to use telnet instead. I have 1.5.3 installed. It doesn't look like telnetd is even in the OpenWRT image.

stbluesrul,
the linux people have been anti-telnet since Bruce Scheier stated - over 10 years ago,

"Anyone using telnet must be Nuts"

He retracted his statement later, but the damage was done. I did a talk in Silicon Valley to counter it "SSH you must be Nuts", but the best I could do was slow it down..... long story.

The short answer is, if you want telnetd on Yun, you'll have to port in and compile it. It's in the Linux (source code) branches -- somewhere.

Perhaps an SSH script would help:

#!/bin/bash
#
#
HOST=$1

MYSUBNET=`ifconfig | grep "inet addr:192.168" | cut -d "." -f 3`
OTHERNET=`echo $HOST | cut -d "." -f 3`

if [ X${HOST} == X"" ]
then
	echo ""
	echo Need hostname or IP.
	echo ""
	exit
fi
if [ ${MYSUBNET} != ${OTHERNET} ]
then
	echo ""
	echo On different subnets";" Change The Access Point.
	echo ""
	exit
fi

ssh -q -o StrictHostKeyChecking=no root@${HOST}

Thanks for the reply. I have a home automation app that I want to use with it and it doesn't support SSH. That's the only reason I'm looking to use telnet. So basically I'm just looking for a socket where I can send and receive commands in plain text. Do I have any options other than HTTP?

Yes stbluesrul,
on the Linux side of the Yun is an almost complete Unix computer. If you can login, then you can add any type of python program you want. If you look around, you might find a psuedo-terminal in python.

However, if all you want to do is poke at the unit and perhaps send it some commands, then there are plenty of example "servers" you could find.

It all depends on how much work you want to do. Like I said, there is a telnetd somewhere out in the world.

I can help you find code, write code, or find a solution. You just need to set some parameters. And I'll let you know my parameters.

Jesse

I do the same thing with my home automation system (happens to be a Crestron)

I use the YunClient class. You can set it up as a client or (I think) as a server. It just opens a raw TCP port. No log in, no nothing. Just send it text back and forth and parse it.

I set up a TCP Server on my Crestron side, and a YunClient on the YUN. Declare the YunClient in the top of the program, connect to your host it in Setup with <>.connect and then test the connection in loop() to make sure it's still connected.

stbluesrul:
I have a home automation app that I want to use with it and it doesn't support SSH.

SSH is only a requirement to get to the Linux command line to manually enter prompts. Basically, only to open a terminal session for the command line in order to do system maintenance, programming, etc. You wold not use that port as an application port.

For sockets to be used by an application, the Bridge Library gives Arduino code access to client and listener ports for HTTP and TCP. If you do your communications on the Linux side, you have the full range of options, including UDP ports.

Thanks for the info. I don't think the YunServer is going to work for me as it's an HTTP server and when connecting to it with Putty it only allows for a single connection at a time. I need multiple simultaneous connections support.

For the moment, I do have a work around. I'm connecting to a router running ddwrt via telnet, then I SSH to the YUN and then telnet to port 6571 to issue commands. It does work but the process is a little cumbersome and slow.

I'm thinking I only have 2 options.

1 - Some how compile telnet for the YUN.

2 - Use a python socket server.

2 seems like the best option, are there any examples you know of I can get started from?

Thanks again.

stbluesrul:
Thanks for the info. I don't think the YunServer is going to work for me as it's an HTTP server and when connecting to it with Putty it only allows for a single connection at a time. I need multiple simultaneous connections support.

Not true. The examples are using it as a mini-web server, by connecting to port 80 and using /arduino/ as the root of the URL. But it IS a TCP socket. If you initialize the sever with a different port number, and make a direct TCP connection to it, it acts like a regular socket.

I've used it to act as a server that listens for connections, accepts a connection, and keeps it open. My application mostly sends and explicitly discards any input, but it is most definitely getting the input and could process it if needed. The socket stays open until explicitly closed by either side. The Yun does know when the remote node closed the socket.

I'm not at my Yun right now, but can post sample code later.

Now, this is a TCP stream socket, it is not explicitly telnet. Telnet is a protocol that rides on top of a TCP socket. It adds commands to negotiate things like echo, terminal size and capabilities, character set, etc. These are important for a general purpose command line console interface, but not needed for specific machine to machine communications. In fact, the characters sent to do the negotiation look like "garbage" at the beginning of a session, and could confuse things. My code works great when my client code on another computer makes a connection, but when I use Putty to make a telnet connection, it gets a stream of "garbage" at the beginning from the negotiation. Seeing how you are considering a Python socket, I think you know this and I don't think you really want telnet, but I'm just making sure.

Here is a rather minimal sketch that runs a very basic TCP server. It's stripped down from that application I was mentioning, just leaving the core code. It verifies, but I haven't tried downloading it and running it.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

#define PORT 255
YunServer server(PORT);
YunClient client;

static boolean clientActive = false;

void setup()
{
  // Bridge startup
  Bridge.begin();
  
  server.noListenOnLocalhost();
  server.begin();
  client = server.accept();
}



void loop()
{
  if (client.connected())
  {
    if (!clientActive)
      Serial.println("New client connection.");
      
    clientActive = true;
    
    // Have a connection. Read and echo any input to the serial port
    if (client.available())
    {
      Serial.print("From client: \"");
      
      while (client.available())
        Serial.print((char)client.read());
      
      Serial.println("\"");
    }
    
    // Send to the client
    client.println("Hello Client!");
  }
  else // No connection, try to accept one.
  {
    if (clientActive)
    {
      client.stop();
      Serial.println("Client disconnected.");
    }
      
    clientActive = false;
    
    client = server.accept();
  }
}

It creates a server, listening on port 255. In setup(), it first starts the Bridge. I'm not sure if this is needed: my code used get/put so it was definitely needed there, I left it in there in case it's needed by the YunClient/YunServer. (My guess is that it is needed.) setup() ends by making the first accept call on the server, primarily to have a valid (even if not connected) client object for use in loop().

loop() first checks to see if a client is connected. If so, I use a boolen flag to see if this is a new connection, and print a message if so (my code does other things on a new connection as well.) Then, the code checks if there are any incoming data: this code just prints them on the serial port, your code would likely do something useful with the data. Then, I send some data (my code is more sophisticated in this section, yours will no doubt also do something more useful.) Finally, if there is no connection, I print a message if the connection was just closed, and then I try to accept a new connection.

How this appears to the user: the Yun is waiting for a connection on port 255. When it gets a connection, it prints a new client connection message to the serial port. As long as the connection is active, any data received is echoed to the serial port, and it sends a steady stream of "Hello Client" as fast as it can (I didn't want to put a delay() there, and I'm too lazy to add a "blink without delay" timeout just for this example.) When the connection is closed, it sends a client disconnection message to the serial port, and waits for a new connection.

Now, this is a TCP stream socket, it is not explicitly telnet. Telnet is a protocol that rides on top of a TCP socket. It adds commands to negotiate things like echo, terminal size and capabilities, character set, etc. These are important for a general purpose command line console interface, but not needed for specific machine to machine communications. In fact, the characters sent to do the negotiation look like "garbage" at the beginning of a session, and could confuse things. My code works great when my client code on another computer makes a connection, but when I use Putty to make a telnet connection, it gets a stream of "garbage" at the beginning from the negotiation. Seeing how you are considering a Python socket, I think you know this and I don't think you really want telnet, but I'm just making sure.

Correct, I'm not really interested in the telnet protocol. Just a TCP socket that I can communicate with, send commands, query data and receive feedback.

Thanks for that example. I have it working, however, when I connect with a second client any data I send does not show in the serial monitor. Nor do I get the steady stream of "Hello Client". If I close the first client the second client starts working. Is it possible to make it support multiple clients simultaneously?

I'm not sure why you're not getting multiple "Hello Client" messages. Like I said, I haven't tried that part.

Yes, the code is specifically set up to handle one client at a time. My application doesn't really make sense to have multiple simultaneous connections, so I haven't tried to accept several connections. The current limitation is the single YunClient object, and how server.accept() is only called when there is no active connection.

The server object keeps the incoming port open, while accept() listens for connections on that port. When a connection request comes in, accept() allocates a new port, sets up the connection, and creates a client object to handle that connection. If you want to keep receiving connections, you need to keep calling server.accept(). Of course, you will need to keep track of multiple client objects: each one manages one connection.

I think I would try making an array of client objects, sized for the maximum number of clients you want to support. Loop through the array, and process each connected client in turn. Then call server.accept() if you have any unconnected clients.

fab03 has discovered a bug in my example code, thank you for finding it, sir!

I have made a change to the code above, toward the end where a disconnected client is handled:

. else // No connection, try to accept one.
  {
    if (clientActive)
    {
      client.stop();
      Serial.println("Client disconnected.");
    }
      
    clientActive = false;
    
    client = server.accept();
  }

It used to be that if (clientActive) is true, it simply printed a message. Now it also explicitly calls client.stop(). I had assumed that since the client object knew the connection was gone, it would clean things up automatically and release resources. That is apparently not the case, because without this explicit closing of the client, the sketch stops accepting connections after 256 cycles.