Beispiel #1
0
/*
 * Read data from the Telnet session to the raw input queue.
 */
static void
telnet_read(ndesc_t *nd, telnet_t *tp)
{
    int cc;

    if (!nq_full(tp->t_rawq))
    {
	if (tp->t_flags & TF_URGENT)
	{
	    if (at_mark(nd_fd(nd)))
	    {
		tp->t_flags &= ~TF_URGENT;
		nd_enable(nd, ND_X);
	    }
	}

        cc = nq_recv(tp->t_rawq, nd_fd(nd), &tp->t_rblen);
        if (cc == -1)
        {
            switch (errno)
            {
            case EWOULDBLOCK:
            case EINTR:
            case EPROTO:
                break;

            default:
		telnet_disconnect(tp);
                return;
            }
        }

	if (cc == 0)
	{
	    telnet_disconnect(tp);
	    return;
	}

	if ((tp->t_flags & TF_FLOWC) == 0)
	    nd_enable(nd, ND_C);

	telnet_enabr(tp);

	if (!nq_full(tp->t_rawq))
	    return;
    }

    tp->t_flags |= TF_ENABR;
    nd_disable(nd, ND_R);
}
Beispiel #2
0
/*
 * Accept a new Telnet connection.
 */
static void
telnet_accept(void *vp)
{
    ndesc_t *nd = vp;
    int addrlen, s;
    struct sockaddr_in addr;
    telnet_t *tp;
    void *ip;

    nd_enable(nd, ND_R);
    
    addrlen = sizeof (addr);
    s = accept(nd_fd(nd), (struct sockaddr *)&addr, &addrlen);
    if (s == -1)
    {
	switch (errno)
	{
	default:
            warning("telnet_accept: accept() errno = %d. ip: %s\n",
                errno, inet_ntoa(addr.sin_addr));
	case EWOULDBLOCK:
	case EINTR:
	case EPROTO:
	    return;
	}
    }

    enable_nbio(s);
    enable_oobinline(s);
    enable_nodelay(s);
    enable_lowdelay(s);
    enable_keepalive(s);
    set_rcvsize(s, TELNET_RCVBUF_SIZE);
    set_sndsize(s, TELNET_SNDBUF_SIZE);

    tp = telnet_alloc();
    tp->t_nd = nd_attach(s, telnet_read, telnet_write, telnet_exception,
			 NULL, telnet_shutdown, tp);
    ip = (void *)new_player(tp, &addr, addrlen);
    if (ip == NULL)
    {
	telnet_shutdown(tp->t_nd, tp);
    }
    else
    {
	telnet_attach(tp, ip);
	nd_enable(tp->t_nd, ND_R | ND_X);
    }
}
Beispiel #3
0
static void
udpsvc_process(udpsvc_t *svc)
{
    int addrlen, cc;
    struct sockaddr_in addr;
    struct gdexception exception_frame;
    
    update_udp_av();

    exception_frame.e_exception = exception;
    exception_frame.e_catch = 0;

    exception = &exception_frame;

    
    if (setjmp(exception_frame.e_context) == 0)
    {
	push_string(inet_ntoa(addr.sin_addr), STRING_MSTRING);
	push_string((char *)nq_rptr(svc->nq), STRING_MSTRING);
	(void)apply_master_ob(M_INCOMING_UDP, 2);
    }
    exception = exception->e_exception;
    addrlen = sizeof (addr);

    if (!read_datagram(svc)) {
	nd_enable(svc->nd, ND_R);
	svc->task = 0;
	return;
    }
    reschedule_task(svc->task);
}
Beispiel #4
0
/*
 * Re-enable the output queue (if blocked).
 */
static void
telnet_enabw(telnet_t *tp)
{
    if (tp->t_flags & TF_ENABW)
    {
	tp->t_flags &= ~TF_ENABW;
	nd_enable(tp->t_nd, ND_W);
    }
}
Beispiel #5
0
/*
 * Re-enable raw queue (if blocked).
 */
static void
telnet_enabr(telnet_t *tp)
{
    if (tp->t_flags & TF_ENABR)
    {
	tp->t_flags &= ~TF_ENABR;
	nd_enable(tp->t_nd, ND_R);
    }
}
Beispiel #6
0
static void
telnet_interactive(void *vp)
{
    telnet_t *tp = vp;
    char *cp;
    
    if (!(tp->t_flags & TF_ATTACH)) {
	tp->task = NULL;
	telnet_shutdown(tp->t_nd, tp);
	return;
    }
    if (tp->t_flags & TF_DISCONNECT) {
	tp->t_flags &= ~TF_DISCONNECT;
	if (tp->t_ip)
	    remove_interactive(tp->t_ip, 1);
    }
    if (!(tp->t_flags & TF_ATTACH)) {
	tp->task = NULL;
	telnet_shutdown(tp->t_nd, tp);
	return;
    }
    if (tp->t_flags & TF_OVFLOUTQ) {
	tp->task = NULL;
	return;
    }
    if (tp->t_flags & TF_INPUT) {
	tp->t_flags &= ~TF_INPUT;
	if (nq_full(tp->t_canq))
	    cp = "";
	else
	    cp = (char *)nq_rptr(tp->t_canq);
	interactive_input(tp->t_ip, cp);
	nq_init(tp->t_canq);
    }
    if (!(tp->t_flags & TF_ATTACH)) {
	tp->task = NULL;
	telnet_shutdown(tp->t_nd, tp);
	return;
    }
    tp->t_flags &= ~TF_GA;
    telnet_readbytes(tp->t_nd, tp);
    telnet_input(tp);
    if (!(tp->t_flags & TF_ATTACH)) {
	tp->task = NULL;
	telnet_shutdown(tp->t_nd, tp);
	return;
    }
    if (tp->t_flags & (TF_INPUT|TF_DISCONNECT)) {
	reschedule_task(tp->task);
	return;
    }
    tp->task = NULL;
    nd_enable(tp->t_nd, ND_R);
}
Beispiel #7
0
/*
 * Disassociate a Telnet control block from an interactive object.
 */
void
telnet_detach(telnet_t *tp)
{
    if ((tp->t_flags & TF_ATTACH) == 0)
	return;

    tp->t_flags ^= TF_ATTACH;
    tp->t_ip = NULL;

    nd_enable(tp->t_nd, ND_C);
}
Beispiel #8
0
/*
 * Write data from the output queue to the Telnet session.
 */
static void
telnet_write(ndesc_t *nd, telnet_t *tp)
{
    if (!nq_empty(tp->t_outq))
    {
	if (nq_send(tp->t_outq, nd_fd(nd), &tp->t_sblen) == -1)
	{
	    switch (errno)
	    {
	    case EWOULDBLOCK:
	    case EINTR:
	    case EPROTO:
		break;

	    default:
		telnet_disconnect(tp);
		return;
	    }
	}
    }

    if (tp->t_flags & TF_OVFLOUTQ)
    {
	if (nq_len(tp->t_outq) < TELNET_OUTQ_LOWAT)
	{
	    tp->t_flags &= ~TF_OVFLOUTQ;
	    nq_puts(tp->t_outq, (u_char *)"*** Truncated. ***\r\n");
	}
    }

    if (tp->t_flags & TF_FLOWC)
    {
	if (nq_len(tp->t_outq) < TELNET_OUTQ_HIWAT)
	{
	    tp->t_flags &= ~TF_FLOWC;
	    nd_enable(nd, ND_C);
	}
    }

    if (!nq_empty(tp->t_outq))
	return;

    nq_init(tp->t_outq);

    tp->t_flags |= TF_ENABW;
    nd_disable(nd, ND_W);
}
Beispiel #9
0
/*
 * Initialize the UDP Manager.
 */
udpsvc_t *
udpsvc_init(int port)
{
    int s;
    struct sockaddr_in addr;
    struct udpsvc_t *svc;
    
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (s == -1)
	fatal("udp_init: socket() error = %d.\n", errno);

    enable_reuseaddr(s);

    memset(&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons((u_short)port);
    addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(s, (struct sockaddr *)&addr, sizeof (addr)) == -1)
    {
	if (errno == EADDRINUSE) 
	{
	    (void)fprintf(stderr, "UDP Socket already bound!\n");
	    debug_message("UDP Socket already bound!\n");
	    (void)close(s);
	    return 0;
	} 
	else 
	{
	    fatal("udp_init: bind() error = %d.\n", errno);
	}
    }

    enable_nbio(s);
    svc = xalloc(sizeof(*udpsvc));
    svc->nq = nq_alloc(UDPSVC_RAWQ_SIZE);
    svc->nd = nd_attach(s, udpsvc_read, NULL, NULL, NULL, udpsvc_shutdown,
			svc);
    nd_enable(svc->nd, ND_R);
    return svc;
}
Beispiel #10
0
/*
 * Initialize the Telnet server.
 */
void
telnet_init(u_short port)
{
    int s;
    struct sockaddr_in addr;
    ndesc_t *nd;

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == -1)
	fatal("telnet_init: socket() error = %d.\n", errno);

    enable_reuseaddr(s);

    memset(&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(s, (struct sockaddr *)&addr, sizeof (addr)) == -1)
    {
	if (errno == EADDRINUSE)
	{
	    (void)fprintf(stderr, "Socket already bound!\n");
	    debug_message("Socket already bound!\n");
	    exit(errno);
	}
	else
	{
	    fatal("telnet_init: bind() error = %d.\n", errno);
	}
    }

    if (listen(s, 5) == -1)
	fatal("telnet_init: listen() error = %d.\n", errno);

    enable_nbio(s);

    nd = nd_attach(s, telnet_ready, NULL, NULL, NULL, telnet_shutdown,
		   NULL);
    nd_enable(nd, ND_R);
}
Beispiel #11
0
/*
 * Re-enable the output queue (if blocked).
 */
static void
telnet_enabw(telnet_t *tp)
{
    nd_enable(tp->t_nd, ND_W);
}