#include "winsock_error.h"
#include "io_ext.h"
#include <cstdio>
#define SOCK_NUM 3
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable : 4996)
int main()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
WSADATA filler;
if (WSAStartup(WSA_VERSION, &filler))
{
output_error("Couldn't initialize WSA");
return EXIT_FAILURE;
}
char host_name[MAXGETHOSTSTRUCT];
enter_message("Please enter a host name: ", host_name);
std::cout << std::endl;
LPHOSTENT remote_host_info = gethostbyname(host_name);
if (remote_host_info == NULL)
{
output_error("Couldn't get a host info");
finalize();
return EXIT_FAILURE;
}
if (remote_host_info->h_addrtype == AF_INET6)
{
output_error("Sorry, but R-Scan can't perform scanning of ipv6-hosts");
finalize();
return EXIT_SUCCESS;
}
//ALIASES SHOWING
if (remote_host_info->h_aliases[0])
{
std::cout << "Server name aliases: " << std::endl;
for (int i = 0; remote_host_info->h_aliases[i]; i++)
std::cout << remote_host_info->h_aliases[i] << std::endl;
std::cout << std::endl;
}
else
std::cout << "Host has no aliases" << std::endl << std::endl;
in_addr tmp;
//ADDRESSES SHOWING
if (remote_host_info->h_addr_list[1])
{
std::cout << "Server addresses: " << std::endl;
for (int i = 0; remote_host_info->h_addr_list[i]; i++)
{
tmp.s_addr = *(LPWORD)remote_host_info->h_addr_list[i];
std::cout << inet_ntoa(tmp) << std::endl;
}
std::cout << std::endl;
}
else
{
std::cout << "Server address: ";
tmp.s_addr = *(u_long*)remote_host_info->h_addr;
std::cout << inet_ntoa(tmp) << std::endl << std::endl;
}
WORD temp;
BYTE max_hops_num;
//MAX HOPS NUM INPUT
while (true)
{
std::cout << "Please enter max number of hops: ";
(std::cin >> temp).get();
if (!std::cin || temp > TTL_MAX_VAL || temp == 0)
{
clear_istream(std::cin);
std::cerr << "You entered wrong value; try again" << std::endl << std::endl;
}
else
break;
}
__asm //firstly value is assigned to 16 bit temporary variable, then left octet of temporary variable is assigned to max_hops_num variable
{
mov ax, temp
mov max_hops_num, al
}
fd_set read;
SOCKET sock = ICMP_SOCKET;
sockaddr_in server_data;
ECHO_REQUEST echo_req;
ECHO_REPLY echo_rep;
timeval wait_time = { 2, 0 };
//CONNECTION DATA FILLING
server_data.sin_family = AF_INET;
server_data.sin_port = 0;
tmp.s_addr = *(LPWORD)&remote_host_info->h_addr;
inet_pton(AF_INET, (PCSTR)inet_ntoa(tmp), &server_data.sin_addr);
//ICMP HDR AND ECHO_REQUEST STRUCT FILLING
echo_req.icmp_hdr.type = ICMP_ECHO_REQ;
echo_req.icmp_hdr.code = 0;
echo_req.icmp_hdr.id = 1;
echo_req.icmp_hdr.seq = 0;
echo_req.icmp_hdr.checksum = 0;
echo_req.dw_time = GetTickCount();
memset(echo_req.data, ECHO_FILLER, PACK_FRAME_SIZE);
echo_req.icmp_hdr.checksum = checksum((LPWORD)&echo_req, sizeof(echo_req));
//TRACERT LOOP
for (BYTE TTL = 1; TTL <= max_hops_num; TTL++)
{
tmp.s_addr = 0;
printf("%3d\t", TTL);
//set TTL
if (setsockopt(sock, IPPROTO_IP, IP_TTL, (PCSTR)&TTL, sizeof(TTL)) == SOCKET_ERROR)
{
error_to_close_socket("Couldn't set IP header TTL", sock);
finalize();
return EXIT_FAILURE;
}
//send 3 ICMP echo requests
RANGE(0, SOCK_NUM)
{
echo_req.dw_time = GetTickCount();
echo_req.icmp_hdr.checksum = checksum((LPWORD)&echo_req, sizeof(echo_req));
if (sendto(sock, (LPSTR)&echo_req, sizeof(echo_req), 0, (LPSOCKADDR)&server_data, sizeof(server_data)) == SOCKET_ERROR)
{
error_to_close_socket("Couldn't perform a ping", sock);
finalize();
return EXIT_FAILURE;
}
FD_ZERO(&read);
FD_SET(sock, &read);
int ret = select(0, &read, NULL, NULL, &wait_time);
if (ret == SOCKET_ERROR)
{
error_to_close_socket("Couldn't perform data awaiting", sock);
finalize();
return EXIT_FAILURE;
}
else if (ret == 0)
{
std::cout << " * \t";
}
else
{
if (recvfrom(sock, (LPSTR)&echo_rep, sizeof(ECHO_REPLY), 0, NULL, NULL) == SOCKET_ERROR)
{
error_to_close_socket("Couldn't receive ICMP", sock);
finalize();
return EXIT_FAILURE;
}
printf("%4d ms\t", GetTickCount() - echo_rep.echo_request.dw_time);
tmp = echo_rep.ip_hdr.src_addr;
}
}
if (tmp.s_addr == 0)
{
std::cout << "Waiting time exceeded" << std::endl;
continue;
}
remote_host_info = gethostbyaddr((PCSTR)&echo_rep.ip_hdr.src_addr, AF_INET_ADDR_LEN, AF_INET);
if (remote_host_info == NULL)
std::cout << inet_ntoa(echo_rep.ip_hdr.src_addr) << std::endl;
else
printf("%s [%s]", remote_host_info->h_name, inet_ntoa(echo_rep.ip_hdr.src_addr));
if (echo_rep.echo_request.icmp_hdr.type == 0 && echo_rep.echo_request.icmp_hdr.code == 0)
break;
}
}