БВТ1803 Пинг Код Подгруппа 1
.pdf#define DEBUG |
//define debug log |
#ifdef DEBUG |
|
#define LOGD(MSG) std::cout<<MSG<<std::endl; |
|
#else |
|
#define LOGD(MSG) |
|
#endif |
|
|
//LIBRARY DECLARATION |
|
// |
#include <string_view> |
//string library |
#include <regex> |
//regex library |
#include <chrono> |
//time library |
#include <filesystem> |
//library for working with file system |
#include <fstream> |
//library to file work |
#include <iostream> |
//console output library |
#include <errno.h> |
//library for fileerror cath |
#include "winsock2.h" |
//socket library |
#include "iphlpapi.h" |
//some library for net |
#include "icmpapi.h" |
//icmp library |
|
//DECLARATION OF GLOBAL VARIABLES |
|
// |
uint32_t errorCode, |
//Error code |
fErrorCode, |
//File error code |
countOfEchoRequest; |
//Number of echo requests |
std::string_view pathToLogFile; |
//Path to the log file |
char* innerBuffer; |
//Data buffer |
|
//Link library |
#pragma comment(lib, "IPHLPAPI.lib") |
//link icmpapi |
#pragma comment(lib, "Ws2_32.lib") |
//link winsock2 |
|
//FUNCTION DECLARATION |
|
// |
bool checkParams(int countOfArgs,char* args[]) |
//Checking input parameters |
{ |
|
LOGD("Enter in " << __func__ << " errorCode =" << |
|
errorCode << " CountOfArgs =" << countOfArgs); |
//DEBUG MESSAGE |
#ifdef DEBUG |
|
if (countOfArgs > 1) |
|
LOGD(" Addr =" << args[1]); |
|
for (size_t i = 0; i < countOfArgs; i++) |
|
LOGD(" el =" << args[i]); |
|
#endif |
|
if (countOfArgs != 2) |
//accept only one extra argument - IPV4 |
errorCode = 3; |
|
else if (!std::regex_match(*(args + 1), |
//check IPV4 format - from 0.0.0.0 to 255.255.255.255 |
std::regex{ "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$" })) |
|
errorCode = 4; |
|
LOGD("Leave " << __func__ << " errorCode =" << errorCode ); |
//DEBUG MESSAGE |
return errorCode != 0; |
|
} |
|
std::string paramError(char** argc) |
//Definition param error |
{ |
|
LOGD("Enter in " << __func__ << " errorCode ="<<errorCode); |
//DEBUG MESSAGE |
std::string result; |
//Create empty resulg info |
switch (errorCode) |
//Definition error |
{ |
|
case 3: |
|
result= std::to_string(errorCode)+ " Wrong count of args"; |
|
break; |
|
case 4: |
|
result = argc[1]; |
|
result +=' ' + std::to_string(errorCode) + " Wrong IP format"; |
|
break; |
|
default: |
|
result = std::to_string(errorCode) + " Unknown Error"; |
|
break; |
|
} |
|
LOGD("Leave " << __func__ << " Result =" << result); |
//DEBUG MESSAGE |
return result; |
|
} |
|
bool checkLog() |
/*Checking the existence of a |
|
log file*/ |
{ |
|
LOGD("Enter in " << __func__); |
//DEBUG MESSAGE |
LOGD("Leave " << __func__ << " Result =" << !std::filesystem::exists(pathToLogFile)); |
|
return !std::filesystem::exists(pathToLogFile); |
//check log |
} |
|
bool logFileCreate() |
//Create log file |
{ |
|
LOGD("Enter in " << __func__ << " fErrorCode =" << fErrorCode); |
//DEBUG MESSAGE |
std::ofstream fStream(pathToLogFile); |
//Create new log file |
if (fStream.fail()) |
|
fErrorCode = errno; |
//If error - save error code |
fStream.close(); |
|
//DEBUG MESSAGE LOGD("Leave " << __func__ << " fErrorCode =" << fErrorCode << " Result=" << (fErrorCode != 0)); return fErrorCode!=0;
} |
|
void LOGFILE_DIAGNOSTIC_ERROR() |
//Diagnosing a log error |
{ |
|
LOGD("Enter in " << __func__ << " fErrorCode =" <<fErrorCode); |
//DEBUG MESSAGE |
std::string result; |
//Create empty resulg info |
result = std::to_string(fErrorCode); |
|
switch (fErrorCode) |
//Definition error |
{ |
|
case EPERM: |
|
result.append(" The operation is not allowed"); |
|
break; |
|
case ENOENT: |
|
result.append(" There is no such file or directory."); |
|
break; |
|
case EBADF: |
|
result.append(" Bad file descriptor."); |
|
break; |
|
case EACCES: |
|
result.append(" Permission denied."); |
|
break; |
|
case EBUSY: |
|
result.append(" The device or resource is busy"); |
|
break; |
|
case EEXIST: |
|
result.append(" The file exists."); |
|
break; |
|
case EXDEV: |
|
result.append(" Invalid communication between devices."); |
|
break; |
|
case EMFILE: |
|
result.append(" There are too many open files."); |
|
break; |
|
case ENFILE: |
|
result.append(" There are too many open files in the system"); |
|
break; |
|
case ETXTBSY: |
|
result.append(" The text file is busy."); |
|
break; |
|
case EFBIG: |
|
result.append(" The file is too large."); |
|
break; |
|
case ENOSPC: |
|
result.append(" There is no free space left on the device."); |
|
break; |
|
case EROFS: |
|
result.append(" The file system is read-only."); |
|
break; |
|
default: |
|
result.append(" Unknown Error"); |
|
break; |
|
} |
|
std::cout << result << std::endl; |
|
LOGD("Leave " << __func__ << " Result ="<<result); |
//DEBUG MESSAGE |
}
/*Adding information to the log*/
bool addIntoLogFile(std::string_view output = "",char** ip = nullptr)
{
//DEBUG MESSAGE
LOGD("Enter in " << __func__ << " Input string ='" << output << "' errorCode =" << errorCode << " fErrorCode =" << fErrorCode);
std::time_t t; |
//Create base time struct |
std::tm* now; |
//Create advance time struct |
std::ostream* ostr; |
//pointer to ofstream/cout |
std::time(&t); |
|
now = std::localtime(&t); |
|
std::ofstream fStream(pathToLogFile, |
|
std::ios::out | std::ios::ate | std::ios::_Nocreate); |
//try to open file |
ostr = &fStream; |
|
if (fStream.fail()) |
//if smt wrong |
{ |
|
fErrorCode = errno; |
//save error |
ostr = &std::cout; |
//change outputStream to cout |
*ostr << "LOG ERROR\n"; |
|
} |
|
|
//outprint msg |
*ostr << '[' << now->tm_hour << ':' << now->tm_min << ':' << now->tm_sec << "] "; |
|
if (ip) |
//if we have ip - add |
*ostr << ip[1] << ' '; |
|
*ostr << output.data() << '\n'; |
|
fStream.close(); |
|
LOGD("Leave " << __func__ << " Input string ='" << output << "' errorCode =" //DEBUG MESSAGE << errorCode << " fErrorCode =" << fErrorCode << " Result =" << (fErrorCode != 0));
return fErrorCode!=0;
}
int echoRequest(std::string_view address) |
//Echo request |
{ |
|
|
//DEBUG MESSAGE |
LOGD("Enter in " << __func__ << "Address ='" << address << "' errorCode =" << errorCode); |
|
HANDLE hIcmpFile; |
//Build echo-request |
unsigned long ipaddr; |
//create destination addr |
uint64_t countOfAnswers, replySize; |
//count of answers and reply buffer size |
char sendData[32]; |
//send data |
std::size_t innerCounter; |
//number of requests made |
ipaddr = inet_addr(address.data()); |
|
countOfAnswers = innerCounter = 0; |
|
replySize = sizeof(ICMP_ECHO_REPLY) + sizeof(sendData); |
|
hIcmpFile = IcmpCreateFile(); |
//create a handler |
innerBuffer = new char[replySize]; |
//take memory |
do |
//try to send request |
{ |
|
countOfAnswers = IcmpSendEcho(hIcmpFile, ipaddr, sendData, sizeof(sendData),NULL, innerBuffer, replySize, 1000); ++innerCounter;
if (countOfAnswers) |
//If no answer |
{ |
|
LOGD("Leave " << __func__ << " Address =" << address |
//DEBUG MESSAGE |
<< " errorCode =" << errorCode << " Result =" << 0 |
|
return 0; |
|
//save errorcode //DEBUG MESSAGE
LOGD("Leave " << __func__ << " Address =" << address << " errorCode =" << errorCode << " Result =" << (errorCode == IP_REQ_TIMED_OUT ? 2 : 1));
return (errorCode == IP_REQ_TIMED_OUT ? 2 : 1);
} |
|
|
std::string echoError() |
|
/*Handling response/request |
|
|
error*/ |
{ |
|
|
LOGD("Enter in " << __func__ << " errorCode =" << errorCode); |
//DEBUG MESSAGE |
|
std::string result; |
//Create empty resulg info |
|
result = std::to_string(errorCode) + " "; |
|
|
switch (errorCode) |
|
//Definition error |
{ |
|
|
case IP_DEST_NET_UNREACHABLE: |
|
|
result= "The destination network was unreachable"; |
|
|
break; |
|
|
case IP_DEST_HOST_UNREACHABLE: |
|
|
result += |
"The destination host was unreachable"; |
|
break; |
|
|
case IP_DEST_PROT_UNREACHABLE: |
|
|
result += |
"The destination protocol was unreachable"; |
|
break; |
|
|
case IP_DEST_PORT_UNREACHABLE: |
|
|
result += |
"The destination port was unreachable"; |
|
break; |
|
|
case IP_NO_RESOURCES: |
|
|
result += |
"Insufficient IP resources were available"; |
|
break; |
|
|
case IP_BAD_OPTION: |
|
|
result += |
"A bad IP option was specified"; |
|
break; |
|
|
case IP_HW_ERROR: |
|
|
result += |
"A hardware error occurred"; |
|
break; |
|
|
case IP_PACKET_TOO_BIG: |
|
|
result += |
"The packet was too big"; |
|
break; |
|
|
case IP_BAD_REQ: |
|
|
result += |
"A bad request"; |
|
break; |
|
|
case IP_BAD_ROUTE: |
|
|
result += |
"A bad route"; |
|
break; |
|
|
case IP_TTL_EXPIRED_TRANSIT: |
|
|
result += |
"The time to live (TTL) expired in transit"; |
|
break; |
|
|
case IP_TTL_EXPIRED_REASSEM: |
|
|
result += |
"The time to live expired during fragment reassembly"; |
|
break; |
|
|
case IP_SOURCE_QUENCH: |
|
|
result += |
"Datagrams are arriving too fast to be processed and datagrams may have been discarded"; |
|
break; |
|
|
case IP_BAD_DESTINATION: |
|
|
result += |
"A bad destination"; |
|
break; |
|
|
case IP_GENERAL_FAILURE: |
|
|
result += |
"A general failure. This error can be returned for some malformed ICMP packets"; |
|
break; |
|
|
default: |
|
|
result += |
"Unknown error"; |
|
break; |
|
|
} |
|
|
LOGD("Leave " << __func__ << " Result =" << result); |
//DEBUG MESSAGE |
|
return result; |
|
|
} |
|
|
bool echoResponse(std::string& result) |
//Echo response |
|
{ |
|
|
LOGD("Enter in " << __func__ << " errorCode =" << errorCode ); |
//DEBUG MESSAGE |
|
result = "Answer from : "; |
//Create answer string |
|
PICMP_ECHO_REPLY pEchoReply; |
//echo-reply struct |
|
struct in_addr ReplyAddr; |
|
|
pEchoReply = (PICMP_ECHO_REPLY)innerBuffer; |
|
|
ReplyAddr.S_un.S_addr = pEchoReply->Address; |
|
|
if (!(errorCode = pEchoReply->Status)) |
//check response status |
|
{ |
|
|
result.append(inet_ntoa(ReplyAddr)); |
//create output message |
result.append(" count of byte = " + std::to_string(pEchoReply->DataSize)); result.append(" response time = " + std::to_string(pEchoReply->RoundTripTime) + "ms"); result.append(" TTL = " + std::to_string(pEchoReply->Options.Ttl));
std::cout << result << std::endl;
}
//DEBUG MESSAGE LOGD("Leave " << __func__ << " errorCode =" << errorCode << " Result =" << (errorCode != 0)); return errorCode!=0;
}
//Program's body
void main(int argv, char* argc[])
{
LOGD("Enter in " << __func__ << " argv =" << argv); |
//DEBUG MESSAGE |
std::string resultMSG; |
//Create string for answer |
resultMSG = ""; |
|
countOfEchoRequest = 2; |
|
pathToLogFile = "C:\\Ping\\Log.txt"; |
|
fErrorCode = errorCode = 0; |
|
innerBuffer = nullptr; |
|
switch (checkParams(argv, argc)) |
|
{ |
|
|
//Correct parameter |
case 0: |
|
switch (checkLog()) |
|
{ |
|
|
//If log file exist |
case 0: |
|
switch (echoRequest(argc[1])) |
|
{ |
|
case 2: |
//end of cycle |
switch (addIntoLogFile(std::to_string(errorCode) + " The request timed out", argc)) |
|
{ |
//Successful add info |
case 0: |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
//Failed to add info |
case 1: |
|
LOGFILE_DIAGNOSTIC_ERROR(); |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
} |
|
case 0: |
//Successful package dispatch |
switch (echoResponse(resultMSG)) |
|
{ |
|
case 0: |
|
switch (addIntoLogFile(resultMSG, argc)) |
|
{ |
//Successful add info |
case 0: |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
//Failed to add info |
case 1: |
|
LOGFILE_DIAGNOSTIC_ERROR(); |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
} |
|
case 1: |
|
switch (addIntoLogFile(echoError(),argc)) |
|
{ |
|
|
//Successful add info |
case 0: |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
|
//Failed to add info |
case 1: |
|
LOGFILE_DIAGNOSTIC_ERROR(); |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
} |
|
} |
|
case 1: |
//Failed package dispatch |
switch (addIntoLogFile(echoError(), argc)) |
|
{ |
|
|
//Successful add info |
case 0: |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
|
//Failed to add info |
case 1: |
|
LOGFILE_DIAGNOSTIC_ERROR(); |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
} |
|
} |
//If log file doesnt exist |
case 1: |
|
switch (logFileCreate()) |
|
{ |
|
case 0: |
|
switch (echoRequest(argc[1])) |
|
{ |
|
case 2: |
//end of cycle |
switch (addIntoLogFile(std::to_string(errorCode) + " The request timed out", argc))
{ |
//Successful add info |
case 0: |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
case 1: |
//Failed to add info |
LOGFILE_DIAGNOSTIC_ERROR(); |
|
LOGD("Leave " << __func__); |
//DEBUG MESSAGE |
delete[] innerBuffer; |
|
return; |
|
} |
|
case 0:
switch (echoResponse(resultMSG))
{
case 0:
switch (addIntoLogFile(resultMSG, argc))
{
case 0:
LOGD("Leave " << __func__); delete[] innerBuffer; return;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
case 1:
switch (addIntoLogFile(echoError(), argc))
{
case 0:
LOGD("Leave " << __func__); delete[] innerBuffer; return;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
}
case 1:
switch (addIntoLogFile(echoError(), argc))
{
case 0:
LOGD("Leave " << __func__); delete[] innerBuffer; return;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
}
break;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
}
case 1:
switch (checkLog())
{
case 0:
switch (addIntoLogFile(paramError(argc)))
{
case 0:
LOGD("Leave " << __func__); delete[] innerBuffer; return;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
case 1:
switch (logFileCreate())
{
case 0:
switch (addIntoLogFile(paramError(argc)))
{
case 0:
LOGD("Leave " << __func__); delete[] innerBuffer; return;
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer; return;
}
case 1:
LOGFILE_DIAGNOSTIC_ERROR(); LOGD("Leave " << __func__); delete[] innerBuffer;
//Successful package dispatch
//Successful add info
//DEBUG MESSAGE
//Failed to add info
//DEBUG MESSAGE
//Successful add info //DEBUG MESSAGE
//Failed to add info
//DEBUG MESSAGE
//Failed package dispatch
//Successful add info //DEBUG MESSAGE
//Failed to add info
//DEBUG MESSAGE
//DEBUG MESSAGE
//Incorrect parameter
//If log file exist
//Successful add info //DEBUG MESSAGE
//Failed to add info
//DEBUG MESSAGE
//If log file doesnt exist
//Successful file creation
//Successful add info //DEBUG MESSAGE
//Failed to add info
//DEBUG MESSAGE
//Failed to create log file
//DEBUG MESSAGE
return;
}
}
}
LOGD("Leave " << __func__); //DEBUG MESSAGE delete[] innerBuffer;
return;
}