Esempio n. 1
0
static
void telnet_process_request (char_tcp_t *drv, unsigned option)
{
	unsigned st;

	st = drv->telnet_state;

	switch (option) {
	case TELNET_OPT_BINARY:
		if ((st == CHAR_TCP_DO) || (st == CHAR_TCP_DONT)) {
			/* We insist on being binary. */
			telnet_will (drv, TELNET_OPT_BINARY);
		}
		else if ((st == CHAR_TCP_WILL) || (st == CHAR_TCP_WONT)) {
			/* We insist on being binary. */
			telnet_do (drv, TELNET_OPT_BINARY);
		}
		return;

	case TELNET_OPT_ECHO:
		if (st == CHAR_TCP_WILL) {
			/* We refuse that the client performs echoing itself. */
			telnet_dont (drv, TELNET_OPT_ECHO);
		}
		else if (st == CHAR_TCP_DONT) {
			/* We insist on echoing. */
			telnet_will (drv, TELNET_OPT_ECHO);
		}
		return;

	case TELNET_OPT_SUPPRESS_GO_AHEAD:
		if (st == CHAR_TCP_DONT) {
			/* We will never send go-aheads. */
			telnet_will (drv, TELNET_OPT_SUPPRESS_GO_AHEAD);
		}
		else if ((st == CHAR_TCP_WILL) || (st == CHAR_TCP_WONT)) {
			/* The client may or may not suppress go-aheads at its own
			 * volition. */
			telnet_send_request (drv, TELNET_OPT_SUPPRESS_GO_AHEAD,
				(st == CHAR_TCP_WILL) ? CHAR_TCP_DO : CHAR_TCP_DONT
			);
		}
		return;

	default:
		/* unknown option, refuse it. */
		telnet_send_request (drv, option,
			(st == CHAR_TCP_WILL) ? TELNET_DONT : TELNET_WONT
		);
	}
}
Esempio n. 2
0
/*
 * Perform Telnet protocol processing, copying the contents of the raw input
 * queue to the canonical queue.
 */
static void
telnet_input(telnet_t *tp)
{
    u_char c;
    while (!nq_empty(tp->t_rawq))
    {
        c = nq_getc(tp->t_rawq);

	switch (tp->t_state)
	{
	case TS_DATA:
            switch (c)
            {
	    case NUL:
		break;

            case BS:
		telnet_ec(tp);
                break;

	    case LF:
		telnet_eol(tp);
                return;
                
            case CR:
                tp->t_state = TS_CR;
                break;

            case DEL:
		telnet_ec(tp);
                break;

            case IAC:
                tp->t_state = TS_IAC;
                break;

            default:
		telnet_canq_putc(tp, c);
                break;
            }
	    break;

	case TS_CR:
	    telnet_eol(tp);
            tp->t_state = TS_DATA;
            return;

	case TS_IAC:
            tp->t_state = TS_DATA;
            switch (c)
            {
            case DM:
		telnet_dm(tp);
                break;

	    case AYT:
		telnet_ayt(tp);
		break;

	    case EC:
		telnet_ec(tp);
		break;

	    case EL:
		telnet_el(tp);
		break;

            case SB:
                tp->t_state = TS_IAC_SB;
                break;

            case WILL:
                tp->t_state = TS_IAC_WILL;
                break;

            case WONT:
                tp->t_state = TS_IAC_WONT;
                break;

            case DO:
                tp->t_state = TS_IAC_DO;
                break;

            case DONT:
                tp->t_state = TS_IAC_DONT;
                break;

            case IAC:
		telnet_canq_putc(tp, c);
		break;
            }
	    break;

	case TS_IAC_SB:
	    telnet_sb(tp, c);
            tp->t_state = TS_IAC_SB_DATA;
	    break;

	case TS_IAC_SB_DATA:
            switch (c)
            {
            case IAC:
                tp->t_state = TS_IAC_SB_IAC;
                break;

            default:
		telnet_optq_putc(tp, c);
                break;
            }
	    break;

	case TS_IAC_SB_IAC:
	    tp->t_state = TS_IAC_SB_DATA;
            switch (c)
            {
            case SE:
                telnet_se(tp);
                tp->t_state = TS_DATA;
                break;

            case IAC:
		telnet_optq_putc(tp, c);
                break;
            }
	    break;

	case TS_IAC_WILL:
            telnet_will(tp, c);
	    tp->t_state = TS_DATA;
	    break;

	case TS_IAC_WONT:
            telnet_wont(tp, c);
            tp->t_state = TS_DATA;
	    break;

	case TS_IAC_DO:
	    telnet_do(tp, c);
            tp->t_state = TS_DATA;
	    break;

	case TS_IAC_DONT:
            telnet_dont(tp, c);
            tp->t_state = TS_DATA;
	    break;
        }
    }

    if ((tp->t_flags & (TF_SGA | TF_GA)) == 0)
    {
	if (nq_avail(tp->t_outq) >= 2)
	{
	    tp->t_flags |= TF_GA;
	    telnet_send_ga(tp);
	}
    }

    nq_init(tp->t_rawq);
}