diff --git a/src/syncterm/conn_telnet.c b/src/syncterm/conn_telnet.c
index d2eeee6fba6d41868515157e1d0c250613f60e9a..a6133da58b86d4a23e32063a8c6f25499ed6fef3 100644
--- a/src/syncterm/conn_telnet.c
+++ b/src/syncterm/conn_telnet.c
@@ -2,6 +2,7 @@
 
 /* $Id: conn_telnet.c,v 1.18 2020/05/03 20:12:42 deuce Exp $ */
 
+#include <stdbool.h>
 #include <stdlib.h>
 
 #include "gen_defs.h"
@@ -19,6 +20,65 @@
 
 extern int	telnet_log_level;
 
+/*****************************************************************************/
+// Escapes Telnet IACs in 'inbuf' by doubling the IAC char
+// 'result' may point to either inbuf (if there were no IACs) or outbuf
+// Returns the final byte count of the result
+/*****************************************************************************/
+size_t st_telnet_expand(const uchar* inbuf, size_t inlen, uchar* outbuf, size_t outlen, BOOL expand_cr, uchar** result)
+{
+	static bool last_was_lf = false;
+	BYTE* first_iac = (BYTE*)memchr(inbuf, TELNET_IAC, inlen);
+	BYTE*   first_cr=NULL;
+
+	if (inlen == 0) {
+		if (result != NULL)
+			*result = (uchar *)inbuf;
+		return 0;
+	}
+	if (last_was_lf && inbuf[0] == '\n') {
+		inbuf++;
+		inlen--;
+	}
+	last_was_lf = false;
+	if (expand_cr)
+		first_cr = (BYTE*)memchr(inbuf, '\r', inlen);
+	else
+		last_was_lf = false;
+
+	if (first_iac == NULL && first_cr == NULL) {	/* Nothing to expand */
+		if (result != NULL)
+			*result = (uchar*)inbuf;
+		return inlen;
+	}
+
+	size_t o;
+
+	if(first_iac != NULL && (first_cr == NULL || first_iac < first_cr))
+		o = first_iac - inbuf;
+	else
+		o = first_cr - inbuf;
+	memcpy(outbuf, inbuf, o);
+
+	for (size_t i = o; i < inlen && o < outlen; i++) {
+		if (inbuf[i] == '\n' && last_was_lf)
+			continue;
+		last_was_lf = false;
+		if(inbuf[i] == TELNET_IAC)
+			outbuf[o++] = TELNET_IAC;
+		if(o >= outlen)
+			break;
+		outbuf[o++] = inbuf[i];
+		if(expand_cr && inbuf[i] == '\r' && o < outlen) {
+			last_was_lf = true;
+			outbuf[o++] = '\n'; // See RFC5198
+		}
+	}
+	if(result != NULL)
+		*result = outbuf;
+	return o;
+}
+
 void *telnet_rx_parse_cb(const void *buf, size_t inlen, size_t *olen)
 {
 	// telnet_interpret() can add up to one byte to inbuf ('\r')
@@ -36,7 +96,7 @@ void *telnet_tx_parse_cb(const void *buf, size_t len, size_t *olen)
 	void *ret = malloc(len * 2);
 	void *parsed;
 
-	*olen = telnet_expand(buf, len, ret, len * 2
+	*olen = st_telnet_expand(buf, len, ret, len * 2
 		,telnet_local_option[TELNET_BINARY_TX]!=TELNET_DO, (BYTE **)&parsed);
 
 	if (parsed != ret)