private void ProcessAndPostBytesReceived(byte[] recvBytes) { // load bytes received from the server into InputArray. var inputArray = new InputByteArray(recvBytes); WorkstationCommandList wipCmdList = null; bool badDataLogged = false; while (inputArray.IsEof() == false) { var rv = ParseAndPostInputArray(inputArray, wipCmdList); wipCmdList = rv.Item1; var gotSomething = rv.Item2; // nothing parsed. And there is data remaining. This is an error. if ((gotSomething == false) && (inputArray.IsEof() == false)) { if (badDataLogged == false) { LogBadData(inputArray); badDataLogged = true; } inputArray.GetByte(); // advance by 1 byte in byte stream. } } }
// EndTemp /// <summary> /// parse the byte array as a data stream containing a sequence of SCS control /// functions. ( text data is a /// </summary> /// <param name="InputArray"></param> /// <returns></returns> public static Tuple <ControlFunctionList, string> ParseDataStream(InputByteArray InputArray) { ControlFunctionList funcList = null; string errmsg = null; while (InputArray.IsEof() == false) { // check for IAC EOR var telCode = InputArray.PeekTelnetCommandCode(CommandCode.EOR); if (telCode != null) { break; } var func = ControlFunction.Factory(InputArray); if ((func == null) || (func.Errmsg != null)) { errmsg = "invalid control function. Postion:" + InputArray.Index + " invalid bytes:" + InputArray.PeekToEnd().Head(16).ToHex(' '); break; } if (funcList == null) { funcList = new ControlFunctionList(); } funcList.Add(func); } return(new Tuple <ControlFunctionList, string>(funcList, errmsg)); }
/// <summary> /// construct an OptionVariable starting at the next byte in the input array. /// </summary> /// <param name="ByteArray"></param> /// <returns></returns> public static OptionVariable Construct(InputByteArray InputArray) { OptionVariable optnVar = null; if (InputArray.IsEof() == false) { var b1 = InputArray.PeekNextByte(); var ev = b1.ToEnvironVarCode(); if (ev != null) { var varCode = ev.Value; if ((varCode == EnvironVarCode.VAR) || (varCode == EnvironVarCode.USERVAR)) { byte[] valueBytes = null; bool gotValue = false; // advance past the VAR or USERVAR code. InputArray.GetNextByte(); // isolate the name text which follows the VAR or USERVAR code. // ( return the stop code. But do not consume it. ) var rv = InputArray.GetBytesUntilCode( new byte[] { 0xff, 0x00, 0x01, 0x02, 0x03 }); var nameBytes = rv.Item1; var endAccumCode = rv.Item2.ToEnvironVarCode(); // the name text ends with VALUE marker. The text that follows is the text value // of the variable. if ((endAccumCode != null) && (endAccumCode.Value == EnvironVarCode.VALUE)) { gotValue = true; // advance past the VALUE var code. InputArray.GetNextByte(); // get the value bytes until end of value code. var rv2 = InputArray.GetBytesUntilCode( new byte[] { 0xff, 0x00, 0x01, 0x02, 0x03 }); valueBytes = rv2.Item1; } optnVar = new OptionVariable(varCode, nameBytes, valueBytes); if (gotValue == true) { optnVar.ValueEmpty = true; } } } } return(optnVar); }
public NullControlFunction(InputByteArray InputArray) : base(InputArray, ControlFunctionCode.Null) { var ba = new ByteArrayBuilder(); // isolate the series of null bytes. while (InputArray.IsEof() == false) { var b1 = InputArray.PeekByte(0); if (b1 != 0x00) { break; } // accum to array of null bytes. ba.Append(b1); InputArray.AdvanceIndex(1); } this.NullBytes = ba.ToByteArray(); }
/// <summary> /// look at the current bytes of the input array. Determine what type of data /// stream command is starting. /// </summary> /// <param name="InputArray"></param> /// <returns></returns> public static TypeServerData?PeekServerCommand( InputByteArray InputArray) { TypeServerData?typeData = null; if (InputArray.IsEof() == true) { typeData = TypeServerData.eof; } else if (InputArray.PeekTelnetCommandCode() != null) { typeData = TypeServerData.telnetCommand; } else if (InputArray.IsDataStreamHeader() == true) { typeData = TypeServerData.workstationHeader; } return(typeData); }
public TextControlFunction(InputByteArray InputArray) : base(InputArray, ControlFunctionCode.Text) { var ba = new ByteArrayBuilder(); // isolate the series of printable bytes. while (InputArray.IsEof() == false) { var b1 = InputArray.PeekByte(0); if (Array.IndexOf(ControlFunctionCodeExt.TextBytes, b1) == -1) { break; } // is a printable byte. accum to array of text bytes. ba.Append(b1); InputArray.AdvanceIndex(1); } this.TextBytes = ba.ToByteArray(); }
/// <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); }
/// <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) { lock (this.LockFlag) { this.Counter += 1; if (this.Counter > 7) { int cc = 3; } InputByteArray inputArray = new InputByteArray(Buffer, Length); while (inputArray.IsEof() == false) { TelnetStatement stmt = null; var escapeCmd = inputArray.PeekNextByte().ToTelnetCommand(); var dsHeader = DataStreamHeader.Factory(inputArray); IBM5250DataStreamCommand dataStreamCommand; if (dsHeader != null) { var s1 = dsHeader.ToString(); System.IO.File.AppendAllText( FilePath, Direction + " " + this.Counter.ToString() + " " + s1 + Environment.NewLine); this.CurrentDataStreamHeader = dsHeader; continue; } // an ibm 5250 data stream command. else if ((this.CurrentDataStreamHeader != null) && ((dataStreamCommand = IBM5250DataStreamCommand.Factory(inputArray)) != null)) { var s1 = dataStreamCommand.ToString(); System.IO.File.AppendAllText( FilePath, Direction + " " + this.Counter.ToString() + " " + s1 + Environment.NewLine); continue; } else if ((stmt = TelnetStatement.Factory(inputArray)) != null) { var s1 = stmt.ToString(); System.IO.File.AppendAllText( FilePath, Direction + " " + this.Counter.ToString() + " " + s1 + Environment.NewLine); continue; } else if ((escapeCmd != null) && (escapeCmd.Value == TelnetCommand.ESCAPE)) { var rv = TerminalVt100Statement.Factory(inputArray); var vtStmt = rv.Item1; var otStmt = rv.Item2; System.IO.File.AppendAllText( this.FilePath, Direction + " " + this.Counter.ToString() + " " + vtStmt.ToString() + Environment.NewLine); if (otStmt != null) { System.IO.File.AppendAllText( this.FilePath, Direction + " " + this.Counter.ToString() + " " + otStmt.ToString() + Environment.NewLine); } continue; } else { var remBytes = inputArray.GetBytesToEnd(); System.IO.File.AppendAllText( this.FilePath, Direction + " " + this.Counter.ToString() + " Raw bytes follow:" + Environment.NewLine); LogFile_WriteRawBytes(remBytes, this.FilePath); } } } }
ParseWorkstationCommandList( InputByteArray InputArray, SessionSettings SessionSettings) { var wrkstnCmdList = new WorkstationCommandList(); DataStreamHeader dsh = null; bool gotEOR = false; bool needMoreBytes = false; string errmsg = null; if (InputArray.IsDataStreamHeader()) { var rv = DataStreamHeader.Factory(InputArray); dsh = rv.Item1; errmsg = rv.Item2; } bool lastCmdWasTelnet_EOR = false; bool gotWorkstationCommand = true; gotEOR = false; while ((InputArray.IsEof( ) == false) && (gotEOR == false) && (gotWorkstationCommand == true)) { // no input data to process. lastCmdWasTelnet_EOR = false; gotWorkstationCommand = false; // check for IAC EOR var telCode = InputArray.PeekTelnetCommandCode(CommandCode.EOR); if (telCode != null) { var telCmd = InputArray.NextTelnetCommand(); lastCmdWasTelnet_EOR = true; gotEOR = true; } // process the input as workstation data stream commands. else { var rv = ParseAndProcessWorkstationCommand(InputArray); var workstationCommand = rv.Item1; var howRead = rv.Item2; if (workstationCommand != null) { wrkstnCmdList.Add(workstationCommand); gotWorkstationCommand = true; } } } // read available bytes from input stream. if (InputArray.IsEof() && (lastCmdWasTelnet_EOR == false)) { needMoreBytes = true; } return(new Tuple <DataStreamHeader, WorkstationCommandList, bool, bool>( dsh, wrkstnCmdList, gotEOR, needMoreBytes)); }