/// <summary> /// 解析(SB) /// </summary> /// <param name="parseData"></param> /// <param name="index"></param> /// <returns></returns> private TelnetNegotiationInfomation ParseSB(byte[] parseData, ref int index) { // 返却オブジェクト生成 TelnetNegotiationInfomation negotiationInfomation = new TelnetNegotiationInfomation() { 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> /// 応答送信(SB) /// </summary> /// <param name="client"></param> /// <param name="info"></param> private void ResponseSB(Common.Net.TelnetClient client, TelnetNegotiationInfomation info) { // オプション毎に分岐 switch (info.Option) { case TelnetOption.terminal_type: // TODO:未実装 if (info.Stream.Length > 0 && info.Stream.ToArray()[0] == 0x01) { client.SendAsync(SendTerminalType()); } break; case TelnetOption.window_size: // TODO:未実装 client.SendAsync(SendWinSize()); break; case TelnetOption.terminal_speed: // TODO:未実装 if (info.Stream.Length > 0 && info.Stream.ToArray()[0] == 0x01) { client.SendAsync(SendTerminalSpeed()); } break; default: break; } }
/// <summary> /// コピーコンストラクタ /// </summary> /// <param name="info"></param> public TelnetNegotiationInfomation(TelnetNegotiationInfomation 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 TelnetNegotiationInfomation ParseSE(byte[] parseData, ref int index) { // 返却オブジェクト生成 TelnetNegotiationInfomation negotiationInfomation = new TelnetNegotiationInfomation() { Command = TelnetCommand.SE }; // インデックス更新 index++; // 返却 return(negotiationInfomation); }
/// <summary> /// 解析(WONT) /// </summary> /// <param name="parseData"></param> /// <param name="index"></param> /// <returns></returns> private TelnetNegotiationInfomation ParseWONT(byte[] parseData, ref int index) { // 返却オブジェクト生成 TelnetNegotiationInfomation negotiationInfomation = new TelnetNegotiationInfomation() { Command = TelnetCommand.WONT }; // インデックス更新 index++; // Telnetオプション設定 negotiationInfomation.Option = (TelnetOption)parseData[index++]; // 返却 return(negotiationInfomation); }
/// <summary> /// 解析 /// </summary> /// <param name="parseData"></param> /// <param name="stream"></param> /// <returns></returns> private List <TelnetNegotiationInfomation> Parse(byte[] parseData, MemoryStream stream) { // 返却オブジェクト生成 List <TelnetNegotiationInfomation> negotiationInfomations = new List <TelnetNegotiationInfomation>(); // 解析データ分繰返し for (int i = 0; i < parseData.Length;) { // データがIAC? if (parseData[i] == (byte)TelnetCommand.IAC) { // IAC解析 TelnetNegotiationInfomation negotiationInfomation = this.ParseIAC(parseData, ref i); if (negotiationInfomation != null) { // リスト追加 negotiationInfomations.Add(negotiationInfomation); } else { // 例外 throw new TelnetNetworkVirtualTerminalException("IAC解析に失敗しました"); } } else { // バッファに書込み stream.WriteByte(parseData[i++]); } } #if DEBUG if (negotiationInfomations != null) { foreach (TelnetNegotiationInfomation info in negotiationInfomations) { Debug.WriteLine("<解析情報>"); Debug.WriteLine(" └ {0} {1} {2}", info.IAC.ToString(), info.Command.ToString(), info.Option.ToString()); } } #endif // 返却 return(negotiationInfomations); }
/// <summary> /// 応答送信(SE) /// </summary> /// <param name="client"></param> /// <param name="info"></param> private void ResponseSE(Common.Net.TelnetClient client, TelnetNegotiationInfomation info) { }
/// <summary> /// 応答送信(WONT) /// </summary> /// <param name="client"></param> /// <param name="info"></param> private void ResponseWONT(Common.Net.TelnetClient client, TelnetNegotiationInfomation info) { if (info.Option <= TelnetOption.max) { switch (this.m_Remote[info.Option].Status) { case TelnetOptionStatus.Yes: this.m_Remote[info.Option].Status = TelnetOptionStatus.No; client.SendAsync(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; client.SendAsync(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 { client.SendAsync(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="client"></param> /// <param name="info"></param> private void ResponseDONT(Common.Net.TelnetClient client, TelnetNegotiationInfomation info) { if (info.Option <= TelnetOption.max) { switch (this.m_Local[info.Option].Status) { case TelnetOptionStatus.Yes: this.m_Local[info.Option].Status = TelnetOptionStatus.No; client.SendAsync(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; client.SendAsync(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 { client.SendAsync(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; } }
/// <summary> /// 応答送信(DO) /// </summary> /// <param name="client"></param> /// <param name="info"></param> private void ResponseDO(Common.Net.TelnetClient client, TelnetNegotiationInfomation 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; client.SendAsync(SendBack(TelnetCommand.WILL, info.Option)); } else { client.SendAsync(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; client.SendAsync(SendBack(TelnetCommand.WONT, info.Option)); break; } break; } } else { client.SendAsync(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) { client.SendAsync(SendWinSize()); } break; case TelnetOption.suppress_go_ahead: if (this.m_Local[TelnetOption.suppress_go_ahead].Status == TelnetOptionStatus.Yes) { this.m_TelLineMode = false; } break; } }