summaryrefslogtreecommitdiffstats
path: root/mux.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-08-28 15:52:29 +0000
committerSascha Hauer <s.hauer@pengutronix.de>2008-08-28 15:52:29 +0000
commit1334a93b2718132eaa5689afdb9c2aaae0db3eaa (patch)
tree4cdcf2da90306064e06a38014b69d057e972f5f1 /mux.c
parent2c73ed237bc8bdc7829218c6c903200d8d768be1 (diff)
downloadmicrocom-1334a93b2718132eaa5689afdb9c2aaae0db3eaa.tar.gz
microcom-1334a93b2718132eaa5689afdb9c2aaae0db3eaa.tar.xz
implement telnet rfc2217 mode (experimental), update help
git-svn-id: https://svn.pengutronix.de/svn/microcom/trunk@6 b6a597e7-0b13-0410-876a-e2d53f4c184b
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c172
1 files changed, 167 insertions, 5 deletions
diff --git a/mux.c b/mux.c
index 8b3242b..15ca435 100644
--- a/mux.c
+++ b/mux.c
@@ -18,6 +18,7 @@
** Rev. 1.0 - Feb. 2000
****************************************************************************/
#include "microcom.h"
+#include <arpa/telnet.h>
#define SCRIPT_DELAY 1
#define BUFSIZE 1024
@@ -25,14 +26,172 @@
extern int dolog;
extern FILE *flog;
+int do_com_port_option(unsigned char *buf, int len)
+{
+ int i = 0;
+
+ while (i < len) {
+ switch (buf[i]) {
+ case IAC:
+ dprintf("IAC ");
+ return i + 1;
+ case SET_BAUDRATE_CS:
+ dprintf("SET_BAUDRATE_CS ");
+ break;
+ case SET_DATASIZE_CS:
+ dprintf("SET_DATASIZE_CS ");
+ break;
+ case SET_PARITY_CS:
+ dprintf("SET_PARITY_CS ");
+ break;
+ case SET_STOPSIZE_CS:
+ dprintf("SET_STOPSIZE_CS ");
+ break;
+ case SET_CONTROL_CS:
+ dprintf("SET_CONTROL_CS ");
+ break;
+ case NOTIFY_LINESTATE_CS:
+ dprintf("NOTIFY_LINESTATE_CS ");
+ break;
+ case NOTIFY_MODEMSTATE_CS:
+ dprintf("NOTIFY_MODEMSTATE_CS ");
+ break;
+ case FLOWCONTROL_SUSPEND_CS:
+ dprintf("FLOWCONTROL_SUSPEND_CS ");
+ break;
+ case FLOWCONTROL_RESUME_CS:
+ dprintf("FLOWCONTROL_RESUME_CS ");
+ break;
+ case SET_LINESTATE_MASK_CS:
+ dprintf("SET_LINESTATE_MASK_CS ");
+ break;
+ case SET_MODEMSTATE_MASK_CS:
+ dprintf("SET_MODEMSTATE_MASK_CS ");
+ break;
+ case PURGE_DATA_CS:
+ dprintf("PURGE_DATA_CS ");
+ break;
+ case SET_BAUDRATE_SC:
+ dprintf("SET_BAUDRATE_SC %d ", ntohl(*(int *)&buf[i + 1]));
+ i += 4;
+ break;
+ case SET_DATASIZE_SC:
+ dprintf("SET_DATASIZE_SC ");
+ break;
+ case SET_PARITY_SC:
+ dprintf("SET_PARITY_SC ");
+ break;
+ case SET_STOPSIZE_SC:
+ dprintf("SET_STOPSIZE_SC ");
+ break;
+ case SET_CONTROL_SC:
+ i++;
+ dprintf("SET_CONTROL_SC 0x%02x ", buf[i]);
+ break;
+ case NOTIFY_LINESTATE_SC:
+ dprintf("NOTIFY_LINESTATE_SC ");
+ break;
+ case NOTIFY_MODEMSTATE_SC:
+ i++;
+ dprintf("NOTIFY_MODEMSTATE_SC 0x%02x ", buf[i]);
+ break;
+ case FLOWCONTROL_SUSPEND_SC:
+ dprintf("FLOWCONTROL_SUSPEND_SC ");
+ break;
+ case FLOWCONTROL_RESUME_SC:
+ dprintf("FLOWCONTROL_RESUME_SC ");
+ break;
+ case SET_LINESTATE_MASK_SC:
+ dprintf("SET_LINESTATE_MASK_SC ");
+ break;
+ case SET_MODEMSTATE_MASK_SC:
+ dprintf("SET_MODEMSTATE_MASK_SC ");
+ break;
+ case PURGE_DATA_SC:
+ dprintf("PURGE_DATA_SC ");
+ break;
+ default:
+ dprintf("%d ", buf[i]);
+ break;
+ }
+ i++;
+ }
+
+ return len;
+}
+
+int do_subneg(unsigned char *buf, int len)
+{
+ int i = 0;
+
+ while (i < len) {
+ switch (buf[i]) {
+ case COM_PORT_OPTION:
+ dprintf("COM_PORT_OPTION ");
+ return do_com_port_option(&buf[i + 1], len - i) + 1;
+ case IAC:
+ dprintf("IAC ");
+ return len - i;
+ default:
+ dprintf("%d ", buf[i]);
+ break;
+ }
+ i++;
+ }
+
+ return len;
+}
+
+int handle_command(unsigned char *buf, int len)
+{
+ int i = 0, a;
+
+ while (i < len) {
+ switch (buf[i]) {
+ case SB:
+ dprintf("SB ");
+ i += do_subneg(&buf[i+1], len - i);
+ break;
+ case IAC:
+ dprintf("IAC ");
+ break;
+ case COM_PORT_OPTION:
+ dprintf("COM_PORT_OPTION ");
+ break;
+ case SE:
+ dprintf("SE ");
+ break;
+ case WILL:
+ dprintf("WILL ");
+ break;
+ case WONT:
+ dprintf("WILL ");
+ break;
+ case DO:
+ dprintf("WILL ");
+ break;
+ case DONT:
+ dprintf("WILL ");
+ break;
+ default:
+ dprintf("%d ", buf[i]);
+ break;
+ }
+ i++;
+ }
+
+ dprintf("\n");
+ return len;
+}
+
/* main program loop */
void
mux_loop(int pf)
{
fd_set ready; /* used for select */
- int i = 0; /* used in the multiplex loop */
+ int i = 0, len; /* used in the multiplex loop */
int done = 0;
- char buf[BUFSIZE];
+ unsigned char buf[BUFSIZE];
struct timeval tv;
tv.tv_sec = SCRIPT_DELAY;
@@ -46,10 +205,13 @@ mux_loop(int pf)
select(pf + 1, &ready, NULL, NULL, NULL);
if (FD_ISSET(pf, &ready)) {
+ i = 0;
/* pf has characters for us */
- i = read(pf, buf, BUFSIZE);
- if (i > 0) {
- write(STDOUT_FILENO, buf, i);
+ len = read(pf, buf, BUFSIZE);
+ if (len > 0) {
+ if (*buf == IAC)
+ i = handle_command(buf, len);
+ write(STDOUT_FILENO, buf + i, len - i);
if (dolog) {
fwrite(buf, 1, i, flog);
fflush(flog);