diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2008-08-28 15:52:29 +0000 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2008-08-28 15:52:29 +0000 |
commit | 1334a93b2718132eaa5689afdb9c2aaae0db3eaa (patch) | |
tree | 4cdcf2da90306064e06a38014b69d057e972f5f1 /mux.c | |
parent | 2c73ed237bc8bdc7829218c6c903200d8d768be1 (diff) | |
download | microcom-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.c | 172 |
1 files changed, 167 insertions, 5 deletions
@@ -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); |