/// <summary>
 /// コピーコンストラクタ
 /// </summary>
 /// <param name="info"></param>
 public NegotiationInfomation(NegotiationInfomation info)
 {
     this.IAC     = info.IAC;
     this.Command = info.Command;
     this.Option  = info.Option;
     this.Stream  = info.Stream;
 }
Пример #2
0
        void EndSequence(TelnetOption option)
        {
            try
            {
                if (option == TelnetOption.TerminalType)
                {
                    if (!Properties.ContainsKey("TerminalType"))
                        Properties["TerminalType"] = string.Empty;
                    var name = Properties["TerminalType"] as string ?? string.Empty;
                    if (name.Length > 0)
                        name += " ";

                    name += Encoding.ASCII.GetString(_sequence.ToArray());
                    Properties["TerminalType"] = name;
                }

                if (option == TelnetOption.WindowSize)
                {
                    Properties["Width"] = (short)_sequence[0];
                    Properties["Height"] = (short)_sequence[1];
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
            }

            _sequence.Clear();
            _telnetCommand = null;
        }
Пример #3
0
        public static Tuple <int, byte[], TelnetLogList> ProcessTelnetCommand(
            TelnetCommand TelnetCmd, NegotiateSettings NegotiateSettings,
            bool doLog = false)
        {
            TelnetLogList logList = null;

            if (doLog == true)
            {
                logList = new TelnetLogList();
            }
            int cx          = 0;
            var writeStream = new ByteArrayBuilder();

            // write to the run log.
            if (logList != null)
            {
                logList.AddItem(Direction.Read, TelnetCmd.ToString());
            }

            if (TelnetCmd.CmdCode == Enums.CommandCode.DO)
            {
                var replyStmt = TelnetCmd.BuildReply(NegotiateSettings);
                writeStream.Append(replyStmt.ToBytes());
            }

            else if (TelnetCmd is NewEnvironCommand)
            {
                var envStmt = TelnetCmd as NewEnvironCommand;
                cx = ProcessNewEnvironStatement(envStmt, writeStream, NegotiateSettings);
            }

            else if (TelnetCmd is TerminalTypeCommand)
            {
                var ttStmt = TelnetCmd as TerminalTypeCommand;
                cx = ProcessTerminalTypeStatement(ttStmt, writeStream, NegotiateSettings);
            }

            else if ((TelnetCmd is EndOfRecordStatement) || (TelnetCmd is TransmitBinaryCommand))
            {
                if (TelnetCmd.CmdCode == Enums.CommandCode.DO)
                {
                    var replyStmt = TelnetCmd.BuildReply(NegotiateSettings);
                    writeStream.Append(replyStmt.ToBytes());

                    if ((replyStmt.CmdCode == Enums.CommandCode.DO) &&
                        (replyStmt.Subject.IsEqual(TelnetSubject.TRANSMIT_BINARY)))
                    {
                    }
                }
                else if (TelnetCmd.CmdCode == Enums.CommandCode.WILL)
                {
                    var replyStmt = TelnetCmd.BuildDoReply();
                    writeStream.Append(replyStmt.ToBytes());
                }
            }
            return(new Tuple <int, byte[], TelnetLogList>(cx, writeStream.ToByteArray(), logList));
        }
Пример #4
0
        /// <summary>
        /// 応答送信
        /// </summary>
        /// <param name="command"></param>
        /// <param name="option"></param>
        private MemoryStream SendBack(TelnetCommand command, TelnetOption option)
        {
            // 送信メモリオブジェクト生成
            MemoryStream sendStream = new MemoryStream();

            sendStream.WriteByte((byte)TelnetCommand.IAC);
            sendStream.WriteByte((byte)command);
            sendStream.WriteByte((byte)option);
            return(sendStream);
        }
Пример #5
0
        public byte Receive()
        {
            byte In = ReceiveRaw();

            if (IsCtrlChar(In) && In == 255)
            {
                TelnetCommand Cmd           = (TelnetCommand)ReceiveRaw();
                TelnetCommand Option        = (TelnetCommand)ReceiveRaw();
                bool          Unimplemented = false;

                if (Cmd == TelnetCommand.IAC && Option == TelnetCommand.IAC)
                {
                    throw new Exception("Invalid control code");
                }

                if (Option == TelnetCommand.SuppressGoAhead)
                {
                    Send(TelnetCommand.IAC, TelnetCommand.WILL, TelnetCommand.SuppressGoAhead);
                }
                else if (Option == TelnetCommand.Echo)
                {
                    if (Cmd == TelnetCommand.DO)
                    {
                        Echo = true;
                    }
                    else if (Cmd == TelnetCommand.DONT)
                    {
                        Echo = false;
                    }
                    else
                    {
                        Unimplemented = true;
                    }

                    Send(TelnetCommand.IAC, Echo ? TelnetCommand.WILL : TelnetCommand.WONT, TelnetCommand.Echo);
                }
                else
                {
                    Unimplemented = true;
                }

                if (Unimplemented)
                {
                    Console.WriteLine("Unsupported: IAC {0} {1}", Cmd, Option);
                }
                return(Receive());
            }

            if (In == 127)
            {
                In = (byte)'\b';
            }
            return(In);
        }
Пример #6
0
 private void SendIAC(TelnetCommand command, byte option)
 {
     if (Connected)
     {
         if (!_TelnetOptions[option])
         {
             _TelnetOptions[option] = true;
             base.WriteRaw(new byte[] { (byte)TelnetCommand.IAC, (byte)command, option });
         }
     }
 }
Пример #7
0
 public static TelnetCommand AsNegative(this TelnetCommand command)
 {
     if (!command.IsPositive())
     {
         return(command);
     }
     else
     {
         return(command.Negate());
     }
 }
        public async Task Handle(TelnetCommand command, TelnetOption option, ITelnetChannel channel)
        {
            TelnetCommand response = command.Reciprocal().AsNegative();

            //if (option == TelnetOption.SuppressGoAhead && command.IsPositive())
            //{
            //    response = response.AsPositive();
            //}

            await channel.SendCommandAsync(response, option);
        }
Пример #9
0
        public static bool IsImperative(this TelnetCommand command)
        {
            switch (command)
            {
            case TelnetCommand.DO:
            case TelnetCommand.DONT:
                return(true);

            default:
                return(false);
            }
        }
Пример #10
0
        public static bool IsPositive(this TelnetCommand command)
        {
            switch (command)
            {
            case TelnetCommand.WILL:
            case TelnetCommand.DO:
                return(true);

            default:
                return(false);
            }
        }
Пример #11
0
        /// <summary>
        /// 応答送信
        /// </summary>
        /// <param name="command"></param>
        /// <param name="option"></param>
        private void SendBack(TelnetCommand command, TelnetOption option)
        {
            // 送信メモリオブジェクト生成
            MemoryStream sendStream = new MemoryStream();

            sendStream.WriteByte((byte)TelnetCommand.IAC);
            sendStream.WriteByte((byte)command);
            sendStream.WriteByte((byte)option);

            // 送信
            this.Parse(sendStream.ToArray());
            this.Send(sendStream);
        }
Пример #12
0
        private static int ProcessNewEnvironStatement(
            NewEnvironCommand Stmt, ByteArrayBuilder WriteStream,
            NegotiateSettings NegotiateSettings)
        {
            int sendStmtCx = 0;

            // got the stmt with the SEND parm. Send back the NEW_ENVIRON stmt with the IS parm.
            if ((Stmt.SubOption != null) &&
                (Stmt.SubOption.Value == TelnetOptionParm.SEND))
            {
                var neSend =
                    new NewEnvironCommand(Enums.CommandCode.SB, TelnetOptionParm.IS);

                foreach (var newEnv in NegotiateSettings.SendNewEnvironList)
                {
                    var optnVar = newEnv.ToOptionVariable(NegotiateSettings.SbsValuesDict);
                    neSend.AddOptionVar(optnVar);
                }

                int xx = 25;
                if (xx == 26)
                {
                    neSend.AddOptionVar(EnvironVarCode.VAR, "USER", "SRICHTER");
                    neSend.AddOptionVar(EnvironVarCode.VAR, "DEVNAME", "STEVE25");

                    // reply to newEnviron IBMRSEED stmt SEND statement.
                    if (Stmt.ContainsUserVar_IBMRSEED() == true)
                    {
                        byte[] clientSeed = new byte[8] {
                            0x55, 0x56, 0x59, 0x5a, 0x5b, 0x5c, 0x4c, 0x48
                        };
                        string passWord             = "******";
                        string userName             = "******";
                        var    serverSeed           = Stmt.IBMRSEED_SeedValue();
                        var    substitutionPassword =
                            CipherCommon.EncryptPassword(passWord, userName, serverSeed, clientSeed);
                        neSend.AddOptionVar(EnvironVarCode.USERVAR, "IBMRSEED", clientSeed);
                        neSend.AddOptionVar(EnvironVarCode.USERVAR, "IBMSUBSPW", substitutionPassword);
                    }
                }

                WriteStream.Append(neSend.ToBytes());

                // send the SE command immed after NEW-ENVIRON
                {
                    var ts = new TelnetCommand(Enums.CommandCode.SE);
                    WriteStream.Append(ts.ToBytes());
                }
            }
            return(sendStmtCx);
        }
Пример #13
0
        public static bool IsNegotiation(this TelnetCommand command)
        {
            switch (command)
            {
            case TelnetCommand.WILL:
            case TelnetCommand.WONT:
            case TelnetCommand.DO:
            case TelnetCommand.DONT:
                return(true);

            default:
                return(false);
            }
        }
Пример #14
0
        public static TelnetCommand Negate(this TelnetCommand command)
        {
            switch (command)
            {
            case TelnetCommand.WILL:
                return(TelnetCommand.WONT);

            case TelnetCommand.WONT:
                return(TelnetCommand.WILL);

            case TelnetCommand.DO:
                return(TelnetCommand.DONT);

            case TelnetCommand.DONT:
                return(TelnetCommand.DO);

            default:
                return(command);
            }
        }
Пример #15
0
    /// <summary>
    /// Handles a Telnet command.
    /// </summary>
    /// <param name="e">Information about the data received.</param>
    private void HandleCommand(SocketAsyncEventArgs e)
    {
        Connection c = e.UserToken as Connection;

        if (c == null || e.BytesTransferred < 3)
        {
            return;
        }
        for (int i = 0; i < e.BytesTransferred; i += 3)
        {
            if (e.BytesTransferred - i < 3)
            {
                break;
            }
            if (e.Buffer[i] == (int)TelnetCommand.IAC)
            {
                TelnetCommand command = (TelnetCommand)e.Buffer[i + 1];
                TelnetOption  option  = (TelnetOption)e.Buffer[i + 2];
                switch (command)
                {
                case TelnetCommand.DO:
                    if (option == TelnetOption.Echo)
                    {
                        // ECHO
                    }
                    break;

                case TelnetCommand.WILL:
                    if (option == TelnetOption.Echo)
                    {
                        // ECHO
                    }
                    break;
                }
                c.ReceiveBuffer.Remove(i, 3);
            }
        }
    }
Пример #16
0
        async Task ParseBytes(byte[] data)
        {
            using (var ms = new MemoryStream(data))
            {
                using (var reader = new BinaryReader(ms))
                {
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        var input = reader.ReadByte();

                        if (_telnetCommand != null)
                        {
                            if (_telnetCommand.Verb == null)
                            {
                                _telnetCommand.Verb = (TelnetVerb)input;
                                continue;
                            }

                            if (_telnetCommand.Option == null)
                            {
                                _telnetCommand.Option = (TelnetOption)input;
                            }

                            var verb = _telnetCommand.Verb.Value;
                            var option = _telnetCommand.Option.Value;

                            switch (verb)
                            {
                                case TelnetVerb.SB:
                                    // Sub-negotiation
                                    // Grab bytes until IAC|SE is reached.
                                    if (input == (byte)option)
                                        continue;

                                    if (input == 0x0)
                                        continue;

                                    if (input == (byte)TelnetVerb.IAC)
                                        continue;

                                    if (input == (byte)TelnetVerb.SE)
                                    {
                                        EndSequence(option);
                                        continue;
                                    }

                                    _sequence.Add(input);
                                    break;
                                case TelnetVerb.SE:
                                    // End of a sequence
                                    EndSequence(option);
                                    break;
                                case TelnetVerb.WILL:
                                    switch (option)
                                    {
                                        case TelnetOption.TerminalType:
                                            await SendRaw(new TelnetCommandBuilder()
                                                .Add(TelnetVerb.DO, TelnetOption.TerminalType)
                                                .AddSequence(TelnetOption.TerminalType, 1)
                                                .Build());
                                            break;
                                        case TelnetOption.WindowSize:
                                            await SendRaw(new TelnetCommandBuilder()
                                                .Add(TelnetVerb.DO, TelnetOption.WindowSize)
                                                .Build());
                                            break;
                                        default:
                                            await SendRaw(new TelnetCommandBuilder()
                                                .Add(TelnetVerb.DONT, option)
                                                .Build());
                                            break;
                                    }
                                    _telnetCommand = null;
                                    break;
                                case TelnetVerb.WONT:
                                    _telnetCommand = null;
                                    break;
                                case TelnetVerb.DO:
                                    switch (option)
                                    {
                                        case TelnetOption.SupressGoAhead:
                                            await SendRaw(new TelnetCommandBuilder()
                                                .Add(TelnetVerb.WILL, TelnetOption.SupressGoAhead)
                                                .Build());
                                            break;
                                        default:
                                            await SendRaw(new TelnetCommandBuilder()
                                                .Add(TelnetVerb.WONT, option)
                                                .Build());
                                            break;
                                    }
                                    _telnetCommand = null;
                                    break;
                                case TelnetVerb.DONT:
                                    _telnetCommand = null;
                                    break;
                                case TelnetVerb.IAC:
                                    // Probably not a telnet command...
                                    _buffer.Add(input);
                                    _telnetCommand = null;
                                    break;
                                default:
                                    _telnetCommand = null;
                                    break;
                            }

                            continue;
                        }

                        switch (input)
                        {
                            case (byte)TelnetVerb.IAC:
                                _telnetCommand = new TelnetCommand();
                                break;
                            case 0x7f: // Backspace
                                // Remove the last character entered.
                                _buffer.RemoveAt(_buffer.Count - 1);
                                break;
                            case 0x0A: // New Line \n
                            case 0x0D: // Carriage Return \r
                                await Context?.ProcessInput(Encoding.ASCII.GetString(_buffer.ToArray()));
                                _buffer.Clear();
                                return;
                            default:
                                _buffer.Add(input);
                                break;
                        }
                    }
                }
            }
        }
Пример #17
0
        /// <summary>
        /// parse the 5250 data stream that is sent from the client to the server.
        /// </summary>
        /// <param name="LogFile"></param>
        /// <param name="ToServerStream"></param>
        /// <returns></returns>
        public static Tuple <ResponseItemList, string> ParseResponseStream(
            InputByteArray InputArray, ResponseHeader ResponseHeader = null)
        {
            var    responseItemList = new ResponseItemList();
            string errmsg           = null;

            var writeStream                 = new ByteArrayBuilder();
            DataStreamHeader dsHeader       = null;
            ResponseHeader   responseHeader = ResponseHeader;

            // stream starts with data stream header.
            if (responseHeader == null)
            {
                var rv = DataStreamHeader.Factory(InputArray);
                dsHeader = rv.Item1;
                responseItemList.Add(dsHeader);
                errmsg = dsHeader.Errmsg;

                // next is the response header.
                if (errmsg == null)
                {
                    responseHeader = new ResponseHeader(InputArray);
                    responseItemList.Add(responseHeader);
                    errmsg = responseHeader.Errmsg;
                }
            }

            // look for 5250 query reply.
            if ((errmsg == null) && (responseHeader.AidKey != null) &&
                (responseHeader.AidKey.Value == AidKey.Query5250Reply))
            {
                var queryResp = new Query5250Response(InputArray);
                if (queryResp.Errmsg == null)
                {
                    responseItemList.Add(queryResp);
                }
            }

            // repeating instances of sbaOrder, textDataOrder pairs.
            while (true)
            {
                var telCmd = TelnetCommand.Factory(InputArray);
                if (telCmd != null)
                {
                    continue;
                }

                // check that an SBA order is starting. Leave loop when it is not.
                if (SetBufferAddressOrder.CheckOrder(InputArray) != null)
                {
                    break;
                }

                var orderPair = new LocatedTextDataOrderPair(InputArray);
                if (orderPair.Errmsg != null)
                {
                    break;
                }
                responseItemList.Add(orderPair);
            }

            return(new Tuple <ResponseItemList, string>(responseItemList, errmsg));
        }
Пример #18
0
 private void SendIAC(TelnetCommand command, byte option)
 {
     if (Connected)
     {
         if (!_TelnetOptions[option])
         {
             _TelnetOptions[option] = true;
             base.WriteRaw(new byte[] { (byte)TelnetCommand.IAC, (byte)command, option });
         }
     }
 }
Пример #19
0
 private static void WriteToHost(
     TelnetLogList LogList, TelnetCommand Stmt, NetworkStream NetStream)
 {
     WriteToHost(LogList, Stmt.ToBytes(), NetStream);
 }
Пример #20
0
 private void SendIAC(TelnetCommand command, TelnetOption option)
 {
     SendIAC(command, (byte)option);
 }
Пример #21
0
 private void SendIAC(TelnetCommand command, TelnetOption option)
 {
     SendIAC(command, (byte)option);
 }
Пример #22
0
        /// <summary>
        /// write buffer contents to log file.
        /// </summary>
        /// <param name="Direction"></param>
        /// <param name="Buffer"></param>
        /// <param name="Length"></param>
        public void Write(string Direction, byte[] Buffer, int Length)
        {
            var lines = new List <string>();

            this.Counter += 1;

            var inputArray = new InputByteArray(Buffer, Length);

            while (inputArray.IsEof() == false)
            {
                // peek to see if the current byte is a telnet command.
                var escapeCmd = inputArray.PeekNextByte().ToTelnetCommandCode();

                // peek to see if the current bytes are an IBM5250 datastream header.
                DataStreamHeader dsh    = null;
                string           errmsg = null;
                {
                    var rv = DataStreamHeader.Factory(inputArray);
                    dsh    = rv.Item1;
                    errmsg = rv.Item2;
                }

                // current bytes are an ibm5250 datastream header. ( page 2-4 of rfc 1205 )
                // store this header as the "current datastream header". When there is a
                // current data stream header the code will match the current bytes against
                // ibm5250 data stream commands.
                if (errmsg == null)
                {
                    lines.Add(
                        Direction + " " + this.Counter.ToString() + " "
                        + dsh.ToString());

                    this.CurrentDataStreamHeader = dsh;

                    continue;
                }

                // currently in a 5250 data stream header.
                if (this.CurrentDataStreamHeader != null)
                {
                    var dataStreamCommand = WorkstationCommandBase.ParseFactory(inputArray);
                    if (dataStreamCommand != null)
                    {
                        lines.Add(
                            Direction + " " + this.Counter.ToString() + " "
                            + dataStreamCommand.ToString());

                        // all the data stream command ToString methods provide enough info.
                        // But for the WriteToDisplayCommand, list out the ToString contents of
                        // the WtdOrders of that command.
                        if (dataStreamCommand is WriteToDisplayCommand)
                        {
                            var wtdCommand = dataStreamCommand as WriteToDisplayCommand;
                            foreach (var order in wtdCommand.OrderList)
                            {
                                lines.Add(order.ToString());
                            }
                        }

                        continue;
                    }
                }

                {
                    var stmt = TelnetCommand.Factory(inputArray);
                    if (stmt != null)
                    {
                        lines.Add(
                            Direction + " " + this.Counter.ToString() + " " + stmt.ToString());
                        continue;
                    }
                }

                if ((escapeCmd != null) && (escapeCmd.Value == CommandCode.ESCAPE))
                {
                    var rv     = TerminalVt100Statement.Factory(inputArray);
                    var vtStmt = rv.Item1;
                    var otStmt = rv.Item2;

                    lines.Add(
                        Direction + " " + this.Counter.ToString() + " " + vtStmt.ToString());

                    if (otStmt != null)
                    {
                        lines.Add(
                            Direction + " " + this.Counter.ToString() + " " + otStmt.ToString());
                    }

                    continue;
                }

                {
                    var remBytes = inputArray.GetBytesToEnd();
                    lines.Add(Direction + " " + this.Counter.ToString()
                              + " Raw bytes follow:");
                    LogFile_WriteRawBytes(remBytes, lines);
                }
            }
            WriteTextLines(lines);
        }
Пример #23
0
        private void ParseTelnetNegData()
        {
            byte[] negBuffer = tnNegCommands.ToArray();
            tnNegCommands.Clear();

            for (int i = 0; i < negBuffer.Length; i += 3)
            {
                if (negBuffer.Length - i < 3)
                {
                    break;
                }

                if (negBuffer[i] == (int)TelnetCommand.IAC)
                {
                    TelnetCommand command = (TelnetCommand)negBuffer[i + 1];
                    TelnetOption  option  = (TelnetOption)negBuffer[i + 2];

                    Console.WriteLine("CLIENT {0} {1}", command, option);

                    switch (command)
                    {
                    case TelnetCommand.WONT:
                        if (!ClientOptionNegociated((byte)option) || GetClientOption((byte)option))
                        {
                            server.Send(new byte[] { 255, (byte)TelnetCommand.DONT, (byte)option }, this);
                        }
                        Console.WriteLine("SERVER {0} {1}", TelnetCommand.DONT, option);
                        AddClientOption((byte)option, false);
                        this.sender.SendFailMessage(string.Format("Negotiating Client Option '{0}'", option), "OFF");
                        break;

                    case TelnetCommand.DONT:
                        if (!ServerOptionNegociated((byte)option) || GetServerOption((byte)option))
                        {
                            server.Send(new byte[] { 255, (byte)TelnetCommand.WONT, (byte)option }, this);
                        }
                        Console.WriteLine("SERVER {0} {1}", TelnetCommand.WONT, option);
                        AddServerOption((byte)option, false);
                        this.sender.SendFailMessage(string.Format("Negotiating Server Option '{0}'", option), "OFF");

                        if (option == TelnetOption.SuppressGoAhead)
                        {
                            //I WILL DISCONNECT ECHO ALSO!!!
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.WONT,
                                (byte)TelnetOption.Echo
                            }, this);
                            AddServerOption((byte)TelnetOption.Echo, false);
                            this.sender.SendFailMessage(string.Format("Negotiating Server Option '{0}'", option), "OFF");
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.WONT, TelnetOption.Echo);
                        }

                        break;

                    case TelnetCommand.DO:
                        switch (option)
                        {
                        case TelnetOption.Echo:
                            if (!ServerOptionNegociated((byte)option) || !GetServerOption((byte)option))
                            {
                                server.Send(new byte[] {
                                    (byte)TelnetCommand.IAC,
                                    (byte)TelnetCommand.WILL,
                                    (byte)TelnetOption.Echo
                                }, this);
                            }

                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.WILL, TelnetOption.Echo);
                            AddServerOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Server Option '{0}'", option), "ON");
                            break;

                        case TelnetOption.SuppressGoAhead:
                            if (!ServerOptionNegociated((byte)option) || !GetServerOption((byte)option))
                            {
                                server.Send(new byte[] {
                                    (byte)TelnetCommand.IAC,
                                    (byte)TelnetCommand.WILL,
                                    (byte)TelnetOption.SuppressGoAhead
                                }, this);
                            }
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.WILL, TelnetOption.SuppressGoAhead);
                            AddServerOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Server Option '{0}'", option), "ON");
                            break;
                        }
                        break;

                    case TelnetCommand.WILL:

                        switch (option)
                        {
                        case TelnetOption.SuppressGoAhead:
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.DO,
                                (byte)TelnetOption.SuppressGoAhead
                            }, this);
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.SuppressGoAhead);
                            AddClientOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON");
                            break;

                        case TelnetOption.Echo:
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.DO,
                                (byte)TelnetOption.Echo
                            }, this);
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.Echo);
                            AddClientOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON");
                            break;

                        case TelnetOption.WindowSize:
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.DO,
                                (byte)TelnetOption.WindowSize
                            }, this);
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.WindowSize);
                            AddClientOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON");
                            //server.Send(new byte[] {
                            //    (byte)TelnetCommand.IAC,
                            //    (byte)TelnetCommand.DO,
                            //    (byte)TelnetOption.DataEntryTerminal}, this);
                            //Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.DataEntryTerminal);
                            break;

                        case TelnetOption.TerminalType:
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.SB,
                                (byte)TelnetOption.TerminalType, 0x1,
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.SE
                            }, this);
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.SB, TelnetOption.TerminalType);
                            AddClientOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON");
                            break;

                        case TelnetOption.Charset:
                            server.Send(new byte[] {
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.SB,
                                (byte)TelnetOption.Charset, 0x1,
                                (byte)'U', (byte)'T', (byte)'F', (byte)'-', (byte)'8',
                                (byte)TelnetCommand.IAC,
                                (byte)TelnetCommand.SE
                            }, this);
                            Console.WriteLine("SERVER {0} {1}", TelnetCommand.SB, TelnetOption.TerminalType);
                            AddClientOption((byte)option, true);
                            this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON");
                            break;
                        }
                        break;

                    case TelnetCommand.SB:
                        switch (option)
                        {
                        case TelnetOption.WindowSize:
                            int w = negBuffer[i + 3] << 4 | negBuffer[i + 4];
                            int h = negBuffer[i + 5] << 4 | negBuffer[i + 6];

                            this.terminalHeight = h;
                            this.terminalWidth  = w;

                            Console.WriteLine("Window Size: {0} {1}", w, h);
                            i = i + 6;
                            if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand)
                            {
                                this.sender.SendMessage(string.Format("Got Terminal Size: '{0}x{1}'", w, h));
                            }

                            break;

                        case TelnetOption.TerminalType:
                            byte        Opt     = negBuffer[i + 3];
                            List <byte> tType   = new List <byte>();
                            bool        isValid = false;
                            for (int ct = i + 4; ct < negBuffer.Length; ct++)
                            {
                                i = ct;
                                if (negBuffer[ct] == (byte)TelnetCommand.IAC &&
                                    ct + 1 < negBuffer.Length &&
                                    negBuffer[ct + 1] == (byte)TelnetCommand.SE)
                                {
                                    isValid = true;
                                    break;
                                }
                                else
                                {
                                    tType.Add(negBuffer[ct]);
                                }
                            }

                            string tt = Encoding.UTF8.GetString(
                                Encoding.Convert(encoding, Encoding.UTF8, tType.ToArray())).ToUpper();

                            if (isValid)
                            {
                                if (!terminalTypes.Contains(tt))
                                {
                                    terminalTypes.Add(tt);
                                    terminalType = tt;
                                    VerifyTerminalType();
                                    Console.WriteLine("Got known terminal type: {0}", tt);
                                    if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand)
                                    {
                                        this.sender.SendSucessMessage("Got known terminal type", tt);
                                    }
                                }
                                else
                                {
                                    VerifyTerminalType();
                                    Console.WriteLine("Got unknown Terminal type: {0}", tt);
                                    if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand)
                                    {
                                        this.sender.SendFailMessage("Got unknown terminal type", tt);
                                    }
                                }
                            }
                            else
                            {
                                Console.WriteLine("Terminal type: {0}", tt);
                                Console.WriteLine("WTF!!!!");
                                if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand)
                                {
                                    this.sender.SendFailMessage("Unable to decode terminal type", tt);
                                }
                            }



                            break;

                        case TelnetOption.Charset:
                            Console.WriteLine("Charset");
                            break;
                        }
                        break;
                    }
                }
            }

            //Console.WriteLine("----------------");
        }