feature: multithreading wip

This commit is contained in:
0x35c
2025-05-29 02:16:04 +02:00
parent 6538a085b9
commit 623b3ad0d7
8 changed files with 231 additions and 29 deletions

View File

@ -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;
}