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.