dest-unreach / socat / contrib / rfc2217
RFC 2217 describes an extension to the telnet protocol that specifies transfer of serial line parameters like baud rate and parity over the network.
Kenneth Kassing contributed a patch to socat that adds support for RFC 2217 controls on a tty/pty and that allows to synchronize the attributes of two tty/pty devices locally or on different hosts.
Apply this patch to socat 1.6.0.0 source.
socat-1.6.0.0-rfc2217.patch.gz
Alternatively, this patch is available as branch socat-rfc2217 in git://repo.or.cz/socat.git and http://repo.or.cz/r/socat.git.
While this contribution adds an extremely useful feature, it does not fit well socat's modulare concept. Therefore there are currently no plans to directly integrate it into socat mainstream; parts of it might, however, be reused for a better conforming solution.
In the file download, documentation of the new features is described in the man page socat.1 only.
Hi Gerhard,
Thanks for your response and suggestions. I have made some updates to
reflect your suggestions.
Attached is an initial patch to socat 1.6.0.0 to support the features I
mentioned in my previous email. Additionally, I have included a change
log below. I have done some extensive testing to the code I added, but
I expect I may find some bugs in the next few weeks and I will send
further updates if I do.
I would like very much to see these updates make it into upcoming
releases, and I am willing to assist you with supporting them.
Thanks
Ken Kassing
CHANGELOG
----------------
* Update doc/socat.1, EXAMPLES
* Add documentation and examples for the TELNET/RF2217 features
* Update Makefile.in, configure.in, configure, config.h.in
* Modify build logic to support the TELNET/RF2217 features
* Update socat.c
* Add '-p- command line option to support continually polling the
sockets for updates to the TERMIOS structure
* Add call to 'termios_updatePorts' in the transfer loop. This will
check for changes to the TERMIOS structure for both sockets and update
them as needed.
* Update xio-openssl.h and xio-openssl.c
* Make 'xioopen_openssl_connect' and 'xioopen_openssl_listen'
functions externally linkable
* Update xio-termios.h, xio-termios.c, xioopts.h, and xioopts.c
* Add 'control', 'read' and 'nomodem' options
* Update xio.h
* Add XIOREAD_TELNET, XIOWRITE_TELNET, and XIODATA_TELNET
* Add termios control structure
* Add telnet control structure
* Update xioread.c and xiowrite.c
* Add support for XIOREAD_TELNET and XIOWRITE_TELNET
* Update xioopen.c
* Add TELNET, TELNET-LISTEN, TELNET-SSL, and TELNET-SSL-LISTEN address
variants
* Add termioscls.h and termioscls.c
* Utility calls that handle the TERMIOS structure operations
* Add xio-telnet.h and xio-telnet.h
* Defines the XIO functions that supports the telnet address types
* Handle the telnet options (including the RFC2217 extension)
Gerhard Rieger wrote:
> Kenneth Kassing wrote:
>> Hello,
>> I am working on making some updates to socat that primarily involve
>> adding a new address type, but also include adding a couple options to
>> the TERMIOS option group.
>>
>> The address type I am adding is an implementation of RFC2217 Telnet Com
>> Port Control Option. This is basically an extension to telnet that
>> allows baud rate, parity, etc to transmitted to the remote server.
>>
>> The most common application for this will be to redirect a com port on
>> one device to another device. This will involve a socat instance
>> running on each device.
>>
>> The server device will bind to the physical tty, and listen on a TCP
>> port. The second device will connect to the remote TCP port, and create
>> a pseudo tty. The end goal of this setup will allow programs running
>> locally (ie.. minicom, kermit, or stty) to change the baud rate of the
>> pseudo tty and have the change propagate to the real tty on the remote
>> device.
>>
>> To actually accomplish this propagation, I added two options to the
>> TERMIOS option group ("control" and "read"). In addition I added a
>> function call to the data loop that will check for updates to the
>> termios structure and propagate them. These options allow a user to
>> seperately enable the system to read termios changes or write them back
>> to the address type. (NOTE: Control assumes read.)
>>
>> Usage/Testing examples:
>>
>> Here is an example that tests the termios prorogation code for a simple
>> case. This is probably not a real usage case for socat.
>>
>> # socat -T 5 -R PTY,link=/dev/ttyR0,raw,group=dialout,mode=660,control
>> PTY,link=/dev/ttyR1,raw,group=dialout,mode=660,control
>> # stty -F /dev/ttyR0 speed; stty -F /dev/ttyR1 speed
>> 38400
>> 38400
>> # stty -F /dev/ttyR0 19200
>> # stty -F /dev/ttyR0 speed; stty -F /dev/ttyR1 speed
>> 19200
>> 19200
>>
>> NOTE: I added the "-R" option to prevent socat from exiting after the
>> idle timeout, so the option string "-T 5 -R" will cause socat to repeat
>> the data loop every 5 seconds. I do this mainly for testing purposes
>> so it will read and propagate the termios changes without any data being
>> transmitted.
>>
>>
>> Here is an example of starting the RCF2217 server
>>
>> # socat -T 5 -R telnet-listen:30000,fork /dev/ttyS0,raw,echo=0,control
>>
>>
>> Here is an example of starting the RCF2217 client
>>
>> # socat -T 5 -R PTY,link=/dev/ttyR0,raw,group=dialout,mode=660,read
>> telnet:localhost:30000
>>
>>
>>
>>
>>
>>
>> I have a couple questions I would like your opinion on.
>>
>> 1. The only way I have found so far to collect the termios information
>> is to poll it from the data loop. (Ie... With the Tcgetattr function.)
>> Currently I am using the global timer option to cause the data loop to
>> escape and read the termios info. This may not be required in the
>> normal case where data is passed regularly. (I added a command line
>> option that prevents the -T option from exiting.) Are you aware of a
>> better method for this?
> I recommend that you check how the ignoreeof option performs polls in
> the transfer loop; this would keep the -T for its original purpose.
>> 2. The RFC2217 is basically a RAW TCP connection that internally escapes
>> some data. Because of this, I am calling 'xioopen_ipapp_connect' and
>> 'xioopen_ipapp_listen' from my respective connect and listen functions.
>> I did this to avoid recoding all the TCP stuff in the hopes that it
>> would help keep the code more maintainable in the future. Do you have
>> any issues with this approach?
> Using these functions is the best way to implement TCP or UDP based
> addresses in socat - but see below.
>> 3. I intend use the OpenSSL functions in the same way I used TCP above.
>> Do you have any issues with this approach?
> See answer below.
>> 4. Have you considered devising an API that would allow address types to
>> wrap some other object like item #2 and #3? I see potential for
>> wrapping other higher layer protocols in a similar manner.
> Yes, I am currently extending socat to support invocations like these:
>
> socat stdio 'ssl|proxy:...|tcp:host:port'
>
> or:
>
> socat tcp-l:port,fork 'ssl-l,cert=...|exec:script'
>
> which means that bidirectional pipes will be possible in socat.
> For your work I recommend that you strictly separate the telnet protocol
> from TCP. I think the best aproach would be to derive the TELNET address
> from the PTY address or the OPEN address with TERMIOS support; this will
> give it direct access to the pty/tty, while the networking part can be
> fulfilled by already existing addresses.