Telnet.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Utils_Termlib_Telnet_
18 #define HH_SENF_Utils_Termlib_Telnet_ 1
19 
20 // Custom includes
21 #include <vector>
22 #include <map>
30 
31 //#include "Telnet.mpp"
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33 
34 namespace senf {
35 namespace term {
36 
132  {
133  public:
134  static unsigned const DEFAULT_REQUEST_TIMEOUT_MS = 500u;
135 
141 
142  typedef unsigned char option_type;
143 
144  struct TelnetHandler;
145 
146  void write(std::string const & s);
147 
149  void write(char c);
150 
153  Handle handle();
154 
155  void sendNOP();
156  void sendBRK();
157  void sendIP();
158  void sendAO();
159  void sendAYT();
160  void sendEC();
161  void sendEL();
162  void sendGA();
163 
164  void sendOptionParameters(option_type option, std::string const & data);
166 
169  void requestLocalOption(option_type option, bool enabled = true);
171 
172  void acceptLocalOption(option_type option, bool enabled = true);
174 
177  void requestPeerOption(option_type option, bool enabled = true);
179 
180  void acceptPeerOption(option_type option, bool enabled = true);
182 
185  bool localOption(option_type option);
186  bool peerOption(option_type option);
187 
188  protected:
189  explicit BaseTelnetProtocol(Handle handle);
191 
192  virtual ~BaseTelnetProtocol();
193 
194  template <class Handler>
195  void registerHandler(Handler * h, bool request=true);
197 
198  void incrementRequestCounter();
199 
203  void decrementRequestCounter();
204 
205  bool requestsPending();
206 
207 #ifndef DOXYGEN
208  private:
209 #endif
210  virtual void v_setupComplete() = 0;
211 
222  virtual void v_charReceived(char c) = 0;
223  virtual void v_eof() = 0;
224 
225  virtual void v_handleNOP();
226  virtual void v_handleBRK();
227  virtual void v_handleIP();
228  virtual void v_handleAO();
229  virtual void v_handleAYT();
230  virtual void v_handleEC();
231  virtual void v_handleEL();
232  virtual void v_handleGA();
233 
234  private:
235  void handleChar(char c);
236  void handleNormalChar(char c);
237  void handleCommand(char c);
238  void handleOption(char c);
239  void handleCR(char c);
240  void handleSBOption(char c);
241  void handleSBData(char c);
242  void handleSBIAC(char c);
243  void emit(char c);
244  void processCommand();
245  void transmit(char c);
246 
247  void sendWILL(char option);
248  void sendWONT(char option);
249  void sendDO(char option);
250  void sendDONT(char option);
251 
252  void readHandler(int state);
253  void writeHandler(int state);
254  void timeout();
255 
256  enum Command {
257  CMD_NONE = 0,
258  CMD_SE = 240,
259  CMD_NOP = 241,
260  CMD_DM = 242,
261  CMD_BRK = 243,
262  CMD_IP = 244,
263  CMD_AO = 245,
264  CMD_AYT = 246,
265  CMD_EC = 247,
266  CMD_EL = 248,
267  CMD_GA = 249,
268  CMD_SB = 250,
269  CMD_WILL = 251,
270  CMD_WONT = 252,
271  CMD_DO = 253,
272  CMD_DONT = 254,
273  CMD_IAC = 255,
274  };
275 
276  struct OptInfo
277  {
278  enum WantState { WANTED, ACCEPTED, DISABLED };
279  enum OptionState { NONE, REQUEST_SENT, ACKNOWLEDGED };
280 
281  OptInfo();
282  OptInfo(bool local, option_type option);
283 
284  //-////////////////////////////////////////////////////////////
285 
286  bool const local;
287  option_type const option;
288 
289  WantState wantState;
290  OptionState optionState;
291  bool enabled;
292 
293  };
294 
295  OptInfo & getOption(bool local, option_type option);
296  void request(OptInfo & info, bool enabled);
297  void response(OptInfo & info, bool enabled);
298 
299  typedef std::map<std::pair<bool, option_type>, OptInfo> OptionsMap;
300  OptionsMap options_;
301 
302  typedef std::map<option_type, TelnetHandler*> OptionHandlerMap;
303  OptionHandlerMap handlers_;
304 
305  Handle handle_;
306 
307  typedef std::vector<char> SendQueue;
308  SendQueue sendQueue_;
309 
310  enum CharState { NORMAL, IAC_SEEN, EXPECT_OPTION, CR_SEEN,
311  SB_OPTION, SB_DATA, SB_IAC_SEEN };
312  CharState charState_;
313 
314  Command command_;
315  option_type option_;
316  std::string data_;
317 
318  scheduler::FdEvent inputEvent_;
319  scheduler::FdEvent outputEvent_;
320 
321  unsigned pendingRequests_;
322 
323  ClockService::clock_type requestTimeout_;
324  scheduler::TimerEvent timeout_;
325 
326  friend struct TelnetHandler;
327  };
328 
334  : public virtual BaseTelnetProtocol
335  {
336  virtual ~TelnetHandler();
337  virtual void v_init() = 0;
338  virtual void v_handleOptionParameters(std::string const & data) = 0;
340  };
341 
348  namespace telnetopt { BaseTelnetProtocol::option_type const ECHO = 1u; }
349  namespace telnetopt { BaseTelnetProtocol::option_type const TRANSMIT_BINARY = 0u; }
350  namespace telnetopt { BaseTelnetProtocol::option_type const SUPPRESS_GO_AHEAD = 3u; }
351  namespace telnetopt { BaseTelnetProtocol::option_type const TERMINAL_TYPE = 24u; }
352  namespace telnetopt { BaseTelnetProtocol::option_type const NAWS = 31u; }
353  namespace telnetopt { BaseTelnetProtocol::option_type const LINEMODE = 34u; }
354 
358 namespace telnethandler {
359 
375  {
376  public:
377  static option_type const OPTION_CODE = telnetopt::TERMINAL_TYPE;
378 
379  void nextTerminalType();
380  std::string const & terminalType() const;
381 
382  protected:
383  TerminalType();
384 
385  private:
386  virtual void v_init();
387  virtual void v_handleOptionParameters(std::string const & data);
388 
389  std::string type_;
390  };
391 
404  class NAWS
406  {
407  public:
408  static option_type const OPTION_CODE = telnetopt::NAWS;
409 
410  unsigned width() const;
411  unsigned height() const;
412 
413  protected:
414  NAWS();
415 
416 # ifndef DOXYGEN
417  private:
418 # endif
419  virtual void v_windowSizeChanged() = 0;
420 
423  private:
424  virtual void v_init();
425  virtual void v_handleOptionParameters(std::string const & data);
426 
427  unsigned width_;
428  unsigned height_;
429  };
430 
431 }
432 
433 }}
434 
435 //-/////////////////////////////////////////////////////////////////////////////////////////////////
436 #include "Telnet.cci"
437 
438 //#include "Telnet.ct"
439 #include "Telnet.cti"
440 #endif
441 
442 
443 // Local Variables:
444 // mode: c++
445 // fill-column: 100
446 // comment-column: 40
447 // c-file-style: "senf"
448 // indent-tabs-mode: nil
449 // ispell-local-dictionary: "american"
450 // compile-command: "scons -u test"
451 // End:
BaseTelnetProtocol::option_type const SUPPRESS_GO_AHEAD
Definition: Telnet.hh:350
virtual void v_handleGA()
Called, when the peer sends a GoAhead.
Definition: Telnet.cc:124
config::time_type clock_type
static unsigned const DEFAULT_REQUEST_TIMEOUT_MS
Definition: Telnet.hh:134
BaseTelnetProtocol()
Provided for TelnetHandler mixins only.
Definition: Telnet.cc:44
virtual void v_handleEC()
Called, when the peer sends an EraseCharacter.
Definition: Telnet.cc:118
void sendEC()
Send EraseCharacter to peer.
virtual void v_handleBRK()
Called, when the peer sends a BReaK.
Definition: Telnet.cc:106
void sendBRK()
Send BReaK to peer.
virtual void v_charReceived(char c)=0
Called whenever a data character is received.
bool localOption(option_type option)
true, if option locally enabled
void write(std::string const &s)
Send string to peer.
Definition: Telnet.cc:58
void requestLocalOption(option_type option, bool enabled=true)
Request option to be enabled here.
u8 data[SPECTRAL_HT20_NUM_BINS]
void incrementRequestCounter()
Increment request counter.
Definition: Telnet.cc:327
virtual void v_handleEL()
Called, when the peer sends an EraseLine.
Definition: Telnet.cc:121
void sendOptionParameters(option_type option, std::string const &data)
Send extended option parameter to peer.
Definition: Telnet.cc:86
void sendEL()
Send EraseLine to peer.
void acceptLocalOption(option_type option, bool enabled=true)
Accept a request for an option to be enabled here.
void registerHandler(Handler *h, bool request=true)
Register a TelnetHandler.
Telnet handler base class.
Definition: Telnet.hh:333
void sendIP()
Send InterruptProcess to peer.
virtual void v_handleIP()
Called, when the peer sends an InterruptProcess.
Definition: Telnet.cc:109
void sendNOP()
Send NOP to peer.
bool requestsPending()
true, if there are pending requests
Implement NAWS (Negotiation About Window Size) option.
Definition: Telnet.hh:404
Handle handle()
Get socket handle.
Telnet protocol implementation.
Definition: Telnet.hh:131
BaseTelnetProtocol::option_type const TRANSMIT_BINARY
Definition: Telnet.hh:349
BaseTelnetProtocol::option_type const LINEMODE
Definition: Telnet.hh:353
virtual void v_eof()=0
Called on input EOF.
void decrementRequestCounter()
Decrement request counter.
Definition: Telnet.cc:430
BaseTelnetProtocol::option_type const NAWS
Definition: Telnet.hh:352
void sendAYT()
Send AreYouThere to peer.
BaseTelnetProtocol::option_type const ECHO
Definition: Telnet.hh:348
unsigned char option_type
Type of telnet option numbers.
Definition: Telnet.hh:142
virtual void v_setupComplete()=0
Called, when no further requests are pending.
void acceptPeerOption(option_type option, bool enabled=true)
Accept a request by the peer to enable an option.
virtual void v_handleAYT()
Called, when the peer sends an AreYouThere.
Definition: Telnet.cc:115
virtual void v_handleNOP()
Called, when the peer sends a NOP.
Definition: Telnet.cc:103
BaseTelnetProtocol::option_type const TERMINAL_TYPE
Definition: Telnet.hh:351
void sendAO()
Send AbortOutput to peer.
Implement TERMINAL_TYPE option.
Definition: Telnet.hh:373
bool peerOption(option_type option)
true, if option enabled in peer
virtual void v_handleAO()
Called, when the peer sends an AbortOutput.
Definition: Telnet.cc:112
void sendGA()
Send GoAhead to peer.
void requestPeerOption(option_type option, bool enabled=true)
Request peer to enable an option.
ClientSocketHandle< senf::MakeSocketPolicy< ConnectedCommunicationPolicy, StreamFramingPolicy, ReadablePolicy, WriteablePolicy >::policy > Handle
Type of socket handle required.
Definition: Telnet.hh:140