コード例 #1
0
static void handlenetinput(int len)
{
	int i;
	int cstart = 0;

	for (i = 0; i < len; i++)
	{
		byte c = G.buf[i];

		if (G.telstate == 0) /* most of the time state == 0 */
		{
			if (c == IAC)
			{
				cstart = i;
				G.telstate = TS_IAC;
			}
		}
		else
			switch (G.telstate)
			 {
			 case TS_0:
				 if (c == IAC)
					 G.telstate = TS_IAC;
				 else
					 G.buf[cstart++] = c;
				 break;

			 case TS_IAC:
				 if (c == IAC) /* IAC IAC -> 0xFF */
				 {
					 G.buf[cstart++] = c;
					 G.telstate = TS_0;
					 break;
				 }
				 /* else */
				 switch (c)
				 {
				 case SB:
					 G.telstate = TS_SUB1;
					 break;
				 case DO:
				 case DONT:
				 case WILL:
				 case WONT:
					 G.telwish =  c;
					 G.telstate = TS_OPT;
					 break;
				 default:
					 G.telstate = TS_0;	/* DATA MARK must be added later */
				 }
				 break;
			 case TS_OPT: /* WILL, WONT, DO, DONT */
				 telopt(c);
				 G.telstate = TS_0;
				 break;
			 case TS_SUB1: /* Subnegotiation */
			 case TS_SUB2: /* Subnegotiation */
				 if (subneg(c))
					 G.telstate = TS_0;
				 break;
			 }
	}
	if (G.telstate)
	{
		if (G.iaclen)			iacflush();
		if (G.telstate == TS_0)	G.telstate = 0;

		len = cstart;
	}

	if (len)
		write(1, G.buf, len);
}
コード例 #2
0
ファイル: telnet.c プロジェクト: Drakey83/steamlink-sdk
static void handle_net_input(int len)
{
	int i;
	int cstart = 0;

	for (i = 0; i < len; i++) {
		byte c = G.buf[i];

		if (G.telstate == TS_NORMAL) { /* most typical state */
			if (c == IAC) {
				cstart = i;
				G.telstate = TS_IAC;
			}
			else if (c == '\r') {
				cstart = i + 1;
				G.telstate = TS_CR;
			}
			/* No IACs were seen so far, no need to copy
			 * bytes within G.buf: */
			continue;
		}

		switch (G.telstate) {
		case TS_CR:
			/* Prev char was CR. If cur one is NUL, ignore it.
			 * See RFC 1123 section 3.3.1 for discussion of telnet EOL handling.
			 */
			G.telstate = TS_COPY;
			if (c == '\0')
				break;
			/* else: fall through - need to handle CR IAC ... properly */

		case TS_COPY: /* Prev char was ordinary */
			/* Similar to NORMAL, but in TS_COPY we need to copy bytes */
			if (c == IAC)
				G.telstate = TS_IAC;
			else
				G.buf[cstart++] = c;
			if (c == '\r')
				G.telstate = TS_CR;
			break;

		case TS_IAC: /* Prev char was IAC */
			if (c == IAC) { /* IAC IAC -> one IAC */
				G.buf[cstart++] = c;
				G.telstate = TS_COPY;
				break;
			}
			/* else */
			switch (c) {
			case SB:
				G.telstate = TS_SUB1;
				break;
			case DO:
			case DONT:
			case WILL:
			case WONT:
				G.telwish = c;
				G.telstate = TS_OPT;
				break;
			/* DATA MARK must be added later */
			default:
				G.telstate = TS_COPY;
			}
			break;

		case TS_OPT: /* Prev chars were IAC WILL/WONT/DO/DONT */
			telopt(c);
			G.telstate = TS_COPY;
			break;

		case TS_SUB1: /* Subnegotiation */
		case TS_SUB2: /* Subnegotiation */
			subneg(c); /* can change G.telstate */
			break;
		}
	}

	if (G.telstate != TS_NORMAL) {
		/* We had some IACs, or CR */
		if (G.iaclen)
			iac_flush();
		if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */
			G.telstate = TS_NORMAL;
		len = cstart;
	}

	if (len)
		full_write(STDOUT_FILENO, G.buf, len);
}