diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..108f82d --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ + +EXENAME := ping.exe +PKGS= +CFLAGS = -g -O0 -Wall $(shell pkg-config --cflags $(PKGS) ) -I. -I./include -std=c99 -D _WIN32_IE=0x0500 -D WINVER=0x0500 +LIBS = -static $(shell pkg-config --libs $(PKGS) ) -lm -lcomctl32 -lws2_32 -lwinmm + +CSRCSCAN := $(wildcard ./*.c) +HSRCSCAN := $(wildcard ./*.h) +CSRCS := $(filter %.c,$(CSRCSCAN)) +objects := $(patsubst %.c,obj/%.o,$(CSRCS)) + +OBJSCAN_PRE1 := $(wildcard ./obj/**/*.o) $(wildcard ./obj/*.o) $(wildcard ./obj/**/**/*.o) +OBJSCAN := $(EXENAME) $(OBJSCAN_PRE1) + +all: $(objects) + $(foreach objFile,$(HSRCSCAN),$(gcc -E $(objFile))) + gcc -o $(EXENAME) $(objects) $(LIBS) + +# Build the resources +# obj/Resource.o: res/Resource.rc res/Application.manifest res/Application.ico include/Resource.h | obj +# windres -I./include -I./res -i "$<" -o "$@" + +$(objects): obj/%.o: %.c + $(shell sh.exe -c "mkdir -p ./$(dir $@) 2> /dev/null") + gcc -g -O0 -Wall $(CFLAGS) -c $< -o $@ + +clean: +#$(shell cmd.exe /c "echo $(CSRCS) > test.txt") +# $(shell cmd.exe /c "echo $(OBJSCAN_PRE1) > test2.txt") +# $(shell cmd.exe /c "echo $(HSRCSCAN) > test3.txt") + $(foreach objFile,$(OBJSCAN),$(shell sh.exe -c "rm $(objFile) 2> /dev/null")) diff --git a/b.bat b/b.bat new file mode 100644 index 0000000..3a68816 --- /dev/null +++ b/b.bat @@ -0,0 +1,5 @@ + +git init +git add *.* +git add Makefile +git commit -am "made changes, %*" diff --git a/dns_call1.h b/dns_call1.h new file mode 100644 index 0000000..0647bf5 --- /dev/null +++ b/dns_call1.h @@ -0,0 +1,72 @@ +/* + * dns_call1.h + * + * Created on: 16 июл. 2023 г. + * Author: User + */ + +#ifndef DNS_CALL1_H_ +#define DNS_CALL1_H_ + +#include +#include +#include + + +static char* dns_call(char* str_webser1) +{ +long ip4_res = 0; +char* alloc_ip4_str=0; + + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + fprintf(stderr, "Failed to initialize Winsock.\n"); + exit(11); + } + + struct addrinfo hints, *results, *result; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; // TCP socket + + int status = getaddrinfo(str_webser1, "80", &hints, &results); + if (status != 0) { + fprintf(stderr, "Failed to resolve hostname: %s\n", gai_strerror(status)); + WSACleanup(); + exit(12); + } + + char ip[INET6_ADDRSTRLEN]; + for (result = results; result != NULL; result = result->ai_next) { + void* addr; + char* ip_version; + + if (result->ai_family == AF_INET) { // IPv4 + struct sockaddr_in* ipv4 = (struct sockaddr_in*)result->ai_addr; + addr = &(ipv4->sin_addr); + ip_version = "IPv4"; + ip4_res = 1; + } else { // IPv6 + struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)result->ai_addr; + addr = &(ipv6->sin6_addr); + ip_version = "IPv6"; + } + + inet_ntop(result->ai_family, addr, ip, sizeof(ip)); + printf("Resolved %s: %s\n", ip_version, ip); + if (ip4_res) + { + alloc_ip4_str = strdup(ip); + } + + } + + freeaddrinfo(results); + WSACleanup(); + + + return alloc_ip4_str; + +} + +#endif /* DNS_CALL1_H_ */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..c991e0b --- /dev/null +++ b/main.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include "timer1.h" +#include "params.h" + +#define MAX_BUFFER_SIZE 1024 + +// ICMP header structure +typedef struct icmp_hdr +{ + unsigned char type; // ICMP message type + unsigned char code; // Type sub-code + unsigned short checksum; // Checksum + unsigned short id; // Identifier + unsigned short seq; // Sequence number +} ICMP_HDR; + +// Calculate the checksum for the ICMP packet +unsigned short +calculateChecksum (unsigned short *buffer, int size) +{ + unsigned long cksum = 0; + + while (size > 1) + { + cksum += *buffer++; + size -= sizeof(unsigned short); + } + + if (size) + { + cksum += *(unsigned char*) buffer; + } + + cksum = (cksum >> 16) + (cksum & 0xffff); + cksum += (cksum >> 16); + + return (unsigned short) (~cksum); +} + +int +main (int argc, char *argv[]) +{ + + parse (argc, argv); // -> str_ip4 ->str_webser + if (str_ip4 == 0) + exit (2); + + WSADATA wsaData; + SOCKET sock; + int bytesReceived; + struct sockaddr_in destAddr; + struct icmp_hdr *icmpHeader; + int packetSize; + const char *destIP = str_ip4; // Destination IP address for ping + + timer1_init (); + + while (1) + { + // Initialize Winsock + if (WSAStartup (MAKEWORD(2, 2), &wsaData) != 0) + { + fprintf (stderr, "Failed to initialize winsock\n"); + return 1; + } + + // Create raw socket for ICMP + sock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sock == INVALID_SOCKET) + { + fprintf (stderr, "Failed to create socket\n"); + return 1; + } + + // Установка максимального времени ожидания ??? + int timeoutMillis = 15000; // 15 секунд + struct timeval timeout; + timeout.tv_sec = timeoutMillis / 1000; + timeout.tv_usec = 0; + //timeout.tv_usec = (timeoutMillis % 1000) * 1000; + + if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, + sizeof(timeout)) == SOCKET_ERROR) + { + fprintf (stderr, "Failed to set recv timeout\n"); + } + + // Set destination address + memset (&destAddr, 0, sizeof(destAddr)); + destAddr.sin_family = AF_INET; + inet_pton (AF_INET, destIP, &(destAddr.sin_addr)); + + char buffer[MAX_BUFFER_SIZE]; + // Prepare the ICMP packet + icmpHeader = (struct icmp_hdr*) buffer; + icmpHeader->type = 8; // ICMP Echo Request type + icmpHeader->code = 0; + icmpHeader->id = htons (GetCurrentProcessId ()); + icmpHeader->seq = htons (1); + icmpHeader->checksum = 0; + icmpHeader->checksum = calculateChecksum ((unsigned short*) icmpHeader, + sizeof(ICMP_HDR)); + + packetSize = sizeof(ICMP_HDR); + + //long restart_recv = 0; + double interv = -1; + //do // цикл для того, чтобы пользователь успел поработать с фаерфолом + { + + interv = -1; + // Send the ICMP packet + timer1_t1 (); + if (sendto (sock, buffer, packetSize, 0, (struct sockaddr*) &destAddr, + sizeof(destAddr)) == SOCKET_ERROR) + { // popup firewall message async + fprintf (stderr, "Failed to send ICMP packet\n"); + closesocket (sock); + WSACleanup (); + return 1; + } + + // Receive the ICMP reply + bytesReceived = recv (sock, buffer, MAX_BUFFER_SIZE, 0); // waiting long + double interv_tmp = timer1_t2_res_us (); + if (bytesReceived == SOCKET_ERROR) + { + } + else if (bytesReceived == 28) // ??? + { + interv = interv_tmp; + //printf("bytesReceived %li packetSize %li \n",bytesReceived , packetSize); + } + } +// while ((restart_recv < 30 // 60 * 2 +// ) && (restart_recv > 0)); + + if ((bytesReceived == SOCKET_ERROR) && (bytesReceived != 28)) + { + fprintf (stderr, "Failed to receive ICMP reply\n"); + closesocket (sock); + WSACleanup (); + + printf ("Ping %s [%s] = timeout \n", str_ip4, str_webser); + } + else + printf ("Ping %s [%s] = %li us\n", str_ip4, str_webser, + (long) (interv + 0.5)); + + // Clean up + closesocket (sock); + WSACleanup (); + + Sleep (1000); + } + + return 0; +} diff --git a/params.h b/params.h new file mode 100644 index 0000000..03a9f22 --- /dev/null +++ b/params.h @@ -0,0 +1,53 @@ +/* + * params.h + * + * Created on: 16 июл. 2023 г. + * Author: User + */ + +#ifndef PARAMS_H_ +#define PARAMS_H_ + +#include "dns_call1.h" + +const char *str_ip4 = 0; +const char *str_webser = 0; + +static void +parse (int argc, char *argv[]) +{ + +// for (int i = 1; i < argc; ++i) { +// argv[i]; +// } + + char *defip = "8.8.8.8"; + + char *par = 0; + if (argc > 1) + if (argv[1] == 0) + argc = 0; + + if (argc > 1) + par = strdup (argv[1]); + else + par = defip; + + if (par[0] == 0) + par = defip; + + char *ip4chars = "0123456789."; + if (strspn (par, ip4chars) == strlen (par)) + { + str_ip4 = par; + str_webser = par; + } + else + { + str_ip4 = dns_call (par); + str_webser = par; + } + +} + +#endif /* PARAMS_H_ */ diff --git a/timer1.h b/timer1.h new file mode 100644 index 0000000..58ddf3e --- /dev/null +++ b/timer1.h @@ -0,0 +1,41 @@ +/* + * timer1.h + * + * Created on: 15 июл. 2023 г. + * Author: User + */ + +#ifndef TIMER1_H_ +#define TIMER1_H_ + +static LARGE_INTEGER frequency; +static LARGE_INTEGER startCount, endCount; +static double elapsedTime; + +void +timer1_init (void) +{ + // Получаем частоту производительного счетчика + QueryPerformanceFrequency (&frequency); +} + +void +timer1_t1 (void) +{ + // Запускаем счетчик времени + QueryPerformanceCounter (&startCount); +} + +double +timer1_t2_res_us (void) +{ + // Останавливаем счетчик времени + QueryPerformanceCounter (&endCount); + // Вычисляем затраченное время в секундах + elapsedTime = (double) (endCount.QuadPart - startCount.QuadPart) + / frequency.QuadPart * 1.0e6; + //printf("Прошло времени: %.6f микросекунд\n", elapsedTime); + return elapsedTime; +} + +#endif /* TIMER1_H_ */