core: use only one struct data instead of thead_data and scan_data
core: do parsing in the main, put all in struct general fix: code support port > 1024
This commit is contained in:
parent
d640c95224
commit
9ae1e29f71
@ -12,7 +12,7 @@ typedef enum {
|
||||
FL_IP,
|
||||
FL_FILE,
|
||||
FL_SPEEDUP,
|
||||
FL_SCAN,
|
||||
FL_TYPE,
|
||||
FL_MAXRETRIES,
|
||||
FL_TTL,
|
||||
// short options
|
||||
@ -26,8 +26,7 @@ struct option_lst {
|
||||
};
|
||||
|
||||
struct option_lst *parse_options(int ac, char *const *av);
|
||||
bool option_isset(const struct option_lst *options, e_flag flag);
|
||||
char *get_option_arg(const struct option_lst *options, e_flag flag);
|
||||
int parse_ports(const char *arg, uint16_t *start, uint16_t *end);
|
||||
e_scantype parse_type(const char *arg);
|
||||
void free_options(struct option_lst *options);
|
||||
int parsing(struct scan *general, const struct option_lst *options);
|
@ -3,6 +3,5 @@
|
||||
#include "parsing.h"
|
||||
#include "response.h"
|
||||
|
||||
void print_host_results(const char *ip_addr, const struct response *responses,
|
||||
const struct option_lst *options, double scan_time);
|
||||
void print_host_results(const struct scan *general, double scan_time);
|
||||
void print_usage(void);
|
||||
|
@ -22,7 +22,6 @@ typedef enum {
|
||||
};
|
||||
|
||||
struct response {
|
||||
uint16_t port;
|
||||
e_state states[SCAN_ALL];
|
||||
char *service;
|
||||
};
|
||||
|
@ -19,14 +19,15 @@ typedef enum {
|
||||
};
|
||||
|
||||
struct scan {
|
||||
const struct host *host;
|
||||
const char *dest_addr;
|
||||
struct host host;
|
||||
char *dest_addr;
|
||||
uint16_t port_start;
|
||||
uint16_t port;
|
||||
uint16_t port_end;
|
||||
e_scantype type;
|
||||
uint8_t ttl;
|
||||
uint8_t max_retries;
|
||||
struct response *response;
|
||||
struct response *responses;
|
||||
uint8_t nb_threads;
|
||||
};
|
||||
|
||||
int scan(struct scan *data);
|
||||
|
@ -7,17 +7,4 @@
|
||||
#include "response.h"
|
||||
#include "scan.h"
|
||||
|
||||
struct thread {
|
||||
uint16_t port_start;
|
||||
uint16_t port_end;
|
||||
char *dest_addr;
|
||||
e_scantype type;
|
||||
uint8_t max_retries;
|
||||
uint8_t ttl;
|
||||
struct host host;
|
||||
struct response *responses;
|
||||
};
|
||||
|
||||
void *routine(void *p_data);
|
||||
int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
struct response *responses);
|
||||
int create_threads(struct scan *general);
|
||||
|
41
src/main.c
41
src/main.c
@ -11,23 +11,19 @@
|
||||
#include "print.h"
|
||||
#include "scan.h"
|
||||
#include "thread.h"
|
||||
#include "interface.h"
|
||||
|
||||
static int scan_host(char *host, const struct option_lst *options)
|
||||
static int scan_host(struct scan *general)
|
||||
{
|
||||
char ip_addr[INET_ADDRSTRLEN];
|
||||
struct sockaddr_in addr_con;
|
||||
host[strcspn(host, "\n")] = '\0';
|
||||
if (dns_lookup(ip_addr, host, &addr_con)) {
|
||||
dprintf(2,
|
||||
"ft_nmap: failed to retrieve ip address from "
|
||||
"'%s'\n",
|
||||
host);
|
||||
return 1;
|
||||
if (dns_lookup(general->dest_addr, general->dest_addr, &addr_con)) {
|
||||
return -1;
|
||||
}
|
||||
struct response responses[1024] = {0};
|
||||
if (create_threads(options, ip_addr, responses) < 0)
|
||||
return 1;
|
||||
print_host_results(ip_addr, responses, options, 10);
|
||||
general->responses = responses;
|
||||
if (create_threads(general) < 0)
|
||||
return -1;
|
||||
print_host_results(general, 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -44,9 +40,20 @@ int main(int ac, char **av)
|
||||
if (options == NULL)
|
||||
return 1;
|
||||
|
||||
char *host = get_option_arg(options, FL_IP);
|
||||
if (host) {
|
||||
int rv = scan_host(host, options);
|
||||
struct scan general;
|
||||
if (parsing(&general, options))
|
||||
{
|
||||
free_options(options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (get_interface_name(&general.host) < 0)
|
||||
return -1;
|
||||
|
||||
char *dest_addr = get_option_arg(options, FL_IP);
|
||||
if (dest_addr) {
|
||||
general.dest_addr = dest_addr;
|
||||
int rv = scan_host(&general);
|
||||
free_options(options);
|
||||
return rv;
|
||||
}
|
||||
@ -64,7 +71,9 @@ int main(int ac, char **av)
|
||||
}
|
||||
char line[256];
|
||||
while (fgets(line, sizeof(line), hosts_file)) {
|
||||
if (scan_host(line, options) < 0) {
|
||||
line[strcspn(line, "\n")] = '\0';
|
||||
general.dest_addr = line;
|
||||
if (scan_host(&general) < 0) {
|
||||
fclose(hosts_file);
|
||||
goto error;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
void create_udp_packet(struct udphdr *udphdr, const struct scan *data)
|
||||
{
|
||||
udphdr->source = htons(1234);
|
||||
udphdr->dest = htons(data->port);
|
||||
udphdr->dest = htons(data->port_start);
|
||||
udphdr->len = sizeof(struct udphdr);
|
||||
udphdr->check = checksum(udphdr, sizeof(struct udphdr));
|
||||
}
|
||||
@ -21,7 +21,7 @@ void create_udp_packet(struct udphdr *udphdr, const struct scan *data)
|
||||
int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
|
||||
{
|
||||
tcphdr->source = htons(1234);
|
||||
tcphdr->dest = htons(data->port);
|
||||
tcphdr->dest = htons(data->port_start);
|
||||
tcphdr->doff = sizeof(struct tcphdr) / sizeof(int);
|
||||
tcphdr->fin = data->type == SCAN_XMAS || data->type == SCAN_FIN;
|
||||
tcphdr->syn = data->type == SCAN_SYN;
|
||||
@ -32,7 +32,7 @@ int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
|
||||
tcphdr->urg_ptr = 0;
|
||||
|
||||
struct pshdr pshdr;
|
||||
pshdr.src_addr = inet_addr(data->host->ip);
|
||||
pshdr.src_addr = inet_addr(data->host.ip);
|
||||
pshdr.dst_addr = inet_addr(data->dest_addr);
|
||||
pshdr.placeholder = 0;
|
||||
pshdr.protocol = IPPROTO_TCP;
|
||||
@ -69,7 +69,7 @@ static void *create_packet(const struct scan *data, size_t packet_size)
|
||||
iphdr->frag_off = 0;
|
||||
iphdr->ttl = data->ttl;
|
||||
iphdr->protocol = isudp ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
iphdr->saddr = inet_addr(data->host->ip);
|
||||
iphdr->saddr = inet_addr(data->host.ip);
|
||||
iphdr->daddr = inet_addr(data->dest_addr);
|
||||
|
||||
iphdr->check = checksum(packet, packet_size);
|
||||
|
@ -47,6 +47,7 @@ e_scantype parse_type(const char *arg)
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
if (!strcmp(arg, types_str[i]))
|
||||
return i;
|
||||
dprintf(2, "ft_nmap: type: invalid argument: '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
|
||||
*p_end = end;
|
||||
return 0;
|
||||
error:
|
||||
dprintf(2, "ft_nmap: invalid argument: '%s'\n", arg);
|
||||
dprintf(2, "ft_nmap: port: invalid argument: '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -105,7 +106,7 @@ static int check_arg(e_flag flag, const char *arg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FL_SCAN:
|
||||
case FL_TYPE:
|
||||
if (!strcmp(arg, "SYN"))
|
||||
break;
|
||||
if (!strcmp(arg, "NULL"))
|
||||
@ -223,3 +224,28 @@ struct option_lst *parse_options(int ac, char *const *av)
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
int parsing(struct scan *general, const struct option_lst *options)
|
||||
{
|
||||
general->port_start = 1;
|
||||
general->port_end = 1024;
|
||||
if (option_isset(options, FL_FAST))
|
||||
general->port_end = 128;
|
||||
if (parse_ports(get_option_arg(options, FL_PORTS), &general->port_start, &general->port_end))
|
||||
return -1;
|
||||
general->type = parse_type(get_option_arg(options, FL_TYPE));
|
||||
if ((int)general->type == -1)
|
||||
return -1;
|
||||
const char *max_retries = get_option_arg(options, FL_MAXRETRIES);
|
||||
general->max_retries = max_retries ? atoi(max_retries) : 1;
|
||||
const char *ttl = get_option_arg(options, FL_TTL);
|
||||
general->ttl = ttl ? atoi(ttl) : 48;
|
||||
const char *nb_threads_str = get_option_arg(options, FL_SPEEDUP);
|
||||
general->nb_threads = nb_threads_str ? atoi(nb_threads_str) : 1;
|
||||
if (general->port_end - general->port_start + 1 < general->nb_threads) {
|
||||
dprintf(2, "ft_nmap: number of threads to use must be superior "
|
||||
"or equals to the ports range\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
17
src/print.c
17
src/print.c
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "parsing.h"
|
||||
@ -9,11 +10,11 @@ void print_usage(void)
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void print_port_state(const struct response *response, e_scantype type)
|
||||
static void print_port_state(uint16_t port, e_scantype type, const struct response * response)
|
||||
{
|
||||
if (type != SCAN_ALL && response->states[type] == CLOSED)
|
||||
return;
|
||||
printf("%-5d %-12s ", response->port,
|
||||
printf("%-5d %-12s ", port,
|
||||
response->service ? response->service : "Unassigned");
|
||||
if (type == SCAN_ALL)
|
||||
for (e_scantype i = SCAN_NULL; i < SCAN_ALL; i++)
|
||||
@ -25,16 +26,12 @@ static void print_port_state(const struct response *response, e_scantype type)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_host_results(const char *ip_addr, const struct response *responses,
|
||||
const struct option_lst *options, double scan_time)
|
||||
void print_host_results(const struct scan *general, double scan_time)
|
||||
{
|
||||
printf("Scan took %lf secs\n", scan_time);
|
||||
printf("IP address: %s\n", ip_addr);
|
||||
printf("IP address: %s\n", general->dest_addr);
|
||||
printf("Open ports:\n");
|
||||
uint16_t port_start = 1, port_end = 1024;
|
||||
parse_ports(get_option_arg(options, FL_PORTS), &port_start, &port_end);
|
||||
e_scantype type = parse_type(get_option_arg(options, FL_SCAN));
|
||||
for (uint16_t i = port_start; i < port_end - port_start; i++) {
|
||||
print_port_state(&responses[i], type);
|
||||
for (uint16_t port = general->port_start; port < general->port_end; port++) {
|
||||
print_port_state(port, general->type, &general->responses[port - general->port_start]);
|
||||
}
|
||||
}
|
||||
|
@ -24,80 +24,80 @@ void tcp_response(const struct tcphdr *tcphdr, const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
if (type == SCAN_UDP) {
|
||||
dprintf(2, "ft_nmap: error: received a TCP response for an UDP "
|
||||
dprintf(2, "ft_nmap: error: received a TCP responses for an UDP "
|
||||
"scan\n");
|
||||
return;
|
||||
}
|
||||
if (data->response->service == NULL)
|
||||
data->response->service = get_service_name(data->port, "tcp");
|
||||
if (data->responses->service == NULL)
|
||||
data->responses->service = get_service_name(data->port_start, "tcp");
|
||||
if (type == SCAN_SYN) {
|
||||
if (tcphdr->ack == 1 && tcphdr->syn == 1)
|
||||
data->response->states[type] = OPENED;
|
||||
data->responses->states[type] = OPENED;
|
||||
else if (tcphdr->ack == 1 && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSED;
|
||||
data->responses->states[type] = CLOSED;
|
||||
} else if (type == SCAN_ACK && tcphdr->rst == 1)
|
||||
data->response->states[type] = UNFILTERED;
|
||||
data->responses->states[type] = UNFILTERED;
|
||||
else if (type == SCAN_NULL && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSED;
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_FIN && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSED;
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_XMAS && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSED;
|
||||
data->responses->states[type] = CLOSED;
|
||||
}
|
||||
|
||||
void udp_response(const struct udphdr *udphdr, const struct scan *data)
|
||||
{
|
||||
(void)udphdr;
|
||||
if (data->type != SCAN_UDP) {
|
||||
dprintf(2, "ft_nmap: error: received an UDP response for a TCP "
|
||||
dprintf(2, "ft_nmap: error: received an UDP responses for a TCP "
|
||||
"scan\n");
|
||||
return;
|
||||
}
|
||||
if (data->response->service == NULL)
|
||||
data->response->service = get_service_name(data->port, "udp");
|
||||
data->response->states[SCAN_UDP] = OPENED;
|
||||
if (data->responses->service == NULL)
|
||||
data->responses->service = get_service_name(data->port_start, "udp");
|
||||
data->responses->states[SCAN_UDP] = OPENED;
|
||||
}
|
||||
|
||||
void icmp_response(const struct icmphdr *icmphdr, const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
|
||||
data->response->service = get_service_name(data->port, "udp");
|
||||
if (data->response->service == NULL)
|
||||
data->response->service = get_service_name(data->port, "tcp");
|
||||
data->responses->service = get_service_name(data->port_start, "udp");
|
||||
if (data->responses->service == NULL)
|
||||
data->responses->service = get_service_name(data->port_start, "tcp");
|
||||
if (type == SCAN_SYN && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_ACK && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_NULL && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_FIN && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_XMAS && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
||||
data->response->states[type] = CLOSED;
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
}
|
||||
|
||||
void no_response(const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
|
||||
data->response->service = get_service_name(data->port, "udp");
|
||||
if (data->response->service == NULL)
|
||||
data->response->service = get_service_name(data->port, "tcp");
|
||||
data->responses->service = get_service_name(data->port_start, "udp");
|
||||
if (data->responses->service == NULL)
|
||||
data->responses->service = get_service_name(data->port_start, "tcp");
|
||||
if (type == SCAN_SYN)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_ACK)
|
||||
data->response->states[type] = FILTERED;
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_NULL)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_FIN)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_XMAS)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_UDP)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ int scan(struct scan *data)
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
bpf_u_int32 net, mask;
|
||||
|
||||
if (pcap_lookupnet(data->host->interface, &net, &mask, errbuf) < 0) {
|
||||
if (pcap_lookupnet(data->host.interface, &net, &mask, errbuf) < 0) {
|
||||
dprintf(2, "ft_nmap: failed to lookup net/mask\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcap_t *handle =
|
||||
pcap_open_live(data->host->interface, BUFSIZ, 0, 1000, errbuf);
|
||||
pcap_open_live(data->host.interface, BUFSIZ, 0, 1000, errbuf);
|
||||
if (handle == NULL) {
|
||||
dprintf(2, "ft_nmap: failed to open device capture\n");
|
||||
return -1;
|
||||
@ -83,7 +83,7 @@ int scan(struct scan *data)
|
||||
struct bpf_program fp;
|
||||
char pcap_expr[BUFSIZ];
|
||||
sprintf(pcap_expr, "src host %s and src port %d and dst host %s",
|
||||
data->dest_addr, data->port, data->host->ip);
|
||||
data->dest_addr, data->port_start, data->host.ip);
|
||||
|
||||
if (pcap_compile(handle, &fp, pcap_expr, 0, mask) < 0) {
|
||||
dprintf(2, "ft_nmap: failed to compile pcap expression\n");
|
||||
|
112
src/thread.c
112
src/thread.c
@ -27,21 +27,15 @@ void *routine(void *p_data)
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
struct thread *thread_data = (struct thread *)p_data;
|
||||
struct scan scan_data = {
|
||||
.dest_addr = thread_data->dest_addr,
|
||||
.host = &thread_data->host,
|
||||
.port_start = thread_data->port_start,
|
||||
.type = thread_data->type,
|
||||
.max_retries = thread_data->max_retries,
|
||||
.ttl = thread_data->ttl,
|
||||
};
|
||||
struct scan *thread_data = p_data;
|
||||
struct scan scan_data;
|
||||
memcpy(&scan_data, thread_data, sizeof(struct scan));
|
||||
|
||||
for (uint16_t port = thread_data->port_start;
|
||||
port <= thread_data->port_end; port++) {
|
||||
scan_data.port = port;
|
||||
scan_data.response = &thread_data->responses[port - 1];
|
||||
scan_data.response->port = port;
|
||||
scan_data.port_start = port;
|
||||
scan_data.port_end = port;
|
||||
scan_data.responses = &thread_data->responses[port - thread_data->port_start];
|
||||
if (scan(&scan_data)) {
|
||||
free(p_data);
|
||||
return NULL;
|
||||
@ -51,72 +45,47 @@ void *routine(void *p_data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct thread *init_threads_data(const struct option_lst *options,
|
||||
char *ip_addr, const struct host *host,
|
||||
struct response *responses,
|
||||
uint8_t nb_threads)
|
||||
static struct scan *init_threads_data(const struct scan *general)
|
||||
{
|
||||
struct thread *threads = malloc(sizeof(struct thread) * nb_threads);
|
||||
if (!threads) {
|
||||
struct scan *threads_data = malloc(sizeof(struct scan) * general->nb_threads);
|
||||
if (!threads_data) {
|
||||
dprintf(2, "ft_nmap: allocation of threads failed\n");
|
||||
return NULL;
|
||||
}
|
||||
for (uint8_t i = 0; i < nb_threads; i++) {
|
||||
memcpy(&threads[i].host, host, sizeof(struct host));
|
||||
threads[i].type = parse_type(get_option_arg(options, FL_SCAN));
|
||||
if (threads[i].type < 0)
|
||||
goto error;
|
||||
threads[i].dest_addr = ip_addr;
|
||||
threads[i].responses = responses;
|
||||
char *max_retries = get_option_arg(options, FL_MAXRETRIES);
|
||||
threads[i].max_retries = max_retries ? atoi(max_retries) : 1;
|
||||
char *ttl = get_option_arg(options, FL_TTL);
|
||||
threads[i].ttl = ttl ? atoi(ttl) : 48;
|
||||
|
||||
const uint16_t port_range = general->port_end - general->port_start + 1;
|
||||
const uint16_t ports_per_thread = port_range / general->nb_threads;
|
||||
uint16_t remaining_ports = port_range % general->nb_threads;
|
||||
uint16_t port_start = general->port_start;
|
||||
for (uint8_t i = 0; i < general->nb_threads; i++) {
|
||||
memcpy(&threads_data[i], general, sizeof(struct scan));
|
||||
threads_data[i].port_start = port_start + i * ports_per_thread;
|
||||
threads_data[i].port_end = (port_start - 1) +
|
||||
(i + 1) * ports_per_thread +
|
||||
(remaining_ports ? 1 : 0);
|
||||
threads_data[i].responses = general->responses + (threads_data[i].port_start - general->port_start);
|
||||
if (remaining_ports) {
|
||||
remaining_ports--;
|
||||
port_start++;
|
||||
}
|
||||
}
|
||||
|
||||
return threads;
|
||||
error:
|
||||
free(threads);
|
||||
return NULL;
|
||||
return threads_data;
|
||||
}
|
||||
|
||||
int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
struct response *responses)
|
||||
int create_threads(struct scan *general)
|
||||
{
|
||||
struct host host;
|
||||
if (get_interface_name(&host) < 0)
|
||||
return -1;
|
||||
|
||||
uint16_t port_start = 1;
|
||||
uint16_t port_end = 1024;
|
||||
if (option_isset(options, FL_FAST))
|
||||
port_end = 128;
|
||||
const char *ports = get_option_arg(options, FL_PORTS);
|
||||
if (parse_ports(ports, &port_start, &port_end) < 0)
|
||||
return -1;
|
||||
|
||||
const char *nb_threads_str = get_option_arg(options, FL_SPEEDUP);
|
||||
if (!nb_threads_str) {
|
||||
struct thread *thread_data =
|
||||
init_threads_data(options, ip_addr, &host, responses, 1);
|
||||
if (general->nb_threads == 1) {
|
||||
g_start = true;
|
||||
routine(thread_data);
|
||||
free(thread_data);
|
||||
routine(general);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t nb_threads = atoi(nb_threads_str);
|
||||
if (port_end - port_start + 1 < nb_threads) {
|
||||
dprintf(2, "ft_nmap: number of threads to use must be superior "
|
||||
"or equals to the ports range\n");
|
||||
struct scan *threads_data =
|
||||
init_threads_data(general);
|
||||
if (threads_data == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct thread *threads_data =
|
||||
init_threads_data(options, ip_addr, &host, responses, nb_threads);
|
||||
if (!threads_data)
|
||||
return -1;
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * nb_threads);
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * threads_data->nb_threads);
|
||||
if (!threads) {
|
||||
free(threads_data);
|
||||
return -1;
|
||||
@ -125,18 +94,7 @@ int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
pthread_mutex_init(&g_start_mtx, NULL);
|
||||
pthread_mutex_init(&g_getservent, NULL);
|
||||
|
||||
const uint16_t ports_per_thread =
|
||||
(port_end - port_start + 1) / nb_threads;
|
||||
uint16_t remaining_ports = (port_end - port_start + 1) % nb_threads;
|
||||
for (uint8_t i = 0; i < nb_threads; i++) {
|
||||
threads_data[i].port_start = port_start + i * ports_per_thread;
|
||||
threads_data[i].port_end = (port_start - 1) +
|
||||
(i + 1) * ports_per_thread +
|
||||
(remaining_ports ? 1 : 0);
|
||||
if (remaining_ports) {
|
||||
remaining_ports--;
|
||||
port_start++;
|
||||
}
|
||||
for (uint8_t i = 0; i < general->nb_threads; i++) {
|
||||
if (pthread_create(&threads[i], NULL, routine,
|
||||
&threads_data[i])) {
|
||||
dprintf(2, "ft_nmap: error during pthread_create()\n");
|
||||
@ -147,7 +105,7 @@ int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
g_start = true;
|
||||
pthread_mutex_unlock(&g_start_mtx);
|
||||
|
||||
for (uint8_t i = 0; i < nb_threads; i++) {
|
||||
for (uint8_t i = 0; i < general->nb_threads; i++) {
|
||||
if (pthread_join(threads[i], NULL)) {
|
||||
dprintf(2, "ft_nmap: error during pthread_join()\n");
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user