diff --git a/Packet++/header/TelnetLayer.h b/Packet++/header/TelnetLayer.h index c2795b613e..571cbd6697 100644 --- a/Packet++/header/TelnetLayer.h +++ b/Packet++/header/TelnetLayer.h @@ -42,7 +42,7 @@ class TelnetLayer : public Layer /** * Telnet Command Indicator */ - enum TelnetCommand + enum class TelnetCommand : int { /// Indicator to parser reached end of packet TelnetCommandEndOfPacket = -1, @@ -103,7 +103,7 @@ class TelnetLayer : public Layer /** * Telnet Options */ - enum TelnetOption + enum class TelnetOption : int { /// Internal return for no option detected TelnetOptionNoOption = -1, diff --git a/Packet++/src/TelnetLayer.cpp b/Packet++/src/TelnetLayer.cpp index 6804bc1c1c..3f0e58b272 100644 --- a/Packet++/src/TelnetLayer.cpp +++ b/Packet++/src/TelnetLayer.cpp @@ -14,7 +14,7 @@ namespace pcpp bool TelnetLayer::isDataField(uint8_t *pos) const { // "FF FF" means data - return pos[0] != InterpretAsCommand || pos[1] == InterpretAsCommand; + return pos[0] != static_cast(TelnetCommand::InterpretAsCommand) || pos[1] == static_cast(TelnetCommand::InterpretAsCommand); } bool TelnetLayer::isCommandField(uint8_t *pos) const @@ -33,14 +33,14 @@ size_t TelnetLayer::distanceToNextIAC(uint8_t *startPos, size_t maxLength) if (addition) addition += 2; - pos = (uint8_t *)memchr(startPos + currentOffset + 1, InterpretAsCommand, maxLength - currentOffset); + pos = (uint8_t *)memchr(startPos + currentOffset + 1, static_cast(TelnetCommand::InterpretAsCommand), maxLength - currentOffset); if (pos) addition += pos - (startPos + currentOffset); else addition += maxLength - currentOffset; currentOffset = currentOffset + addition; // "FF FF" means data continue - } while (pos && (pos[1] == InterpretAsCommand) && (currentOffset < maxLength)); + } while (pos && (pos[1] == static_cast(TelnetCommand::InterpretAsCommand)) && (currentOffset < maxLength)); return addition; } @@ -48,13 +48,13 @@ size_t TelnetLayer::distanceToNextIAC(uint8_t *startPos, size_t maxLength) size_t TelnetLayer::getFieldLen(uint8_t *startPos, size_t maxLength) { // Check first byte is IAC - if (startPos && (startPos[0] == InterpretAsCommand) && (maxLength >= 2)) + if (startPos && (startPos[0] == static_cast(TelnetCommand::InterpretAsCommand)) && (maxLength >= 2)) { // If subnegotiation parse until next IAC - if (startPos[1] == Subnegotiation) + if (startPos[1] == static_cast(TelnetCommand::Subnegotiation)) return distanceToNextIAC(startPos, maxLength); // Only WILL, WONT, DO, DONT have option. Ref http://pcmicro.com/netfoss/telnet.html - else if (startPos[1] >= WillPerform && startPos[1] <= DontPerform) + else if (startPos[1] >= static_cast(TelnetCommand::WillPerform) && startPos[1] <= static_cast(TelnetCommand::DontPerform)) return 3; return 2; } @@ -97,14 +97,14 @@ uint8_t *TelnetLayer::getNextCommandField(uint8_t *pos, size_t len) int16_t TelnetLayer::getSubCommand(uint8_t *pos, size_t len) { - if (len < 3 || pos[1] < Subnegotiation) - return TelnetOptionNoOption; + if (len < 3 || pos[1] < static_cast(TelnetCommand::Subnegotiation)) + return static_cast(TelnetOption::TelnetOptionNoOption); return pos[2]; } uint8_t *TelnetLayer::getCommandData(uint8_t *pos, size_t &len) { - if (pos[1] == Subnegotiation && len > 3) + if (pos[1] == static_cast(TelnetCommand::Subnegotiation) && len > 3) { len -= 3; return &pos[3]; @@ -161,11 +161,11 @@ size_t TelnetLayer::getTotalNumberOfCommands() size_t TelnetLayer::getNumberOfCommands(TelnetCommand command) { - if (command < 0) + if (static_cast(command) < 0) return 0; size_t ctr = 0; - if (isCommandField(m_Data) && m_Data[1] == command) + if (isCommandField(m_Data) && m_Data[1] == static_cast(command)) ++ctr; uint8_t *pos = m_Data; @@ -173,7 +173,7 @@ size_t TelnetLayer::getNumberOfCommands(TelnetCommand command) { size_t offset = pos - m_Data; pos = getNextCommandField(pos, m_DataLen - offset); - if (pos && pos[1] == command) + if (pos && pos[1] == static_cast(command)) ++ctr; } @@ -190,7 +190,7 @@ TelnetLayer::TelnetCommand TelnetLayer::getFirstCommand() uint8_t *pos = getNextCommandField(m_Data, m_DataLen); if (pos) return static_cast(pos[1]); - return TelnetCommandEndOfPacket; + return TelnetCommand::TelnetCommandEndOfPacket; } TelnetLayer::TelnetCommand TelnetLayer::getNextCommand() @@ -209,7 +209,7 @@ TelnetLayer::TelnetCommand TelnetLayer::getNextCommand() return static_cast(pos[1]); } lastPositionOffset = SIZE_MAX; - return TelnetCommandEndOfPacket; + return TelnetCommand::TelnetCommandEndOfPacket; } TelnetLayer::TelnetOption TelnetLayer::getOption() @@ -217,19 +217,19 @@ TelnetLayer::TelnetOption TelnetLayer::getOption() if (lastPositionOffset < m_DataLen) return static_cast(getSubCommand( &m_Data[lastPositionOffset], getFieldLen(&m_Data[lastPositionOffset], m_DataLen - lastPositionOffset))); - return TelnetOptionNoOption; + return TelnetOption::TelnetOptionNoOption; } TelnetLayer::TelnetOption TelnetLayer::getOption(TelnetCommand command) { // Check input - if (command < 0) + if (static_cast(command) < 0) { PCPP_LOG_ERROR("Command type can't be negative"); - return TelnetOptionNoOption; + return TelnetOption::TelnetOptionNoOption; } - if (isCommandField(m_Data) && m_Data[1] == command) + if (isCommandField(m_Data) && m_Data[1] == static_cast(command)) return static_cast(getSubCommand(m_Data, getFieldLen(m_Data, m_DataLen))); uint8_t *pos = m_Data; @@ -238,12 +238,12 @@ TelnetLayer::TelnetOption TelnetLayer::getOption(TelnetCommand command) size_t offset = pos - m_Data; pos = getNextCommandField(pos, m_DataLen - offset); - if (pos && pos[1] == command) + if (pos && pos[1] == static_cast(command)) return static_cast(getSubCommand(pos, getFieldLen(pos, m_DataLen - offset))); } PCPP_LOG_DEBUG("Can't find requested command"); - return TelnetOptionNoOption; + return TelnetOption::TelnetOptionNoOption; } uint8_t *TelnetLayer::getOptionData(size_t &length) @@ -262,14 +262,14 @@ uint8_t *TelnetLayer::getOptionData(size_t &length) uint8_t *TelnetLayer::getOptionData(TelnetCommand command, size_t &length) { // Check input - if (command < 0) + if (static_cast(command) < 0) { PCPP_LOG_ERROR("Command type can't be negative"); length = 0; return nullptr; } - if (isCommandField(m_Data) && m_Data[1] == command) + if (isCommandField(m_Data) && m_Data[1] == static_cast(command)) { size_t lenBuffer = getFieldLen(m_Data, m_DataLen); uint8_t *posBuffer = getCommandData(m_Data, lenBuffer); @@ -284,7 +284,7 @@ uint8_t *TelnetLayer::getOptionData(TelnetCommand command, size_t &length) size_t offset = pos - m_Data; pos = getNextCommandField(pos, m_DataLen - offset); - if (pos && pos[1] == command) + if (pos && pos[1] == static_cast(command)) { size_t lenBuffer = getFieldLen(m_Data, m_DataLen); uint8_t *posBuffer = getCommandData(m_Data, lenBuffer); @@ -303,47 +303,47 @@ std::string TelnetLayer::getTelnetCommandAsString(TelnetCommand val) { switch (val) { - case TelnetCommandEndOfPacket: + case TelnetCommand::TelnetCommandEndOfPacket: return "Reached end of packet while parsing"; - case EndOfFile: + case TelnetCommand::EndOfFile: return "End of File"; - case Suspend: + case TelnetCommand::Suspend: return "Suspend current process"; - case Abort: + case TelnetCommand::Abort: return "Abort Process"; - case EndOfRecordCommand: + case TelnetCommand::EndOfRecordCommand: return "End of Record"; - case SubnegotiationEnd: + case TelnetCommand::SubnegotiationEnd: return "Subnegotiation End"; - case NoOperation: + case TelnetCommand::NoOperation: return "No Operation"; - case DataMark: + case TelnetCommand::DataMark: return "Data Mark"; - case Break: + case TelnetCommand::Break: return "Break"; - case InterruptProcess: + case TelnetCommand::InterruptProcess: return "Interrupt Process"; - case AbortOutput: + case TelnetCommand::AbortOutput: return "Abort Output"; - case AreYouThere: + case TelnetCommand::AreYouThere: return "Are You There"; - case EraseCharacter: + case TelnetCommand::EraseCharacter: return "Erase Character"; - case EraseLine: + case TelnetCommand::EraseLine: return "Erase Line"; - case GoAhead: + case TelnetCommand::GoAhead: return "Go Ahead"; - case Subnegotiation: + case TelnetCommand::Subnegotiation: return "Subnegotiation"; - case WillPerform: + case TelnetCommand::WillPerform: return "Will Perform"; - case WontPerform: + case TelnetCommand::WontPerform: return "Wont Perform"; - case DoPerform: + case TelnetCommand::DoPerform: return "Do Perform"; - case DontPerform: + case TelnetCommand::DontPerform: return "Dont Perform"; - case InterpretAsCommand: + case TelnetCommand::InterpretAsCommand: return "Interpret As Command"; default: return "Unknown Command"; @@ -354,115 +354,115 @@ std::string TelnetLayer::getTelnetOptionAsString(TelnetOption val) { switch (val) { - case TelnetOptionNoOption: + case TelnetOption::TelnetOptionNoOption: return "No option for this command"; - case TransmitBinary: + case TelnetOption::TransmitBinary: return "Binary Transmission"; - case Echo: + case TelnetOption::Echo: return "Echo"; - case Reconnection: + case TelnetOption::Reconnection: return "Reconnection"; - case SuppressGoAhead: + case TelnetOption::SuppressGoAhead: return "Suppress Go Ahead"; - case ApproxMsgSizeNegotiation: + case TelnetOption::ApproxMsgSizeNegotiation: return "Negotiate approximate message size"; - case Status: + case TelnetOption::Status: return "Status"; - case TimingMark: + case TelnetOption::TimingMark: return "Timing Mark"; - case RemoteControlledTransAndEcho: + case TelnetOption::RemoteControlledTransAndEcho: return "Remote Controlled Transmission and Echo"; - case OutputLineWidth: + case TelnetOption::OutputLineWidth: return "Output Line Width"; - case OutputPageSize: + case TelnetOption::OutputPageSize: return "Output Page Size"; - case OutputCarriageReturnDisposition: + case TelnetOption::OutputCarriageReturnDisposition: return "Negotiate About Output Carriage-Return Disposition"; - case OutputHorizontalTabStops: + case TelnetOption::OutputHorizontalTabStops: return "Negotiate About Output Horizontal Tabstops"; - case OutputHorizontalTabDisposition: + case TelnetOption::OutputHorizontalTabDisposition: return "Negotiate About Output Horizontal Tab Disposition"; - case OutputFormfeedDisposition: + case TelnetOption::OutputFormfeedDisposition: return "Negotiate About Output Formfeed Disposition"; - case OutputVerticalTabStops: + case TelnetOption::OutputVerticalTabStops: return "Negotiate About Vertical Tabstops"; - case OutputVerticalTabDisposition: + case TelnetOption::OutputVerticalTabDisposition: return "Negotiate About Output Vertcial Tab Disposition"; - case OutputLinefeedDisposition: + case TelnetOption::OutputLinefeedDisposition: return "Negotiate About Output Linefeed Disposition"; - case ExtendedASCII: + case TelnetOption::ExtendedASCII: return "Extended ASCII"; - case Logout: + case TelnetOption::Logout: return "Logout"; - case ByteMacro: + case TelnetOption::ByteMacro: return "Byte Macro"; - case DataEntryTerminal: + case TelnetOption::DataEntryTerminal: return "Data Entry Terminal"; - case SUPDUP: + case TelnetOption::SUPDUP: return "SUPDUP"; - case SUPDUPOutput: + case TelnetOption::SUPDUPOutput: return "SUPDUP Output"; - case SendLocation: + case TelnetOption::SendLocation: return "Send Location"; - case TerminalType: + case TelnetOption::TerminalType: return "Terminal Type"; - case EndOfRecordOption: + case TelnetOption::EndOfRecordOption: return "End Of Record"; - case TACACSUserIdentification: + case TelnetOption::TACACSUserIdentification: return "TACACS User Identification"; - case OutputMarking: + case TelnetOption::OutputMarking: return "Output Marking"; - case TerminalLocationNumber: + case TelnetOption::TerminalLocationNumber: return "Terminal Location Number"; - case Telnet3270Regime: + case TelnetOption::Telnet3270Regime: return "Telnet 3270 Regime"; - case X3Pad: + case TelnetOption::X3Pad: return "X3 Pad"; - case NegotiateAboutWindowSize: + case TelnetOption::NegotiateAboutWindowSize: return "Negotiate About Window Size"; - case TerminalSpeed: + case TelnetOption::TerminalSpeed: return "Terminal Speed"; - case RemoteFlowControl: + case TelnetOption::RemoteFlowControl: return "Remote Flow Control"; - case Linemode: + case TelnetOption::Linemode: return "Line mode"; - case XDisplayLocation: + case TelnetOption::XDisplayLocation: return "X Display Location"; - case EnvironmentOption: + case TelnetOption::EnvironmentOption: return "Environment Option"; - case AuthenticationOption: + case TelnetOption::AuthenticationOption: return "Authentication Option"; - case EncryptionOption: + case TelnetOption::EncryptionOption: return "Encryption Option"; - case NewEnvironmentOption: + case TelnetOption::NewEnvironmentOption: return "New Environment Option"; - case TN3270E: + case TelnetOption::TN3270E: return "TN3270E"; - case XAuth: + case TelnetOption::XAuth: return "X Server Authentication"; - case Charset: + case TelnetOption::Charset: return "Charset"; - case TelnetRemoteSerialPort: + case TelnetOption::TelnetRemoteSerialPort: return "Telnet Remote Serial Port"; - case ComPortControlOption: + case TelnetOption::ComPortControlOption: return "Com Port Control Option"; - case TelnetSuppressLocalEcho: + case TelnetOption::TelnetSuppressLocalEcho: return "Telnet Suppress Local Echo"; - case TelnetStartTLS: + case TelnetOption::TelnetStartTLS: return "Telnet Start TLS"; - case Kermit: + case TelnetOption::Kermit: return "Kermit"; - case SendURL: + case TelnetOption::SendURL: return "Send URL"; - case ForwardX: + case TelnetOption::ForwardX: return "Forward X Server"; - case TelOptPragmaLogon: + case TelnetOption::TelOptPragmaLogon: return "Telnet Option Pragma Logon"; - case TelOptSSPILogon: + case TelnetOption::TelOptSSPILogon: return "Telnet Option SSPI Logon"; - case TelOptPragmaHeartbeat: + case TelnetOption::TelOptPragmaHeartbeat: return "Telnet Option Pragma Heartbeat"; - case ExtendedOptions: + case TelnetOption::ExtendedOptions: return "Extended option list"; default: return "Unknown Option"; diff --git a/Tests/Packet++Test/Tests/TelnetTests.cpp b/Tests/Packet++Test/Tests/TelnetTests.cpp index 0735f7834c..58b95fe24e 100644 --- a/Tests/Packet++Test/Tests/TelnetTests.cpp +++ b/Tests/Packet++Test/Tests/TelnetTests.cpp @@ -24,47 +24,58 @@ PTF_TEST_CASE(TelnetCommandParsingTests) PTF_ASSERT_EQUAL(telnetLayer->getDataAsString(), ""); PTF_ASSERT_EQUAL(telnetLayer->getTotalNumberOfCommands(), 8); - PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::WillPerform), 1); - PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::DoPerform), 5); - PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::SubnegotiationEnd), 1); + PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::TelnetCommand::WillPerform), 1); + PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::TelnetCommand::DoPerform), 5); + PTF_ASSERT_EQUAL(telnetLayer->getNumberOfCommands(pcpp::TelnetLayer::TelnetCommand::SubnegotiationEnd), 1); - PTF_ASSERT_EQUAL(telnetLayer->getFirstCommand(), pcpp::TelnetLayer::WillPerform); + PTF_ASSERT_EQUAL(telnetLayer->getFirstCommand(), pcpp::TelnetLayer::TelnetCommand::WillPerform, enumclass); - PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::WillPerform), pcpp::TelnetLayer::SuppressGoAhead); - PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::DoPerform), pcpp::TelnetLayer::TerminalType); - PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::AreYouThere), pcpp::TelnetLayer::TelnetOptionNoOption); + PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::TelnetCommand::WillPerform), + pcpp::TelnetLayer::TelnetOption::SuppressGoAhead, enumclass); + PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::TelnetCommand::DoPerform), + pcpp::TelnetLayer::TelnetOption::TerminalType, enumclass); + PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::TelnetCommand::AreYouThere), + pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption, enumclass); // Check iteration - pcpp::TelnetLayer::TelnetCommand vCommand[] = { - pcpp::TelnetLayer::WillPerform, pcpp::TelnetLayer::DoPerform, pcpp::TelnetLayer::DoPerform, - pcpp::TelnetLayer::DoPerform, pcpp::TelnetLayer::DoPerform, pcpp::TelnetLayer::DoPerform, - pcpp::TelnetLayer::Subnegotiation, pcpp::TelnetLayer::SubnegotiationEnd}; - pcpp::TelnetLayer::TelnetOption vOptions[] = {pcpp::TelnetLayer::SuppressGoAhead, - pcpp::TelnetLayer::TerminalType, - pcpp::TelnetLayer::NegotiateAboutWindowSize, - pcpp::TelnetLayer::TerminalSpeed, - pcpp::TelnetLayer::RemoteFlowControl, - pcpp::TelnetLayer::Linemode, - pcpp::TelnetLayer::Linemode, - pcpp::TelnetLayer::TelnetOptionNoOption}; - std::string vCommandString[] = {"Will Perform", "Do Perform", "Do Perform", "Do Perform", - "Do Perform", "Do Perform", "Subnegotiation", "Subnegotiation End"}; - std::string vOptionString[] = { + std::vector vCommand = { + pcpp::TelnetLayer::TelnetCommand::WillPerform, + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::Subnegotiation, + pcpp::TelnetLayer::TelnetCommand::SubnegotiationEnd}; + + std::vector vOptions = { + pcpp::TelnetLayer::TelnetOption::SuppressGoAhead, + pcpp::TelnetLayer::TelnetOption::TerminalType, + pcpp::TelnetLayer::TelnetOption::NegotiateAboutWindowSize, + pcpp::TelnetLayer::TelnetOption::TerminalSpeed, + pcpp::TelnetLayer::TelnetOption::RemoteFlowControl, + pcpp::TelnetLayer::TelnetOption::Linemode, + pcpp::TelnetLayer::TelnetOption::Linemode, + pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption}; + + std::vector vCommandString = {"Will Perform", "Do Perform", "Do Perform", "Do Perform", + "Do Perform", "Do Perform", "Subnegotiation", "Subnegotiation End"}; + std::vector vOptionString = { "Suppress Go Ahead", "Terminal Type", "Negotiate About Window Size", "Terminal Speed", "Remote Flow Control", - "Line mode", "Line mode", "No option for this command"}; + "Line mode", "Line mode", "No option for this command"}; size_t ctr = 0; size_t length = 0; pcpp::TelnetLayer::TelnetCommand commandVal = telnetLayer->getNextCommand(); - while (commandVal != pcpp::TelnetLayer::TelnetCommandEndOfPacket) + while (commandVal != pcpp::TelnetLayer::TelnetCommand::TelnetCommandEndOfPacket) { // Check command - PTF_ASSERT_EQUAL(commandVal, vCommand[ctr]); + PTF_ASSERT_EQUAL(commandVal, vCommand[ctr], enumclass); PTF_ASSERT_EQUAL(telnetLayer->getTelnetCommandAsString(commandVal), vCommandString[ctr]); // Check option pcpp::TelnetLayer::TelnetOption option = telnetLayer->getOption(); - PTF_ASSERT_EQUAL(option, vOptions[ctr]); + PTF_ASSERT_EQUAL(option, vOptions[ctr], enumclass); PTF_ASSERT_EQUAL(telnetLayer->getTelnetOptionAsString(option), vOptionString[ctr]); // Check option data @@ -97,18 +108,23 @@ PTF_TEST_CASE(TelnetCommandParsingTests) PTF_ASSERT_EQUAL(telnetLayer2->getDataAsString(), "@"); PTF_ASSERT_EQUAL(telnetLayer2->getTotalNumberOfCommands(), 3); - pcpp::TelnetLayer::TelnetCommand vCommand2[] = {pcpp::TelnetLayer::DoPerform, pcpp::TelnetLayer::WillPerform, - pcpp::TelnetLayer::EndOfRecordCommand}; - pcpp::TelnetLayer::TelnetOption vOptions2[] = { - pcpp::TelnetLayer::TransmitBinary, pcpp::TelnetLayer::TransmitBinary, pcpp::TelnetLayer::TelnetOptionNoOption}; + std::vector vCommand2 = { + pcpp::TelnetLayer::TelnetCommand::DoPerform, + pcpp::TelnetLayer::TelnetCommand::WillPerform, + pcpp::TelnetLayer::TelnetCommand::EndOfRecordCommand}; + + std::vector vOptions2 = { + pcpp::TelnetLayer::TelnetOption::TransmitBinary, + pcpp::TelnetLayer::TelnetOption::TransmitBinary, + pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption}; size_t ctr2 = 0; size_t length2 = 0; pcpp::TelnetLayer::TelnetCommand commandVal2 = telnetLayer2->getNextCommand(); - while (commandVal2 != pcpp::TelnetLayer::TelnetCommandEndOfPacket) + while (commandVal2 != pcpp::TelnetLayer::TelnetCommand::TelnetCommandEndOfPacket) { - PTF_ASSERT_EQUAL(commandVal2, vCommand2[ctr2]); - PTF_ASSERT_EQUAL(telnetLayer2->getOption(), vOptions2[ctr2]); + PTF_ASSERT_EQUAL(commandVal2, vCommand2[ctr2], enumclass); + PTF_ASSERT_EQUAL(telnetLayer2->getOption(), vOptions2[ctr2], enumclass); // Check option data PTF_ASSERT_NULL(telnetLayer2->getOptionData(length2)); @@ -133,14 +149,111 @@ PTF_TEST_CASE(TelnetCommandParsingTests) "expired.Login using username and passwordWelcome to Microsoft Telnet Service login: "); PTF_ASSERT_EQUAL(telnetLayer3->getTotalNumberOfCommands(), 2); - PTF_ASSERT_EQUAL(telnetLayer3->getNumberOfCommands(pcpp::TelnetLayer::Subnegotiation), 1); - PTF_ASSERT_EQUAL(telnetLayer3->getNumberOfCommands(pcpp::TelnetLayer::SubnegotiationEnd), 1); + PTF_ASSERT_EQUAL(telnetLayer3->getNumberOfCommands(pcpp::TelnetLayer::TelnetCommand::Subnegotiation), 1); + PTF_ASSERT_EQUAL(telnetLayer3->getNumberOfCommands(pcpp::TelnetLayer::TelnetCommand::SubnegotiationEnd), 1); - PTF_ASSERT_EQUAL(telnetLayer3->getOption(pcpp::TelnetLayer::Subnegotiation), - pcpp::TelnetLayer::AuthenticationOption); - PTF_ASSERT_EQUAL(telnetLayer3->getOption(pcpp::TelnetLayer::SubnegotiationEnd), - pcpp::TelnetLayer::TelnetOptionNoOption); + PTF_ASSERT_EQUAL(telnetLayer3->getOption(pcpp::TelnetLayer::TelnetCommand::Subnegotiation), + pcpp::TelnetLayer::TelnetOption::AuthenticationOption, enumclass); + PTF_ASSERT_EQUAL(telnetLayer3->getOption(pcpp::TelnetLayer::TelnetCommand::SubnegotiationEnd), + pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption, enumclass); PTF_ASSERT_EQUAL(telnetLayer3->toString(), "Telnet Control"); + + // Commands + std::vector> possibleCommands = { + {static_cast(0), "Unknown Command"}, + {pcpp::TelnetLayer::TelnetCommand::TelnetCommandEndOfPacket, "Reached end of packet while parsing"}, + {pcpp::TelnetLayer::TelnetCommand::EndOfFile, "End of File"}, + {pcpp::TelnetLayer::TelnetCommand::Suspend, "Suspend current process"}, + {pcpp::TelnetLayer::TelnetCommand::Abort, "Abort Process"}, + {pcpp::TelnetLayer::TelnetCommand::EndOfRecordCommand, "End of Record"}, + {pcpp::TelnetLayer::TelnetCommand::SubnegotiationEnd, "Subnegotiation End"}, + {pcpp::TelnetLayer::TelnetCommand::NoOperation, "No Operation"}, + {pcpp::TelnetLayer::TelnetCommand::DataMark, "Data Mark"}, + {pcpp::TelnetLayer::TelnetCommand::Break, "Break"}, + {pcpp::TelnetLayer::TelnetCommand::InterruptProcess, "Interrupt Process"}, + {pcpp::TelnetLayer::TelnetCommand::AbortOutput, "Abort Output"}, + {pcpp::TelnetLayer::TelnetCommand::AreYouThere, "Are You There"}, + {pcpp::TelnetLayer::TelnetCommand::EraseCharacter, "Erase Character"}, + {pcpp::TelnetLayer::TelnetCommand::EraseLine, "Erase Line"}, + {pcpp::TelnetLayer::TelnetCommand::GoAhead, "Go Ahead"}, + {pcpp::TelnetLayer::TelnetCommand::Subnegotiation, "Subnegotiation"}, + {pcpp::TelnetLayer::TelnetCommand::WillPerform, "Will Perform"}, + {pcpp::TelnetLayer::TelnetCommand::WontPerform, "Wont Perform"}, + {pcpp::TelnetLayer::TelnetCommand::DoPerform, "Do Perform"}, + {pcpp::TelnetLayer::TelnetCommand::DontPerform, "Dont Perform"}, + {pcpp::TelnetLayer::TelnetCommand::InterpretAsCommand, "Interpret As Command"}}; + + for (const auto &entry : possibleCommands) + { + PTF_ASSERT_EQUAL(pcpp::TelnetLayer::getTelnetCommandAsString(entry.first), entry.second); + } + + // Options + std::vector> possibleOptions = { + {static_cast(-10), "Unknown Option"}, + {pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption, "No option for this command"}, + {pcpp::TelnetLayer::TelnetOption::TransmitBinary, "Binary Transmission"}, + {pcpp::TelnetLayer::TelnetOption::Echo, "Echo"}, + {pcpp::TelnetLayer::TelnetOption::Reconnection, "Reconnection"}, + {pcpp::TelnetLayer::TelnetOption::SuppressGoAhead, "Suppress Go Ahead"}, + {pcpp::TelnetLayer::TelnetOption::ApproxMsgSizeNegotiation, "Negotiate approximate message size"}, + {pcpp::TelnetLayer::TelnetOption::Status, "Status"}, + {pcpp::TelnetLayer::TelnetOption::TimingMark, "Timing Mark"}, + {pcpp::TelnetLayer::TelnetOption::RemoteControlledTransAndEcho, "Remote Controlled Transmission and Echo"}, + {pcpp::TelnetLayer::TelnetOption::OutputLineWidth, "Output Line Width"}, + {pcpp::TelnetLayer::TelnetOption::OutputPageSize, "Output Page Size"}, + {pcpp::TelnetLayer::TelnetOption::OutputCarriageReturnDisposition, + "Negotiate About Output Carriage-Return Disposition"}, + {pcpp::TelnetLayer::TelnetOption::OutputHorizontalTabStops, "Negotiate About Output Horizontal Tabstops"}, + {pcpp::TelnetLayer::TelnetOption::OutputHorizontalTabDisposition, + "Negotiate About Output Horizontal Tab Disposition"}, + {pcpp::TelnetLayer::TelnetOption::OutputFormfeedDisposition, "Negotiate About Output Formfeed Disposition"}, + {pcpp::TelnetLayer::TelnetOption::OutputVerticalTabStops, "Negotiate About Vertical Tabstops"}, + {pcpp::TelnetLayer::TelnetOption::OutputVerticalTabDisposition, + "Negotiate About Output Vertcial Tab Disposition"}, + {pcpp::TelnetLayer::TelnetOption::OutputLinefeedDisposition, "Negotiate About Output Linefeed Disposition"}, + {pcpp::TelnetLayer::TelnetOption::ExtendedASCII, "Extended ASCII"}, + {pcpp::TelnetLayer::TelnetOption::Logout, "Logout"}, + {pcpp::TelnetLayer::TelnetOption::ByteMacro, "Byte Macro"}, + {pcpp::TelnetLayer::TelnetOption::DataEntryTerminal, "Data Entry Terminal"}, + {pcpp::TelnetLayer::TelnetOption::SUPDUP, "SUPDUP"}, + {pcpp::TelnetLayer::TelnetOption::SUPDUPOutput, "SUPDUP Output"}, + {pcpp::TelnetLayer::TelnetOption::SendLocation, "Send Location"}, + {pcpp::TelnetLayer::TelnetOption::TerminalType, "Terminal Type"}, + {pcpp::TelnetLayer::TelnetOption::EndOfRecordOption, "End Of Record"}, + {pcpp::TelnetLayer::TelnetOption::TACACSUserIdentification, "TACACS User Identification"}, + {pcpp::TelnetLayer::TelnetOption::OutputMarking, "Output Marking"}, + {pcpp::TelnetLayer::TelnetOption::TerminalLocationNumber, "Terminal Location Number"}, + {pcpp::TelnetLayer::TelnetOption::Telnet3270Regime, "Telnet 3270 Regime"}, + {pcpp::TelnetLayer::TelnetOption::X3Pad, "X3 Pad"}, + {pcpp::TelnetLayer::TelnetOption::NegotiateAboutWindowSize, "Negotiate About Window Size"}, + {pcpp::TelnetLayer::TelnetOption::TerminalSpeed, "Terminal Speed"}, + {pcpp::TelnetLayer::TelnetOption::RemoteFlowControl, "Remote Flow Control"}, + {pcpp::TelnetLayer::TelnetOption::Linemode, "Line mode"}, + {pcpp::TelnetLayer::TelnetOption::XDisplayLocation, "X Display Location"}, + {pcpp::TelnetLayer::TelnetOption::EnvironmentOption, "Environment Option"}, + {pcpp::TelnetLayer::TelnetOption::AuthenticationOption, "Authentication Option"}, + {pcpp::TelnetLayer::TelnetOption::EncryptionOption, "Encryption Option"}, + {pcpp::TelnetLayer::TelnetOption::NewEnvironmentOption, "New Environment Option"}, + {pcpp::TelnetLayer::TelnetOption::TN3270E, "TN3270E"}, + {pcpp::TelnetLayer::TelnetOption::XAuth, "X Server Authentication"}, + {pcpp::TelnetLayer::TelnetOption::Charset, "Charset"}, + {pcpp::TelnetLayer::TelnetOption::TelnetRemoteSerialPort, "Telnet Remote Serial Port"}, + {pcpp::TelnetLayer::TelnetOption::ComPortControlOption, "Com Port Control Option"}, + {pcpp::TelnetLayer::TelnetOption::TelnetSuppressLocalEcho, "Telnet Suppress Local Echo"}, + {pcpp::TelnetLayer::TelnetOption::TelnetStartTLS, "Telnet Start TLS"}, + {pcpp::TelnetLayer::TelnetOption::Kermit, "Kermit"}, + {pcpp::TelnetLayer::TelnetOption::SendURL, "Send URL"}, + {pcpp::TelnetLayer::TelnetOption::ForwardX, "Forward X Server"}, + {pcpp::TelnetLayer::TelnetOption::TelOptPragmaLogon, "Telnet Option Pragma Logon"}, + {pcpp::TelnetLayer::TelnetOption::TelOptSSPILogon, "Telnet Option SSPI Logon"}, + {pcpp::TelnetLayer::TelnetOption::TelOptPragmaHeartbeat, "Telnet Option Pragma Heartbeat"}, + {pcpp::TelnetLayer::TelnetOption::ExtendedOptions, "Extended option list"}}; + + for (const auto &entry : possibleOptions) + { + PTF_ASSERT_EQUAL(pcpp::TelnetLayer::getTelnetOptionAsString(entry.first), entry.second); + } } PTF_TEST_CASE(TelnetDataParsingTests)