6 * Portable Windows Library
8 * Copyright (c) 1993-2002 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
27 * Revision 1.24 2005/11/30 12:47:37 csoutheren
28 * Removed tabs, reformatted some code, and changed tags for Doxygen
30 * Revision 1.23 2002/11/06 22:47:24 robertj
31 * Fixed header comment (copyright etc)
33 * Revision 1.22 2002/09/16 01:08:59 robertj
34 * Added #define so can select if #pragma interface/implementation is used on
35 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
37 * Revision 1.21 1999/03/09 08:01:47 robertj
38 * Changed comments for doc++ support (more to come).
40 * Revision 1.20 1999/02/16 08:07:10 robertj
41 * MSVC 6.0 compatibility changes.
43 * Revision 1.19 1998/11/30 02:50:56 robertj
44 * New directory structure
46 * Revision 1.18 1998/09/23 06:20:04 robertj
47 * Added open source copyright license.
49 * Revision 1.17 1996/08/08 10:08:54 robertj
50 * Directory structure changes for common files.
52 * Revision 1.16 1995/06/17 11:13:32 robertj
53 * Documentation update.
55 * Revision 1.15 1995/06/17 00:47:38 robertj
56 * Changed overloaded Open() calls to 3 separate function names.
57 * More logical design of port numbers and service names.
59 * Revision 1.14 1995/06/04 12:46:26 robertj
60 * Slight redesign of port numbers on sockets.
62 * Revision 1.13 1995/04/25 11:12:30 robertj
63 * Fixed functions hiding ancestor virtuals.
65 * Revision 1.12 1995/04/01 08:32:10 robertj
66 * Finally got a working TELNET.
68 * Revision 1.11 1995/03/18 06:27:50 robertj
69 * Rewrite of telnet socket protocol according to RFC1143.
71 * Revision 1.10 1995/03/14 12:42:47 robertj
72 * Updated documentation to use HTML codes.
74 * Revision 1.9 1995/02/21 11:25:33 robertj
75 * Further implementation of telnet socket, feature complete now.
77 * Revision 1.8 1995/01/03 09:36:23 robertj
80 * Revision 1.7 1995/01/01 01:07:33 robertj
81 * More implementation.
83 * Revision 1.6 1994/11/28 12:38:59 robertj
84 * Added DONT and WONT states.
86 * Revision 1.5 1994/08/23 11:32:52 robertj
89 * Revision 1.4 1994/08/22 00:46:48 robertj
90 * Added pragma fro GNU C++ compiler.
92 * Revision 1.3 1994/08/21 23:43:02 robertj
93 * Changed type of socket port number for better portability.
95 * Revision 1.2 1994/07/25 03:36:03 robertj
96 * Added sockets to common, normalising to same comment standard.
100 #ifndef _PTELNETSOCKET
101 #define _PTELNETSOCKET
107 #include <ptlib/sockets.h>
110 /** A TCP/IP socket for the TELNET high level protocol.
112 class PTelnetSocket
: public PTCPSocket
114 PCLASSINFO(PTelnetSocket
, PTCPSocket
)
118 // Create an unopened TELNET socket.
121 const PString
& address
///< Address of remote machine to connect to.
123 // Create an opened TELNET socket.
126 // Overrides from class PChannel
127 /** Low level read from the channel. This function may block until the
128 requested number of characters were read or the read timeout was
129 reached. The GetLastReadCount() function returns the actual number
132 The GetErrorCode() function should be consulted after Read() returns
133 FALSE to determine what caused the failure.
135 The TELNET channel intercepts and escapes commands in the data stream to
136 implement the TELNET protocol.
139 TRUE indicates that at least one character was read from the channel.
140 FALSE means no bytes were read due to timeout or some other I/O error.
143 void * buf
, ///< Pointer to a block of memory to receive the read bytes.
144 PINDEX len
///< Maximum number of bytes to read into the buffer.
147 /** Low level write to the channel. This function will block until the
148 requested number of characters are written or the write timeout is
149 reached. The GetLastWriteCount() function returns the actual number
152 The GetErrorCode() function should be consulted after Write() returns
153 FALSE to determine what caused the failure.
155 The TELNET channel intercepts and escapes commands in the data stream to
156 implement the TELNET protocol.
158 Returns TRUE if at least len bytes were written to the channel.
161 const void * buf
, ///< Pointer to a block of memory to write.
162 PINDEX len
///< Number of bytes to write.
166 /** Connect a socket to a remote host on the specified port number. This is
167 typically used by the client or initiator of a communications channel.
168 This connects to a "listening" socket at the other end of the
169 communications channel.
171 The port number as defined by the object instance construction or the
172 <A>PIPSocket::SetPort()</A> function.
175 TRUE if the channel was successfully connected to the remote host.
177 virtual BOOL
Connect(
178 const PString
& address
///< Address of remote machine to connect to.
182 /** Open a socket to a remote host on the specified port number. This is an
183 "accepting" socket. When a "listening" socket has a pending connection
184 to make, this will accept a connection made by the "connecting" socket
185 created to establish a link.
187 The port that the socket uses is the one used in the <A>Listen()</A>
188 command of the <CODE>socket</CODE> parameter.
190 Note that this function will block until a remote system connects to the
191 port number specified in the "listening" socket.
194 TRUE if the channel was successfully opened.
197 PSocket
& socket
///< Listening socket making the connection.
201 /** This is callback function called by the system whenever out of band data
202 from the TCP/IP stream is received. A descendent class may interpret
203 this data according to the semantics of the high level protocol.
205 The TELNET socket uses this for sychronisation.
207 virtual void OnOutOfBand(
208 const void * buf
, ///< Data to be received as URGENT TCP data.
209 PINDEX len
///< Number of bytes pointed to by <CODE>buf</CODE>.
215 IAC
= 255, ///< Interpret As Command - escape character.
216 DONT
= 254, ///< You are not to use option.
217 DO
= 253, ///< Request to use option.
218 WONT
= 252, ///< Refuse use of option.
219 WILL
= 251, ///< Accept the use of option.
220 SB
= 250, ///< Subnegotiation begin.
221 GoAhead
= 249, ///< Function GA, you may reverse the line.
222 EraseLine
= 248, ///< Function EL, erase the current line.
223 EraseChar
= 247, ///< Function EC, erase the current character.
224 AreYouThere
= 246, ///< Function AYT, are you there?
225 AbortOutput
= 245, ///< Function AO, abort output stream.
226 InterruptProcess
= 244, ///< Function IP, interrupt process, permanently.
227 Break
= 243, ///< NVT character break.
228 DataMark
= 242, ///< Marker for connection cleaning.
229 NOP
= 241, ///< No operation.
230 SE
= 240, ///< Subnegotiation end.
231 EndOfReccord
= 239, ///< End of record for transparent mode.
232 AbortProcess
= 238, ///< Abort the entire process
233 SuspendProcess
= 237, ///< Suspend the process.
234 EndOfFile
= 236 ///< End of file marker.
236 // Defined telnet commands codes
238 /** Send an escaped IAC command. The <CODE>opt</CODE> parameters meaning
239 depends on the command being sent:
242 <DT>DO, DONT, WILL, WONT <DD><CODE>opt</CODE> is Options code.
244 <DT>AbortOutput <DD>TRUE is flush buffer.
246 <DT>InterruptProcess,
248 SuspendProcess <DD>TRUE is synchronise.
251 Synchronises the TELNET streams, inserts the data mark into outgoing
252 data stream and sends an out of band data to the remote to flush all
253 data in the stream up until the syncronisation command.
256 TRUE if the command was successfully sent.
259 Command cmd
, ///< Command code to send
260 int opt
= 0 ///< Option for command code.
265 TransmitBinary
= 0, ///< Assume binary 8 bit data is transferred.
266 EchoOption
= 1, ///< Automatically echo characters sent.
267 ReconnectOption
= 2, ///< Prepare to reconnect
268 SuppressGoAhead
= 3, ///< Do not use the GA protocol.
269 MessageSizeOption
= 4, ///< Negatiate approximate message size
270 StatusOption
= 5, ///< Status packets are understood.
271 TimingMark
= 6, ///< Marker for synchronisation.
272 RCTEOption
= 7, ///< Remote controlled transmission and echo.
273 OutputLineWidth
= 8, ///< Negotiate about output line width.
274 OutputPageSize
= 9, ///< Negotiate about output page size.
275 CRDisposition
= 10, ///< Negotiate about CR disposition.
276 HorizontalTabsStops
= 11, ///< Negotiate about horizontal tabstops.
277 HorizTabDisposition
= 12, ///< Negotiate about horizontal tab disposition
278 FormFeedDisposition
= 13, ///< Negotiate about formfeed disposition.
279 VerticalTabStops
= 14, ///< Negotiate about vertical tab stops.
280 VertTabDisposition
= 15, ///< Negotiate about vertical tab disposition.
281 LineFeedDisposition
= 16, ///< Negotiate about output LF disposition.
282 ExtendedASCII
= 17, ///< Extended ascic character set.
283 ForceLogout
= 18, ///< Force logout.
284 ByteMacroOption
= 19, ///< Byte macro.
285 DataEntryTerminal
= 20, ///< data entry terminal.
286 SupDupProtocol
= 21, ///< supdup protocol.
287 SupDupOutput
= 22, ///< supdup output.
288 SendLocation
= 23, ///< Send location.
289 TerminalType
= 24, ///< Provide terminal type information.
290 EndOfRecordOption
= 25, ///< Record boundary marker.
291 TACACSUID
= 26, ///< TACACS user identification.
292 OutputMark
= 27, ///< Output marker or banner text.
293 TerminalLocation
= 28, ///< Terminals physical location infromation.
294 Use3270RegimeOption
= 29, ///< 3270 regime.
295 UseX3PADOption
= 30, ///< X.3 PAD
296 WindowSize
= 31, ///< NAWS - Negotiate About Window Size.
297 TerminalSpeed
= 32, ///< Provide terminal speed information.
298 FlowControl
= 33, ///< Remote flow control.
299 LineModeOption
= 34, ///< Terminal in line mode option.
300 XDisplayLocation
= 35, ///< X Display location.
301 EnvironmentOption
= 36, ///< Provide environment information.
302 AuthenticateOption
= 37, ///< Authenticate option.
303 EncriptionOption
= 38, ///< Encryption option.
304 EncryptionOption
= 38, ///< Duplicate to fix spelling mistake and remain backwards compatible.
305 ExtendedOptionsList
= 255, ///< Code for extended options.
308 // Defined TELNET options.
314 TRUE if the command was successfully sent.
317 BYTE option
///< Option to DO
320 /** Send DONT command.
323 TRUE if the command was successfully sent.
325 virtual BOOL
SendDont(
326 BYTE option
///< Option to DONT
329 /** Send WILL request.
332 TRUE if the command was successfully sent.
334 virtual BOOL
SendWill(
335 BYTE option
///< Option to WILL
338 /** Send WONT command.
341 TRUE if the command was successfully sent.
343 virtual BOOL
SendWont(
344 BYTE option
///< Option to WONT
347 enum SubOptionCodes
{
348 SubOptionIs
= 0, ///< Sub-option is...
349 SubOptionSend
= 1, ///< Request to send option.
351 // Codes for sub option negotiation.
353 /** Send a sub-option with the information given.
356 TRUE if the command was successfully sent.
359 BYTE code
, ///< Suboptions option code.
360 const BYTE
* info
, ///< Information to send.
361 PINDEX len
, ///< Length of information.
362 int subCode
= -1 ///< Suboptions sub-code, -1 indicates no sub-code.
365 /** Set if the option on our side is possible, this does not mean it is set
366 it only means that in response to a DO we WILL rather than WONT.
369 BYTE code
, ///< Option to check.
370 BOOL state
= TRUE
///< New state for for option.
371 ) { option
[code
].weCan
= state
; }
373 /** Set if the option on their side is desired, this does not mean it is set
374 it only means that in response to a WILL we DO rather than DONT.
377 BYTE code
, ///< Option to check.
378 BOOL state
= TRUE
///< New state for for option.
379 ) { option
[code
].theyShould
= state
; }
381 /** Determine if the option on our side is enabled.
384 TRUE if option is enabled.
387 BYTE code
///< Option to check.
388 ) const { return option
[code
].ourState
== OptionInfo::IsYes
; }
390 /** Determine if the option on their side is enabled.
393 TRUE if option is enabled.
396 BYTE code
///< Option to check.
397 ) const { return option
[code
].theirState
== OptionInfo::IsYes
; }
399 void SetTerminalType(
400 const PString
& newType
///< New terminal type description string.
402 // Set the terminal type description string for TELNET protocol.
404 const PString
& GetTerminalType() const { return terminalType
; }
405 // Get the terminal type description string for TELNET protocol.
408 WORD width
, ///< New window width.
409 WORD height
///< New window height.
411 // Set the width and height of the Network Virtual Terminal window.
414 WORD
& width
, ///< Old window width.
415 WORD
& height
///< Old window height.
417 // Get the width and height of the Network Virtual Terminal window.
422 // Common construct code for TELNET socket channel.
424 /** This callback function is called by the system when it receives a DO
425 request from the remote system.
427 The default action is to send a WILL for options that are understood by
428 the standard TELNET class and a WONT for all others.
431 TRUE if option is accepted.
434 BYTE option
///< Option to DO
437 /** This callback function is called by the system when it receives a DONT
438 request from the remote system.
440 The default action is to disable options that are understood by the
441 standard TELNET class. All others are ignored.
444 BYTE option
///< Option to DONT
447 /** This callback function is called by the system when it receives a WILL
448 request from the remote system.
450 The default action is to send a DO for options that are understood by
451 the standard TELNET class and a DONT for all others.
454 BYTE option
///< Option to WILL
457 /** This callback function is called by the system when it receives a WONT
458 request from the remote system.
460 The default action is to disable options that are understood by the
461 standard TELNET class. All others are ignored.
464 BYTE option
///< Option to WONT
467 /** This callback function is called by the system when it receives a
468 sub-option command from the remote system.
470 virtual void OnSubOption(
471 BYTE code
, ///< Option code for sub-option data.
472 const BYTE
* info
, ///< Extra information being sent in the sub-option.
473 PINDEX len
///< Number of extra bytes.
477 /** This callback function is called by the system when it receives an
478 telnet command that it does not do anything with.
480 The default action displays a message to the <A>PError</A> stream
481 (when <CODE>debug</CODE> is TRUE) and returns TRUE;
484 TRUE if next byte is not part of the command.
486 virtual BOOL
OnCommand(
487 BYTE code
///< Code received that could not be precessed.
494 IsNo
, IsYes
, WantNo
, WantNoQueued
, WantYes
, WantYesQueued
496 unsigned weCan
:1; // We can do the option if they want us to do.
498 unsigned theyShould
:1; // They should if they will.
499 unsigned theirState
:3;
502 OptionInfo option
[MaxOptions
];
503 // Information on protocol options.
505 PString terminalType
;
506 // Type of terminal connected to telnet socket, defaults to "UNKNOWN"
508 WORD windowWidth
, windowHeight
;
509 // Size of the "window" used by the NVT.
512 // Debug socket, output messages to PError stream.
524 StateSubNegotiations
,
527 // Internal states for the TELNET decoder
530 // Current state of incoming characters.
532 PBYTEArray subOption
;
533 // Storage for sub-negotiated options
535 unsigned synchronising
;
537 BOOL
StartSend(const char * which
, BYTE code
);
544 // End Of File ///////////////////////////////////////////////////////////////