Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Desarrollo de una Herramienta Software para el Acceso a Redes TCP/IP a través de la Red Telefónica Conmutada

Última Actualización: 30 de Junio de 1.996 - Domingo

Capítulo 12:
El Módulo TELNET

El módulo TELNET [RFC854] [RFC855] es el encargado de efectuar una conexión a una máquina remota de tal forma que el ordenador en el que nos encontremos se comporte, desde el punto de vista de la otra computadora, como un terminal. Proporciona un enlace de comunicación bidireccional de ocho bits.

La aplicación más común de este sistema consiste en el acceso a una cuenta de usuario residente en otra máquina, para poder utilizarla sin necesidad de desplazarnos físicamente hasta uno de sus terminales asociados. No obstante el protocolo TELNET resulta, también, extremadamente útil para depurar e, incluso, implementar completamente otros protocolos. Por ejemplo, mientras no se dispone de un cliente POP3 es posible utilizar dicho servicio a través de TELNET, siempre y cuando el usuario en cuestión conozca razonablemente qué debe hacer. Lo mismo ocurre con los protocolos SMTP, IMAP4 y, también, con FTP.

Habitualmente, no obstante, TELNET no suele ser una aplicación típica disponible en los paquetes de software distribuidos por los proveedores de acceso Internet. Ello es debido a que lo normal es que el usuario no disponga de una cuenta explícita en una máquina remota. Tan sólo se mantienen allí su correo, el sistema de NEWS y, en muchos casos, sus páginas WEB. Es por ello por lo que un usuario común no necesita este servicio. Hemos decidido implementar una capa TELNET plenamente funcional dado que el objetivo de este Proyecto consiste en el desarrollo de una herramienta software lo más completa y funcional posible y ya que, por otra parte, hay muchas personas con cuentas de usuario en universidades y demás organizaciones que desean poder acceder a las mismas desde su propio hogar.

Dada la gran variedad de hardware de visualización existente en el mercado, y para evitar problemas de compatibilidad, el protocolo TELNET define un terminal virtual NVT (Network Virtual Terminal) con una serie de funcionalidades que deben cumplir todos los sistemas [RFC854]. No obstante existen multitud de opciones adicionales para poder implementar facilidades añadidas, como el control de los tabuladores, el modo eco, etc. Todo ello hace que el protocolo TELNET sea, al mismo tiempo, uno de los protocolos más simples y más complicados del mundo TCP/IP. Es decir, es relativamente fácil crear una aplicación TELNET sencilla, pero si se desea dotarla de todas las funcionalidades declaradas, el volumen de código fuente y la complejidad del mismo crece de forma notable.

En este proyecto hemos optado por implementar las funcionalidades más comunes y útiles, como el "Go-Ahead" [RFC858] y el "Window Size" [RFC1073]. Adicionalmente, dada la gran difusión del mismo, se decidió implantar también una capa de emulación VT100.


Interfaz

La interfaz de este módulo está constituida por diversos procesos cooperantes y varias rutinas que se ejecutan en el contexto del llamante.


PROC_TELNET_BC

Este proceso es el encargado de inicializar este módulo. Debe ser invocado con un mensaje "MSG_INIT" o "MSG_QUIT". La inicialización de este módulo debe ser posterior a la del módulo TCP.


PROC_TELNET_SUP

Este proceso es el encargado de hacer llegar al extremo remoto la información que deseamos transmitir, así como secuencias de control. Espera recibir diferentes mensajes, con el siguiente formato:

  • MSG_MBUF

    Estos mensajes solicitan el envío de la información indicada al otro extremo.

    campo1: Cadena MBUF conteniendo los datos que queremos transmitir
    campo2: Identificador de la conexión
    campo3: Ignorado

  • MSG_TELNET_IP

    Este mensaje define un mecanismo estándar para que el usuario (o bien otros protocolos que utilicen el TELNET) pueda interrumpir un proceso (IP=Interrupt Process). Su formato es el siguiente:

    campo1: Ignorado
    campo2: Identificador de la conexión
    campo3: Ignorado

    Este formato de mensaje será utilizado también por los siguientes.

  • MSG_TELNET_AO

    Este mensaje define otro mecanismo estándar, esta vez asociado a la salida en pantalla (AO=Abort Output). A través de él se solicita al otro extremo que descarte cualquier salida que todavía reste por enviar.

  • MSG_TELNET_AYT

    Este mensaje (AYT=Are You There?) se utiliza para que el usuario pueda tener una evidencia de que el sistema remoto permanece activo.

  • MSG_TELNET_EC

    Con este mensaje se indica al sistema remoto que debe borrar el último carácter enviado (EC=Erase Character).

  • MSG_TELNET_EL

    Con este mensaje se pide al sistema remoto que borre la última línea introducida (EL=Erase Line).

  • MSG_TELNET_GA

    Con este mensaje se indica al otro extremo que hemos terminado de enviar información, de momento, y que le cedemos la iniciativa. La utilidad de una orden así viene determinada por la existencia de sistemas Half-dúplex que no permiten la transmisión y recepción simultanea. En la actualidad la ventaja de esta función es muy reducida. De hecho el protocolo TELNET implementado negocia, al principio de la conexión, la supresión de esta orden.

  • MSG_TELNET_SYNC

    Este mensaje implementa un mecanismo de escape que indica a la la máquina remota que debe alcanzar, lo antes posible, este punto. Ello se realiza, normalmente, descartando cualquier información que debiera ser visualizada, aunque se gestionan adecuadamente los comandos de control insertados en medio del flujo de datos. Para mejorar aún más la respuesta a este comando se utilizan las facilidades "PUSH" y "MODO_URGENTE" disponibles en la capa TCP.


PROC_TELNET_INF

Este proceso es el encargado de interactuar con el módulo TCP para recibir los datos provenientes del otro extremo. Los mensajes enviados hacia arriba son:

  • MSG_TELNET_OPEN

    Este mensaje se genera para indicar a la capa superior que ha sido aceptado un intento de conexión a una máquina remota. A partir de ese momento la conexión está abierta y lista para aceptar información.

    campo1: Valor indeterminado
    campo2: Identificador de la conexión
    campo3: Valor indeterminado

  • MSG_TELNET_CLOSE

    Este mensaje se genera cuando el otro extremo decide cerrar la conexión TELNET, o bien cuando un intento de conexión es rechazado por la máquina remota. También se produce cuando ocurre cualquier error TCP, como un exceso en el número de reintentos.

    campo1: Valor indeterminado
    campo2: Identificador de la conexión
    campo3: Valor indeterminado

    Este mensaje también se genera cuando somos nosotros quienes pedimos cerrar la conexión. El mensaje se envía cuando la conexión se ha cerrado realmente, no cuando se da la orden.

  • MSG_TELNET_IP
  • MSG_TELNET_AO
  • MSG_TELNET_AYT
  • MSG_TELNET_EC
  • MSG_TELNET_EL
  • MSG_TELNET_GA

    Estos mensajes son generados cuando se recibe el comando correspondiente desde el otro lado. Su formato es idéntico al especificado con anterioridad.

    El mensaje "MSG_TELNET_SYNC" no llega nunca arriba, ya que lo gestiona el módulo TELNET receptor de forma automática. Simplemente descarta todos los datos que se reciban hasta alcanzar el mismo punto que el transmisor. Los comandos y las negociaciones en sí se gestionan de forma normal.

En cuanto a las rutinas, su prototipos son:


void telnet_open(uint32 ip,uint16 puerto,uint32 id,proc_id proc_retorno);

Esta rutina intenta realizar una conexión TELNET al puerto 'puerto' de la máquina 'ip'. 'id' contiene el identificador de la conexión y 'proc_retorno' es el proceso que debe ser informado de todos los eventos y que recibe los datos en sí. Como resultado de esta llamada, el proceso especificado recibirá un mensaje "MSG_TELNET_OPEN" o bien un "MSG_TELNET_CLOSE", según corresponda. Su formato es el declarado anteriormente.

Aunque la conexión puede efectuarse a cualquier puerto "LISTEN" de la máquina destino -por ejemplo, para emular otros protocolos-, el puerto TELNET por defecto se ha definido como "TELNET_PUERTO" (puerto 23).


void telnet_close(uint32 id);

Esta rutina cierra una conexión, especificada según su identificador 'id'. El proceso responsable recibirá un "MSG_TELNET_CLOSE", con el formato habitual, cuando la conexión se cierre finalmente. La semántica de los mensajes pendientes en la cola del dispatcher no está definida. Pueden ser entregados, o bien ignorarse.


estado telnet_flujo(uint32 id,uint16 tamanho);

Esta rutina informa de la posibilidad de enviar nuevos datos a través de una conexión TELNET. La rutina devuelve "FLUJO_LLENO" si el flujo está cerrado, la conexión no está aún establecida, etc., y "OK" si la capa TELNET está dispuesta a aceptar nuevos datos. 'id' es el identificador de la conexión, mientras que 'tamanho' informa del número de bytes que deseamos transmitir. Aún cuando este módulo admite nuevos datos con el control de flujo cerrado, se desaconseja completamente el uso de esta característica. Si en un momento dado el control de flujo está cerrado habrá que reintentarlo de nuevo tras un tiempo prudencial (por ejemplo, una décima de segundo).


void telnet_cerrar_flujo_rx(uint32 id);

Esta rutina solicita a la capa TELNET que detenga la recepción de datos. Cualquier mensaje pendiente se entregará. La utilidad de esta llamada es el cerrar la recepción durante momentos concretos, como por ejemplo si el usuario demanda una congelación de la pantalla. 'id' es el identificador de la conexión.

Esta acción sólo debe solicitarse en casos de necesidad. En [RFC1122] se especifica claramente que debe evitarse su uso en lo posible. Habitualmente existen formas menos agresivas de lograr un efecto equivalente.


void telnet_abrir_flujo_rx(uint32 id);

Esta rutina es la encargada de abrir el control de flujo para que la capa TELNET acepte nuevos datos para la conexión 'id'. Se trata de la función complementaria a la anterior.


Implementación

Como ya se ha comentado con anterioridad el protocolo TELNET es, al mismo tiempo, uno de los más simples y más complicados del mundo TCP/IP. Aún cuando realizar una implantación funcional es relativamente simple [RFC854] [RFC855], en la práctica la necesidad de añadir funcionalidades adicionales supone una carga importante. El esquema de negociación TELNET, siendo a primera vista bastante intuitivo y directo, posee un gran número de matices que hacen necesaria una programación larga, laboriosa y muy proclive a errores [RFC728] [RFC1143].

Las extensiones programadas en la actualidad, al margen de la emulación VT100, son el "Go-Ahead" [RFC858] y el "Window Size" [RFC1073]. Es bastante razonable pensar que a medida que el uso de esta herramienta se popularice y la demanda aumente, se implantarán extensiones adicionales. Aunque muchas de las extensiones estandarizadas están completamente anticuadas en la actualidad (provienen de la época de los teletipos e impresoras), existen algunas cuya inclusión resulta bastante razonable, aunque no se ha hecho por falta de tiempo: eco [RFC857], modo de línea [RFC1184] y autentificación [RFC1416].


Bibliografía


[RFC595]    RFC595: "Second thoughts in defense of the Telnet
            Go-Ahead"
            W. Hathaway
            Diciembre 1.973

[RFC596]    RFC596: "Second thoughts on Telnet Go-Ahead"
            E. Taft
            Diciembre 1.973

[RFC652]    RFC652: "Telnet output carriage-return disposition
            option"
            D. Crocker
            Octubre 1.974

[RFC653]    RFC653: "Telnet output horizontal tabstops option"
            D. Crocker
            Octubre 1.974

[RFC654]    RFC654: "Telnet output horizontal tab disposition option"
            D. Crocker
            Octubre 1.974

[RFC655]    RFC655: "Telnet output formfeed disposition option"
            D. Crocker
            Octubre 1.974

[RFC656]    RFC656: "Telnet output vertical tabstops option"
            D. Crocker
            Octubre 1.974

[RFC657]    RFC657: "Telnet output vertical tab disposition option"
            D. Crocker
            Octubre 1.974

[RFC658]    RFC658: "Telnet output linefeed disposition"
            D. Crocker
            Octubre 1.974

[RFC659]    RFC659: "Announcing additional Telnet options"
            Jon Postel
            Octubre 1.974

[RFC698]    RFC698: "TELNET EXTENDED ASCII OPTION"
            (Autor desconocido)
            Julio 1.975

[RFC726]    RFC726: "Remote Controlled Transmssion and Echoing
            Telnet Option"
            Jon Postel
            Dave Crocker
            Marzo 1.977

[RFC727]    RFC727: "TELNET Logout Option"
            Mark Crispin
            Abril 1.977

[RFC728]    RFC728: "A Minor Pitfall in the Telnet Protocol"
            John Day
            Abril 1.977

[RFC735]    RFC735: "Revised Telnet byte macro option"
            D. Crocker
            R. Gumpertz
            Noviembre 1.977

[RFC736]    RFC736: "Telnet SUPDUP option"
            M. Crispin
            Octubre 1.977

[RFC749]    RFC749: "Telnet SUPDUP-Output option"
            B. Greenberg
            Septiembre 1.978

[RFC748]    RFC748: "Telnet randomly-lose option"
            M. Crispin
            Abril 1.978

[RFC779]    RFC779: "Telnet send-location option"
            E. Killian
            Abril 1.981

[RFC793]    RFC793: "Transport Control Protocol"
            Jon Postel
            Septiembre 1.981

[RFC854]    RFC854: "Telnet Protocol specification"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC855]    RFC855: "Telnet option specifications"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC856]    RFC856: "Telnet binary transmission"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC857]    RFC857: "TELNET ECHO OPTION"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC858]    RFC858: "TELNET SUPPRESS GO AHEAD OPTION"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC859]    RFC859: "Telnet status option"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC860]    RFC860: "TELNET TIMING MARK OPTION"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC861]    RFC861: "Telnet extended options: List option"
            Jon Postel
            Joyce Reynolds
            Mayo 1.983

[RFC885]    RFC885: "Telnet end of record option"
            Jon Postel
            Diciembre 1.983

[RFC927]    RFC927: "TACACS user identification Telnet option"
            B. Anderson
            Diciembre 1.984

[RFC930]    RFC930: "TELNET TERMINAL TYPE OPTION"
            Marvin Sólomon
            Edward Wimmers
            Enero 1.985

[RFC933]    RFC933: "OUTPUT MARKING TELNET OPTION"
            S. Silverman
            Enero 1.985

[RFC946]    RFC946: "Telnet terminal location number option"
            R. Nedved
            Mayo 1.985

[RFC1041]   RFC1041: "Telnet 3270 regime option"
            Y. Rekhter
            Enero 1.988

[RFC1043]   RFC1043: "Telnet Data Entry Terminal option: DODIIS
            implementation"
            A. Yasuda
            T. Thompson
            Febrero 1.988

[RFC1053]   RFC1053: "Telnet X.3 PAD option"
            S. Levy
            T. Jacobson
            Abril 1.988

[RFC1073]   RFC1073: "Telnet Window Size Option"
            D. Waitzman
            Octubre 1.988

[RFC1079]   RFC1079: "Telnet terminal speed option"
            C. Hedrick
            Diciembre 1.988

[RFC1091]   RFC1091: "Telnet Terminal-Type Option"
            James VanBokkelen
            Febrero 1.989

[RFC1096]   RFC1096: "Telnet X display location option"
            G. Marcy
            Marzo 1.989

[RFC1097]   RFC1097: "Telnet subliminal-message option"
            B. Miller
            Abril 1.989

[RFC1123]   RFC1123:"Requirements for Internet Hosts --
            Application and Support"
            Robert Braden
            Octubre 1.989

[RFC1143]   RFC1143: "The Q Method of Implementing TELNET Option
            Negotiation"
            Daniel J. Bernstein
            Febrero 1.990

[RFC1184]   RFC1184: "Telnet Linemode Option"
            David A. Borman
            Octubre 1.990

[RFC1205]   RFC1205: "5250 Telnet Interface"
            P. Chmielewski
            Febrero 1.991

[RFC1372]   RFC1372: "Telnet Remote Flow Control Option"
            David Borman
            Charles Hedrick
            Octubre 1.992

[RFC1411]   RFC1411: "Telnet Authentication: Kerberos Version 4"
            David Borman
            Enero 1.993

[RFC1412]   RFC1412: "Telnet Authentication : SPX"
            K. Alagappan
            Enero 1.993

[RFC1416]   RFC1416: "Telnet Authentication Option"
            David Borman
            Febrero 1.993

[RFC1571]   RFC1571: "Telnet Environment Option Interoperability
            Issues"
            David Borman
            Enero 1.994

[RFC1572]   RFC1572: "Telnet Environment Option"
            Steve Alexander
            Enero 1.994

[TELEVIDEO] Televideo 9320 Operator's Manual
            Junio 1.988



Python Zope ©1996 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS