public TelnetSocket(string address) { _address = new DnsEndPoint(address, 23); _buffer = new Queue <byte[]>(); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _flags = TelnetOptionFlags.Echo | TelnetOptionFlags.SupressGoAhead | TelnetOptionFlags.NAWS; _negotiated = TelnetOptionFlags.None; _writeLock = new AutoResetEvent(false); }
public static TelnetOptions[] GetFlags(this TelnetOptionFlags flag) { List <TelnetOptions> options = new List <TelnetOptions>(); foreach (TelnetOptionFlags tflag in flag.ParseOptions()) { options.Add(tflag.Translate()); } return(options.ToArray()); }
public static TelnetOptionFlags[] ParseOptions(this TelnetOptionFlags flag) { List <TelnetOptionFlags> flags = new List <TelnetOptionFlags>(); foreach (FieldInfo fi in typeof(TelnetOptionFlags).GetFields(BindingFlags.Static | BindingFlags.Public)) { TelnetOptionFlags option = (TelnetOptionFlags)fi.GetValue(null); if (flag.Contains(option)) { flags.Add(option); } } return(flags.ToArray()); }
public static bool Contains(this TelnetOptionFlags current, TelnetOptionFlags flag) { return((current & flag) > 0); }
public static TelnetOptions Translate(this TelnetOptionFlags flag) { string name = Enum.GetName(typeof(TelnetOptionFlags), flag); return((TelnetOptions)Enum.Parse(typeof(TelnetOptions), name, true)); }
public void Disable(TelnetOptionFlags flag) { _flags &= ~flag; }
public void Enable(TelnetOptionFlags flag) { _flags |= flag; }
public bool IsEnabled(TelnetOptionFlags flag) { return((_flags & flag) > 0); }
public TelnetSocket(string address, TelnetOptionFlags options) : this(address) { _flags |= options; }
void ParseResponse() { // track the current color that should be applied to the text Color currentColor = Colors.Cyan;//Color.FromArgb(0xFF, 0x0, 0x0, 0x0); do { // wait for input _writeLock.WaitOne(); // reset the lock _writeLock.Reset(); // create an array to hold the bytes byte[] data = new byte[_overflow.Length]; // copy any overflow bytes into the array Array.Copy(_overflow, data, _overflow.Length); // clear the overflow _overflow = new byte[0]; // lock the buffer to keep additional data entry lock (_buffer) { // append each block in the buffer to the data array while (_buffer.Count > 0) { byte[] next = _buffer.Dequeue(); Array.Resize <byte>(ref data, data.Length + next.Length); Array.Copy(next, 0, data, data.Length - next.Length, next.Length); } } // begin processing the bytes // check if consumer supports ansi bool ansi = _flags.Contains(TelnetOptionFlags.ANSI); // create a list to hold the segments List <IFormattedTextSegment> segments = new List <IFormattedTextSegment>(); // create a string builder to construct segments StringBuilder segment = new StringBuilder(); // create a byte array to store any response to server requests byte[] response = new byte[0]; // process the entire byte stream for (int i = 0; i < data.Length; ++i) { if (data[i] == ESC) // ansi escape { Color background = Colors.Black; int row = 0, col = 0; if (segment.Length > 0) { segments.Add(new DisplayText() { Text = segment.ToString(), TextColor = currentColor }); segment.Clear(); } int processed = AnsiProcessor.ReadCommand(data, i, ref row, ref col, ref background, ref currentColor); if (processed < 0) // fragment { _overflow = new byte[data.Length - i]; Array.Copy(data, i, _overflow, 0, _overflow.Length); break; } i += processed; // advance past the command continue; } else if (data[i] == TelnetCommands.IAC.Translate()) // process the telnet command { TelnetCommands command = data[++i].ToTelnetCommand(); // subnegotiation so there will be more data if (command == TelnetCommands.Subnegotation) { } // delete a character else if (command == TelnetCommands.EraseCharacter) { } // delete the line else if (command == TelnetCommands.EraseLine) { } else { // regular negotiation TelnetOptions option = data[++i].ToTelnetOption(); Array.Resize <byte>(ref response, response.Length + 3); response[response.Length - 3] = TelnetCommands.IAC.Translate(); // check to see if that option is supported if (_flags.Contains(option.ToFlag())) { if (command == TelnetCommands.Will || command == TelnetCommands.Do) { response[response.Length - 2] = TelnetCommands.Will.Translate(); } else { response[response.Length - 2] = TelnetCommands.Wont.Translate(); } if (option == TelnetOptions.NAWS && (command == TelnetCommands.Will)) { _nawsEnabled = true; } } else // tell the server not to support this { if (command == TelnetCommands.Will) { response[response.Length - 2] = TelnetCommands.Dont.Translate(); } else { response[response.Length - 2] = TelnetCommands.Wont.Translate(); } } response[response.Length - 1] = option.Translate(); _negotiated |= option.ToFlag(); } continue; } // append the data to the segment char c = (char)data[i]; if (c == '\b') { if (segment.Length > 0) { segment.Remove(segment.Length - 1, 1); } } else { segment.Append(c); } } // check for server negotiation if (response.Length > 0) { // add any additional flags that haven't been negotiated foreach (TelnetOptionFlags option in _flags.ParseOptions()) { // this has already been negotiated if (_negotiated.Contains(option)) { continue; } // request the ones that we are comfortable with so far switch (option) { case TelnetOptionFlags.SupressGoAhead: goto case TelnetOptionFlags.NAWS; case TelnetOptionFlags.Echo: goto case TelnetOptionFlags.NAWS; case TelnetOptionFlags.NAWS: Array.Resize <byte>(ref response, response.Length + 3); response[response.Length - 3] = TelnetCommands.IAC.Translate(); response[response.Length - 2] = TelnetCommands.Do.Translate(); response[response.Length - 1] = option.Translate().Translate(); break; } _negotiated |= option; } // create the socket event args SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.UserToken = _socket; args.RemoteEndPoint = _address; args.Completed += new EventHandler <SocketAsyncEventArgs>(AsyncCompletedHandler); // put the response in the buffer args.SetBuffer(response, 0, response.Length); // send the response to the server _socket.SendAsync(args); } // notify any listeners if (MessageRecieved != null) { segments.Add(new DisplayText() { Text = segment.ToString(), TextColor = currentColor }); MessageRecieved(this, new MessageRecievedEventArgs() { Segments = segments.ToArray() }); } // end byte processing } while (_socket.Connected); }