Please implement telnet negotiation for serial ports

Here you can provide suggestions on how to improve the product, website, etc.
Post Reply
Udo Munk
Posts: 2
Joined: 5. Mar 2016, 15:18

Please implement telnet negotiation for serial ports

Post by Udo Munk »

If using a UNIX guest under Virtualbox one might want to telnet into the VM via the serial ports. This is interesting special for older UNIX systems without networking, like COHERENT.

Unfortunately the TCP/IP sockets for the serial ports won't do telnet negotiation, so one gets a connection with local editing and local echo, which is annoying to use. Of course one can tell most telnet clients to use character mode, but theses things can be automated very easily. In the COM port settings for TCP/IP sockets add a selection 'raw' and 'telnet'. If set to telnet the following function will negotiate a proper setting for telnet clients, kermit and whatever:

Code: Select all

/*
 *      do the telnet option negotiation
 */
void telnet_negotiation(int fd)
{
        static char will_echo[3] = {255, 251, 1};
        static char char_mode[3] = {255, 251, 3};
        struct pollfd p[1];
        BYTE c[3];

        /* send the telnet options we need */
        write(fd, &char_mode, 3);
        write(fd, &will_echo, 3);

        /* and reject all others offered */
        p[0].fd = fd;
        p[0].events = POLLIN;
        while (1) {
                /* wait for input */
                p[0].revents = 0;
                poll(p, 1, TELNET_TIMEOUT);
                /* done if no more input */
                if (! p[0].revents)
                        break;

                /* else read the option */
                read(fd, &c, 3);
                //printf("telnet: %d %d %d\r\n", c[0], c[1], c[2]);
                if (c[2] == 1 || c[2] == 3)
                        continue;       /* ignore answers to our requests */
                if (c[1] == 251)        /* and reject other options */
                        c[1] = 254;
                else if (c[1] == 253)
                        c[1] = 252;
                write(fd, &c, 3);
        }
}
Call this function after accept() for the server socket, if the telnet setting is checked, for TELNET_TIMEOUT I use 800.

Code needs to be read with RFC for telnet negotiation close by. This is the implementation I use for my Z80/8080 virtual machines from the z80pack project. (google it, I may not post URLs).

Code is under BSD license, can be used under MIT license or whatever you need, I really don't care.

With that in place it is much more comfortable to telnet into VMs running some sort of UNIX. This is a really small change and it would make using Virtualbox more comfortable for me, probably for others too, so thanks in advance.
Last edited by noteirak on 13. Mar 2016, 23:28, edited 1 time in total.
Reason: Added code tag
mpack
Site Moderator
Posts: 39134
Joined: 4. Sep 2008, 17:09
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Mostly XP

Re: Please implement telnet negotiation for serial ports

Post by mpack »

These are software functions. They have no place in a hardware simulator.
Udo Munk
Posts: 2
Joined: 5. Mar 2016, 15:18

Re: Please implement telnet negotiation for serial ports

Post by Udo Munk »

If the COM port could only be mapped to the physical ports of the host then yes, that would be hardware emulation only.
But the ports support software functions, like TCP/IP connections, and these can be implemented a bit better as is.
Grant
Posts: 4
Joined: 13. Mar 2016, 19:33

Re: Please implement telnet negotiation for serial ports

Post by Grant »

I agree with Munk. I believe this VBOX feature request was tossed around in the GNS3 community in the beginning. Their purpose was to allow telneting to virtual networking equipment guests. I can't recall if GNS3 console option requires the VBOX guest to have TCP enabled at the moment though. Anyway... if anyone has a method for telneting to the serial port on a VBOX router guest that would help me greatly.

In the current state I am not able to connect to my VM via the TCP/IP/Serial.

login: admin<cr>
admin <- echo full line text after <cr> above
password: <- bypassed which I assume means \r\n is sent for <cr> above

Authentication failure <- due to empty password above.
login:

As mentioned in a previous post, I have attempted socat and to a name pipe and clean things up a little. I just a router nerd and this is a little beyond by scope.
mpack
Site Moderator
Posts: 39134
Joined: 4. Sep 2008, 17:09
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Mostly XP

Re: Please implement telnet negotiation for serial ports

Post by mpack »

VirtualBox emulates a specific UART that the guest OS has drivers for. If you can point to a UART that implements telnet, and that a typical guest OS has drivers for, then it would certainly advance your cause. I also don't see how Telnet could be attached as a host stream, since Telnet is not a stream.
Grant
Posts: 4
Joined: 13. Mar 2016, 19:33

Re: Please implement telnet negotiation for serial ports

Post by Grant »

I did a little more ready up and the telnet NVT protocol is not truely compatible with the interactive raw TCP socket that VBOX provides. If there is no telnetd to interpret NVT, too many/few "characters" are fowarded through the VBOX raw TCP session to the emulated uart and into the guest OS.

Basically VBOX would almost have to be a telnet terminal server to do this. From an example that I read, a Network Virtual Terminal (NVT telnet) bare carriage return is (CR, ASCII 13) followed by ASCII 0. A raw TCP session will forward both bytes. I suppose ANSI, VT100 or whatever get tripped out by the 0.

I assume this is the implementation in VBOX.

telnet client <--- TCP session on tcp1234 ---> VBOX socket tcp1234 <--- raw data pipe ---> emulated uart <---> Guest OS TTY VT100 shell

Apparently there are telnet clients that can work around this. Windows Putty was one suggestion that I came across. I am using expect with linux telnet.

My understanding at this point is protocol compliant telnet is not supported to a serial port in VBOX.

Apologies if this is all nonsense, but it is the best that I have come up with.
Grant
Posts: 4
Joined: 13. Mar 2016, 19:33

Re: Please implement telnet negotiation for serial ports

Post by Grant »

Use ser2net to handle the telnet daemon portion.

# in /etc/rc.d/rc.local
socat -d -d pty,link=/tmp/td1,raw,echo=0 pty,link=/tmp/vb1,raw,echo=0 &
socat -d -d pty,link=/tmp/td2,raw,echo=0 pty,link=/tmp/vb2,raw,echo=0 &

# ser2net.conf
2001:telnet:0:/tmp/td1:9600
2002:telnet:0:/tmp/td2:9600

vbox config for VM#1
Serial Enabled -> Com1 -> Host Device -> /tmp/vb1 (ignore warning on VM startup)
vbox config for VM#2
Serial Enabled -> Com1 -> Host Device -> /tmp/vb2 (ignore warning on VM startup)

--- telnet 192.168.1.123 2001 connects to VM#1's console with no issues and characters are handled as they should be. (guest VM kernel/OS boots 9600 8n1 VT100... don't know if this matters or not).

Many thanks to everyone who develops and supports VBox.
Post Reply