Написал простой сканер портов на асинхронных сокетах. Соединение при сканировании mail.ru и диапазоне [1; 1024] удается установить только на порт 25, на остальные - безуспешно. Кусок
main():
port_range range; //structure for saving range of ports
(std::cin >> range.from >> range.to).get();
con_list cons; //std::vector of structures with sockets
sockaddr_in server_data;
u_long cmd = 1;
fd_set write;
timeval wait_time = { 0, 0 };
USHORT port = range.from;
server_data.sin_family = AF_INET;
tmp.s_addr = *(u_long*)remote_host_info->h_addr;
inet_pton(AF_INET, (PCSTR)inet_ntoa(tmp), &server_data.sin_addr);
while (true)
{
//CONNECTION PHASE
if (port <= range.to)
{
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
server_data.sin_port = htons(port);
if (sock == INVALID_SOCKET)
{
output_error("Couldn't create scan socket");
finalize(); //WSACleanup(), system("pause")
return EXIT_FAILURE;
}
//else
//std::cout << "Created" << std::endl;
if (ioctlsocket(sock, FIONBIO, &cmd) == SOCKET_ERROR)
{
error_to_close_cons("Couldn't put the socket in asynchronous mode", cons); //closes all created sockets, clears con_list container
error_to_close_socket("", sock);
finalize();
return EXIT_FAILURE;
}
//else
//std::cout << "Async" << std::endl;
cons.push_back({ sock, 0, con_mode::write, port, 0, clock() });
if (connect(sock, (SOCKADDR*)&server_data, sizeof(server_data)) == SOCKET_ERROR)
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
error_to_close_cons("Couldn't connect", cons);
error_to_close_socket("", sock);
finalize();
return EXIT_FAILURE;
}
//else
//std::cout << "Connected" << std::endl;
}
port++;
//SCAN PHASE
delete_invalid_cons(cons); //deletes structures with INVALID_SOCKET
FD_ZERO(&write);
if (cons.empty())
break;
for (u_int i = 0; i < cons.size(); i++)
FD_SET(cons[i].sock, &write);
if (select(0, NULL, &write, NULL, &wait_time) == SOCKET_ERROR)
{
error_to_close_cons("Couldn't perform client loop", cons);
finalize();
return EXIT_FAILURE;
}
//else
//std::cout << "Selected" << std::endl;
for (u_int i = 0; i < cons.size(); i++)
if (FD_ISSET(cons[i].sock, &write))
{
std::cout << "Connection established on port " << cons[i].con_port << " in " << (clock() - cons[i].con_time) / CLOCKS_PER_SEC << " seconds" << std::endl;
close_socket(cons[i].sock);
cons[i].sock = INVALID_SOCKET;
}
else
{
std::cout << "Waiting time exceeded" << std::endl;
close_socket(cons[i].sock);
cons[i].sock = INVALID_SOCKET;
}
//else
//std::cout << "Couldn't scan" << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
Кусок заголовочника:
#pragma once
#ifndef WINSOCK_ERROR
#define WINSOCK_ERROR
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <ctime>
#define ECHO_PORT 32768
#define WSA_VERSION 0x0202
#define LOCALHOST "127.0.0.1"
#define BUFF_SIZE 8192
#define BACKLOG 4
#define WAIT_TIME 10
#define INPUT_BUFF 16
namespace con_mode
{
enum mode
{
write,
read,
input //for client
};
}
typedef struct async_connection
{
SOCKET sock;
int buffer_pos; //position in buffer
con_mode::mode c_mode; //defines in which mode (recv/send) a socket works (for single-channel applications)
//char* buffer; //for message from client
USHORT con_port;
int address_num; //address number in HOSTENT struct
clock_t con_time;
} async_connection;
typedef struct port_range
{
USHORT from;
USHORT to;
bool error_flag;
char* error_message;
} port_range;
typedef std::vector<async_connection> con_list;
Другой сканер при тех же условиях устанавливал соединение на большее число портов.