# Module Telnet_client

    module Telnet_client: sig .. end

Telnet client

This is a Telnet client providing the basic Telnet services. It supports sending and receiving data (asynchronously), and the negotiation of Telnet options, but it does not implement any option.

    exception Telnet_protocol of exn

Wrapper for exceptions that already passed the exception handler.

    type telnet_command =

`|` | `Telnet_data of `string`` | `(*` | User data | `*)`
`|` | `Telnet_nop` | `(*` | No operation | `*)`
`|` | `Telnet_dm` | `(*` | data mark | `*)`
`|` | `Telnet_brk` | `(*` | break | `*)`
`|` | `Telnet_ip` | `(*` | interrupt process | `*)`
`|` | `Telnet_ao` | `(*` | abort output | `*)`
`|` | `Telnet_ayt` | `(*` | are you there? | `*)`
`|` | `Telnet_ec` | `(*` | erase character | `*)`
`|` | `Telnet_el` | `(*` | erase line | `*)`
`|` | `Telnet_ga` | `(*` | Go ahead | `*)`
`|` | `Telnet_sb of `char`` | `(*` | Begin of subnegotiation | `*)`
`|` | `Telnet_se` | `(*` | End of subnegotation | `*)`
`|` | `Telnet_will of `char`` | `(*` | Acknowledges that option is in effect | `*)`
`|` | `Telnet_wont of `char`` | `(*` | Acknowledges that option is rejected | `*)`
`|` | `Telnet_do of `char`` | `(*` | Requests to turn on an option | `*)`
`|` | `Telnet_dont of `char`` | `(*` | Requests to turn off an option | `*)`
`|` | `Telnet_unknown of `char`` | `(*` | Unknown command | `*)`
`|` | `Telnet_eof` | `(*` | End of file | `*)`
`|` | `Telnet_timeout` | `(*` | Timeout event | `*)`

A `telnet_command` is the interpretation of the octets in a Telnet session, i.e. it is one level above the octet stream. See RFC 854 for an explanation what the commands mean. `Telnet_data` represents the data chunks between the commands. Note that you do not need to double octets having value 255; this is done automatically. `Telnet_unknown` represents any command not covered by RFC 854, for example the End-of-record-mark (introduced in RFC 885) would be `Telnet_unknown '\239'`. `Telnet_eof` represents the end of the octet stream, useable in both directions. `Telnet_timeout` is added to the input queue if I/O has not been happened for the configured period of time.

    type telnet_options = {

`` | `connection_timeout :`float`;`
`` | `verbose_input :`bool`;`
`` | `verbose_output :`bool`;`

}
`telnet_options`: modifies the behaviour of the client. Do not mix these options up with the options negotiated with the remote side.

- `connection_timeout`: After this period of time (in seconds) a `Telnet_timeout` pseudo-command is added to the input queue, and the connection is aborted.
- `verbose_input`: Enables printing of input events to `Netlog.Debug`.
- `verbose_output`: Enables printing of output events to `Netlog.Debug`

    type telnet_negotiated_option =

`|` | `Telnet_binary` | `(*` | see RFC 856 | `*)`
`|` | `Telnet_echo` | `(*` | see RFC 857 | `*)`
`|` | `Telnet_suppress_GA` | `(*` | see RFC 858 | `*)`
`|` | `Telnet_status` | `(*` | see RFC 859 | `*)`
`|` | `Telnet_timing_mark` | `(*` | see RFC 860 | `*)`
`|` | `Telnet_ext_opt_list` | `(*` | see RFC 861 | `*)`
`|` | `Telnet_end_of_rec` | `(*` | see RFC 885 | `*)`
`|` | `Telnet_window_size` | `(*` | see RFC 1073 | `*)`
`|` | `Telnet_term_speed` | `(*` | see RFC 1079 | `*)`
`|` | `Telnet_term_type` | `(*` | see RFC 1091 | `*)`
`|` | `Telnet_X_display` | `(*` | see RFC 1096 | `*)`
`|` | `Telnet_linemode` | `(*` | see RFC 1184 | `*)`
`|` | `Telnet_flow_ctrl` | `(*` | see RFC 1372 | `*)`
`|` | `Telnet_auth` | `(*` | see RFC 1416 | `*)`
`|` | `Telnet_new_environ` | `(*` | see RFC 1572 and 1571 | `*)`
`|` | `Telnet_option of `int`` | `(*` | all other options | `*)`

`telnet_negotiated_option`: names for the most common options, and the generic name `Telnet_option` for other options.

    type telnet_option_state =

`|` | `Not_negotiated`
`|` | `Accepted`
`|` | `Rejected`

An option has one of three states:

- `Not_negotiated`: There was no negotiation about the option. This means that the option is turned off (but this client is allowed to reject it explicitly)
- `Accepted`: Both sides have accepted the option.
- `Rejected`: One side has rejected the option. This also means that the option is off, but the client refuses to send further acknoledgements that the option is off (to avoid endless negotiation loops).

    val char_of_option : telnet_negotiated_option -> char

Converts the option name to the character representing it on the octet-stream level.

    val option_of_char : char -> telnet_negotiated_option

Converts a character representing an option to the internal option name.

    type telnet_connector =

`|` | `Telnet_connect of `(string * int)``
`|` | `Telnet_socket of `Unix.file_descr``

Connectors:

- `Telnet_connect(host,port)`: The client connects to this port.
- `Telnet_socket s`: The client uses an already connected socket.

Why `Telnet_socket`? Telnet is a symmetrical protocol; client and servers implement the same protocol features (the only difference is the environment: a client is typically connected with a real terminal; a server is connected with a pseudo terminal). This simply means that this implementation of a client can also be used as a server implementation. You need only to add code which accepts new connections and which passes these connections over to a `telnet_session` object via `Telnet_socket`.

    class telnet_session : object .. end

A telnet session

# Debugging

    module Debug: sig .. end