/// <summary> /// 解析(SB) /// </summary> /// <param name="parseData"></param> /// <param name="index"></param> /// <returns></returns> private NegotiationInfomation ParseSB(byte[] parseData, ref int index) { // 返却オブジェクト生成 NegotiationInfomation negotiationInfomation = new NegotiationInfomation() { Command = TelnetCommand.SB }; // インデックス更新 index++; // Telnetオプション設定 negotiationInfomation.Option = (TelnetOption)parseData[index++]; // インデックス繰り返し for (; index < parseData.Length; index++) { // 副交渉の終わり? if (parseData[index] == (byte)TelnetCommand.IAC && parseData[index + 1] == (byte)TelnetCommand.SE) { // 副交渉の終わりだった場合は繰り返し終了 break; } // データ部格納 if (negotiationInfomation.Stream == null) { negotiationInfomation.Stream = new MemoryStream(); } negotiationInfomation.Stream.WriteByte(parseData[index]); } // 返却 return(negotiationInfomation); }
/// <summary> /// 解析 /// </summary> /// <param name="parseData"></param> /// <param name="stream"></param> /// <returns></returns> private List <NegotiationInfomation> Parse(byte[] parseData, MemoryStream stream) { // 返却オブジェクト生成 List <NegotiationInfomation> negotiationInfomations = new List <NegotiationInfomation>(); // 解析データ分繰返し for (int i = 0; i < parseData.Length;) { // データがIAC? if (parseData[i] == (byte)TelnetCommand.IAC) { // IAC解析 NegotiationInfomation negotiationInfomation = this.ParseIAC(parseData, ref i); if (negotiationInfomation != null) { // リスト追加 this.Logger.Info(" " + negotiationInfomation.ToString()); negotiationInfomations.Add(negotiationInfomation); } else { // 例外 throw new NetworkVirtualTerminalException("IAC解析に失敗しました"); } } else { // バッファに書込み stream.WriteByte(parseData[i++]); } } // 返却 return(negotiationInfomations); }
/// <summary> /// 応答送信(SB) /// </summary> /// <param name="info"></param> private void ResponseSB(NegotiationInfomation info) { // オプション毎に分岐 switch (info.Option) { case TelnetOption.terminal_type: // TODO:未実装 if (info.Stream.Length > 0 && info.Stream.ToArray()[0] == 0x01) { this.SendTerminalType(); } break; case TelnetOption.window_size: // TODO:未実装 this.SendWinSize(); break; case TelnetOption.terminal_speed: // TODO:未実装 if (info.Stream.Length > 0 && info.Stream.ToArray()[0] == 0x01) { this.SendTerminalSpeed(); } break; default: break; } }
/// <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; }
/// <summary> /// 解析(SE) /// </summary> /// <param name="parseData"></param> /// <param name="index"></param> /// <returns></returns> private NegotiationInfomation ParseSE(byte[] parseData, ref int index) { // 返却オブジェクト生成 NegotiationInfomation negotiationInfomation = new NegotiationInfomation() { Command = TelnetCommand.SE }; // インデックス更新 index++; // 返却 return(negotiationInfomation); }
/// <summary> /// 解析(WONT) /// </summary> /// <param name="parseData"></param> /// <param name="index"></param> /// <returns></returns> private NegotiationInfomation ParseWONT(byte[] parseData, ref int index) { // 返却オブジェクト生成 NegotiationInfomation negotiationInfomation = new NegotiationInfomation() { Command = TelnetCommand.WONT }; // インデックス更新 index++; // Telnetオプション設定 negotiationInfomation.Option = (TelnetOption)parseData[index++]; // 返却 return(negotiationInfomation); }
/// <summary> /// 応答送信(DO) /// </summary> /// <param name="info"></param> private void ResponseDO(NegotiationInfomation info) { if (info.Option <= TelnetOption.max) { // オプション状態で分岐 switch (this.m_Local[info.Option].Status) { case TelnetOptionStatus.No: if (this.m_Local[info.Option].Accept) { this.m_Local[info.Option].Status = TelnetOptionStatus.Yes; SendBack(TelnetCommand.WILL, info.Option); } else { SendBack(TelnetCommand.WONT, info.Option); } break; case TelnetOptionStatus.WantNo: switch (this.m_Local[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Local[info.Option].Status = TelnetOptionStatus.No; break; case TelnetOptionQueue.Opposite: this.m_Local[info.Option].Status = TelnetOptionStatus.Yes; break; } break; case TelnetOptionStatus.WantYes: switch (this.m_Local[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Local[info.Option].Status = TelnetOptionStatus.Yes; break; case TelnetOptionQueue.Opposite: this.m_Local[info.Option].Status = TelnetOptionStatus.WantNo; this.m_Local[info.Option].Queue = TelnetOptionQueue.Empty; SendBack(TelnetCommand.WONT, info.Option); break; } break; } } else { SendBack(TelnetCommand.WONT, info.Option); } switch (info.Option) { case TelnetOption.binary: switch (this.m_Local[TelnetOption.binary].Status) { case TelnetOptionStatus.Yes: this.m_TelBinSend = true; break; case TelnetOptionStatus.No: this.m_TelBinSend = false; break; } break; case TelnetOption.window_size: if (this.m_Local[TelnetOption.window_size].Status == TelnetOptionStatus.Yes) { SendWinSize(); } break; case TelnetOption.suppress_go_ahead: if (this.m_Local[TelnetOption.suppress_go_ahead].Status == TelnetOptionStatus.Yes) { this.m_TelLineMode = false; } break; } }
/// <summary> /// 応答送信(SE) /// </summary> /// <param name="info"></param> private void ResponseSE(NegotiationInfomation info) { }
/// <summary> /// 応答送信(WONT) /// </summary> /// <param name="info"></param> private void ResponseWONT(NegotiationInfomation info) { if (info.Option <= TelnetOption.max) { switch (this.m_Remote[info.Option].Status) { case TelnetOptionStatus.Yes: this.m_Remote[info.Option].Status = TelnetOptionStatus.No; SendBack(TelnetCommand.DONT, info.Option); break; case TelnetOptionStatus.WantNo: switch (this.m_Remote[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Remote[info.Option].Status = TelnetOptionStatus.No; break; case TelnetOptionQueue.Opposite: this.m_Remote[info.Option].Status = TelnetOptionStatus.WantYes; this.m_Remote[info.Option].Queue = TelnetOptionQueue.Empty; SendBack(TelnetCommand.DO, info.Option); break; } break; case TelnetOptionStatus.WantYes: switch (this.m_Remote[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Remote[info.Option].Status = TelnetOptionStatus.No; break; case TelnetOptionQueue.Opposite: this.m_Remote[info.Option].Status = TelnetOptionStatus.No; this.m_Remote[info.Option].Queue = TelnetOptionQueue.Empty; break; } break; } } else { SendBack(TelnetCommand.DONT, info.Option); } switch (info.Option) { case TelnetOption.echo: if (this.m_TelEcho) { switch (this.m_Remote[TelnetOption.echo].Status) { case TelnetOptionStatus.Yes: this.m_LocalEcho = 0; break; case TelnetOptionStatus.No: this.m_LocalEcho = 1; break; } } if (this.m_Remote[TelnetOption.echo].Status == TelnetOptionStatus.Yes) { this.m_TelLineMode = false; } break; case TelnetOption.binary: switch (this.m_Remote[TelnetOption.binary].Status) { case TelnetOptionStatus.Yes: this.m_TelBinRecv = true; break; case TelnetOptionStatus.No: this.m_TelBinRecv = false; break; } break; } }
/// <summary> /// 応答送信(DONT) /// </summary> /// <param name="info"></param> private void ResponseDONT(NegotiationInfomation info) { if (info.Option <= TelnetOption.max) { switch (this.m_Local[info.Option].Status) { case TelnetOptionStatus.Yes: this.m_Local[info.Option].Status = TelnetOptionStatus.No; SendBack(TelnetCommand.WONT, info.Option); break; case TelnetOptionStatus.WantNo: switch (this.m_Local[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Local[info.Option].Status = TelnetOptionStatus.No; break; case TelnetOptionQueue.Opposite: this.m_Local[info.Option].Status = TelnetOptionStatus.WantYes; this.m_Local[info.Option].Queue = TelnetOptionQueue.Empty; SendBack(TelnetCommand.WILL, info.Option); break; } break; case TelnetOptionStatus.WantYes: switch (this.m_Local[info.Option].Queue) { case TelnetOptionQueue.Empty: this.m_Local[info.Option].Status = TelnetOptionStatus.No; break; case TelnetOptionQueue.Opposite: this.m_Local[info.Option].Status = TelnetOptionStatus.No; this.m_Local[info.Option].Queue = TelnetOptionQueue.Empty; break; } break; } } else { SendBack(TelnetCommand.WONT, info.Option); } switch (info.Option) { case TelnetOption.binary: switch (this.m_Local[TelnetOption.binary].Status) { case TelnetOptionStatus.Yes: this.m_TelBinSend = true; break; case TelnetOptionStatus.No: this.m_TelBinSend = false; break; } break; } }