feature: multithreading wip
This commit is contained in:
131
src/thread.c
131
src/thread.c
@ -1,12 +1,33 @@
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "interface.h"
|
||||
#include "parsing.h"
|
||||
#include "scan.h"
|
||||
#include "thread.h"
|
||||
|
||||
uint8_t g_nb_threads;
|
||||
bool g_start = false;
|
||||
pthread_mutex_t g_nb_threads_mtx;
|
||||
pthread_mutex_t g_start_mtx;
|
||||
|
||||
void *routine(void *p_data)
|
||||
{
|
||||
while (1) {
|
||||
pthread_mutex_lock(&g_start_mtx);
|
||||
bool start = g_start;
|
||||
pthread_mutex_unlock(&g_start_mtx);
|
||||
if (start)
|
||||
break;
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
struct thread *thread_data = (struct thread *)p_data;
|
||||
struct scan scan_data = {
|
||||
.dest_addr = thread_data->dest_addr,
|
||||
@ -20,11 +41,113 @@ void *routine(void *p_data)
|
||||
scan_data.port = port;
|
||||
scan_data.response =
|
||||
&thread_data->responses[port - thread_data->port_start];
|
||||
if (scan(&scan_data))
|
||||
printf("uwu on port %d\n", port);
|
||||
if (scan(&scan_data)) {
|
||||
free(p_data);
|
||||
return NULL;
|
||||
printf("%d: %s\n", port,
|
||||
scan_data.response->state == 1 ? "OPEN" : "CLOSED");
|
||||
}
|
||||
printf("%d has state: %d\n", port, scan_data.response->state);
|
||||
}
|
||||
|
||||
return p_data;
|
||||
pthread_mutex_lock(&g_nb_threads_mtx);
|
||||
g_nb_threads--;
|
||||
pthread_mutex_unlock(&g_nb_threads_mtx);
|
||||
free(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 g_nb_threads)
|
||||
{
|
||||
struct thread *threads = malloc(sizeof(struct thread) * g_nb_threads);
|
||||
if (!threads) {
|
||||
dprintf(2, "ft_nmap: allocation of threads failed\n");
|
||||
return NULL;
|
||||
}
|
||||
for (uint8_t i = 0; i < g_nb_threads; i++) {
|
||||
memcpy(&threads[i].host, host, sizeof(struct host));
|
||||
const char *ports = get_option_arg(options, FL_PORTS);
|
||||
if (parse_ports(ports, &threads[i].port_start,
|
||||
&threads[i].port_end) < 0)
|
||||
goto error;
|
||||
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;
|
||||
}
|
||||
|
||||
return threads;
|
||||
error:
|
||||
free(threads);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
struct response *responses)
|
||||
{
|
||||
uint16_t port_start, port_end;
|
||||
const char *ports = get_option_arg(options, FL_PORTS);
|
||||
if (parse_ports(ports, &port_start, &port_end) < 0)
|
||||
return -1;
|
||||
struct host host;
|
||||
if (get_interface_name(&host) < 0)
|
||||
return -1;
|
||||
|
||||
const char *arg = get_option_arg(options, FL_SPEEDUP);
|
||||
if (!arg) {
|
||||
struct thread *thread_data =
|
||||
init_threads_data(options, ip_addr, &host, responses, 1);
|
||||
thread_data->port_start = port_start;
|
||||
thread_data->port_end = port_end;
|
||||
routine(thread_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_nb_threads = atoi(arg);
|
||||
struct thread *threads_data =
|
||||
init_threads_data(options, ip_addr, &host, responses, g_nb_threads);
|
||||
if (!threads_data)
|
||||
return -1;
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * g_nb_threads);
|
||||
if (!threads) {
|
||||
free(threads_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&g_nb_threads_mtx, NULL);
|
||||
pthread_mutex_init(&g_start_mtx, NULL);
|
||||
|
||||
const uint16_t ports_per_thread =
|
||||
(port_end - port_start) / g_nb_threads;
|
||||
uint16_t remaining_ports = (port_end - port_start) % g_nb_threads;
|
||||
for (uint8_t i = 0; i < g_nb_threads; i++) {
|
||||
threads_data[i].port_start = port_start + i * ports_per_thread;
|
||||
threads_data[i].port_end =
|
||||
port_start + (i + 1) * ports_per_thread;
|
||||
// TODO implement remaining_ports
|
||||
(void)remaining_ports;
|
||||
if (pthread_create(&threads[i], NULL, routine,
|
||||
&threads_data[i])) {
|
||||
dprintf(2, "ft_nmap: error during pthread_create()\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
pthread_mutex_lock(&g_start_mtx);
|
||||
g_start = true;
|
||||
pthread_mutex_unlock(&g_start_mtx);
|
||||
|
||||
while (1) {
|
||||
pthread_mutex_lock(&g_nb_threads_mtx);
|
||||
bool nb_threads = g_nb_threads;
|
||||
pthread_mutex_unlock(&g_nb_threads_mtx);
|
||||
if (nb_threads == 0)
|
||||
break;
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user