add: multi scan
This commit is contained in:
@ -28,6 +28,6 @@ struct option_lst {
|
||||
struct option_lst *parse_options(int ac, char *const *av);
|
||||
char *get_option_arg(const struct option_lst *options, e_flag flag);
|
||||
bool option_isset(const struct option_lst *options, e_flag flag);
|
||||
e_scantype parse_type(const char *arg);
|
||||
uint8_t parse_type(char *arg);
|
||||
void free_options(struct option_lst *options);
|
||||
int parsing(struct scan *general, const struct option_lst *options);
|
||||
|
@ -22,7 +22,7 @@ typedef enum {
|
||||
};
|
||||
|
||||
struct response {
|
||||
e_state states[SCAN_ALL];
|
||||
e_state states[NB_SCAN];
|
||||
char *service;
|
||||
};
|
||||
|
||||
|
@ -4,26 +4,26 @@
|
||||
|
||||
#include "host.h"
|
||||
|
||||
typedef enum {
|
||||
SCAN_NULL,
|
||||
SCAN_SYN,
|
||||
SCAN_ACK,
|
||||
SCAN_FIN,
|
||||
SCAN_XMAS,
|
||||
SCAN_UDP,
|
||||
SCAN_ALL,
|
||||
} e_scantype;
|
||||
#define SCAN_NULL (1 << 0)
|
||||
#define SCAN_SYN (1 << 1)
|
||||
#define SCAN_ACK (1 << 2)
|
||||
#define SCAN_FIN (1 << 3)
|
||||
#define SCAN_XMAS (1 << 4)
|
||||
#define SCAN_UDP (1 << 5)
|
||||
#define SCAN_ALL (SCAN_NULL | SCAN_SYN | SCAN_ACK | SCAN_FIN | SCAN_XMAS | SCAN_UDP)
|
||||
|
||||
[[__maybe_unused__]] static const char *types_str[] = {
|
||||
"NULL", "SYN", "ACK", "FIN", "XMAS", "UDP",
|
||||
};
|
||||
|
||||
#define NB_SCAN (sizeof(types_str) / sizeof(*types_str))
|
||||
|
||||
struct scan {
|
||||
struct host host;
|
||||
char *dest_addr;
|
||||
uint16_t port_start;
|
||||
uint16_t port_end;
|
||||
e_scantype type;
|
||||
uint8_t type;
|
||||
uint8_t ttl;
|
||||
uint8_t max_retries;
|
||||
struct response *responses;
|
||||
|
14
src/packet.c
14
src/packet.c
@ -23,11 +23,11 @@ int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
|
||||
tcphdr->source = htons(1234);
|
||||
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;
|
||||
tcphdr->psh = data->type == SCAN_XMAS;
|
||||
tcphdr->ack = data->type == SCAN_ACK;
|
||||
tcphdr->urg = data->type == SCAN_XMAS;
|
||||
tcphdr->fin = ((data->type & SCAN_XMAS) != 0) || ((data->type & SCAN_FIN) != 0);
|
||||
tcphdr->syn = ((data->type & SCAN_SYN) != 0);
|
||||
tcphdr->psh = ((data->type & SCAN_XMAS) != 0);
|
||||
tcphdr->ack = ((data->type & SCAN_ACK) != 0);
|
||||
tcphdr->urg = ((data->type & SCAN_XMAS) != 0);
|
||||
tcphdr->window = htons(5840);
|
||||
tcphdr->urg_ptr = 0;
|
||||
|
||||
@ -52,7 +52,7 @@ int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
|
||||
|
||||
static void *create_packet(const struct scan *data, size_t packet_size)
|
||||
{
|
||||
const bool isudp = data->type == SCAN_UDP;
|
||||
const bool isudp = ((data->type & SCAN_UDP) != 0);
|
||||
void *packet = calloc(packet_size, 1);
|
||||
if (!packet) {
|
||||
dprintf(2,
|
||||
@ -90,7 +90,7 @@ int send_packet(const struct scan *data, int sockfd)
|
||||
conn_addr.sin_addr.s_addr = inet_addr(data->dest_addr);
|
||||
|
||||
size_t packet_size = sizeof(struct iphdr) +
|
||||
(data->type == SCAN_UDP ? sizeof(struct udphdr)
|
||||
(((data->type & SCAN_UDP) != 0) ? sizeof(struct udphdr)
|
||||
: sizeof(struct tcphdr));
|
||||
void *packet = create_packet(data, packet_size);
|
||||
|
||||
|
@ -40,15 +40,36 @@ char *get_option_arg(const struct option_lst *options, e_flag flag)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e_scantype parse_type(const char *arg)
|
||||
uint8_t parse_type(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return SCAN_ALL;
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
if (!strcmp(arg, types_str[i]))
|
||||
return i;
|
||||
uint8_t type = 0;
|
||||
char *current_arg = arg;
|
||||
while (current_arg[0] != '\0')
|
||||
{
|
||||
if (strncmp(current_arg, "NULL", 4) == 0)
|
||||
type |= SCAN_NULL;
|
||||
else if (strncmp(current_arg, "SYN", 3) == 0)
|
||||
type |= SCAN_SYN;
|
||||
else if (strncmp(current_arg, "ACK", 3) == 0)
|
||||
type |= SCAN_ACK;
|
||||
else if (strncmp(current_arg, "FIN", 3) == 0)
|
||||
type |= SCAN_FIN;
|
||||
else if (strncmp(current_arg, "XMAS", 4) == 0)
|
||||
type |= SCAN_XMAS;
|
||||
else if (strncmp(current_arg, "UDP", 5) == 0)
|
||||
type |= SCAN_UDP;
|
||||
else
|
||||
{
|
||||
dprintf(2, "ft_nmap: invalid argument to --scan: '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
current_arg += strcspn(current_arg, ",");
|
||||
if (current_arg[0] == ',')
|
||||
current_arg++;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
|
||||
@ -114,20 +135,6 @@ static int check_arg(e_flag flag, const char *arg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FL_TYPE:
|
||||
if (!strcmp(arg, "SYN"))
|
||||
break;
|
||||
if (!strcmp(arg, "NULL"))
|
||||
break;
|
||||
if (!strcmp(arg, "ACK"))
|
||||
break;
|
||||
if (!strcmp(arg, "FIN"))
|
||||
break;
|
||||
if (!strcmp(arg, "XMAS"))
|
||||
break;
|
||||
if (!strcmp(arg, "UDP"))
|
||||
break;
|
||||
return -1;
|
||||
case FL_TTL: {
|
||||
int nb = atoi(arg);
|
||||
if (nb == 0) {
|
||||
@ -248,7 +255,7 @@ int parsing(struct scan *general, const struct option_lst *options)
|
||||
return -1;
|
||||
}
|
||||
general->type = parse_type(get_option_arg(options, FL_TYPE));
|
||||
if ((int)general->type == -1)
|
||||
if (general->type == (uint8_t) -1)
|
||||
return -1;
|
||||
const char *max_retries = get_option_arg(options, FL_MAXRETRIES);
|
||||
general->max_retries = max_retries ? atoi(max_retries) : 1;
|
||||
|
21
src/print.c
21
src/print.c
@ -31,20 +31,18 @@ void print_config(const struct scan *general, const char *hosts_path,
|
||||
printf("Number of scans to be performed: %d\n",
|
||||
general->port_end - general->port_start + 1);
|
||||
printf("Scans to be performed: ");
|
||||
if (general->type == SCAN_ALL)
|
||||
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++)
|
||||
for (uint8_t type = 0; type < NB_SCAN; type++)
|
||||
if (general->type & (1 << type))
|
||||
printf("%s ", types_str[type]);
|
||||
else
|
||||
printf("%s", types_str[general->type]);
|
||||
printf("\n");
|
||||
if (nb_threads > 1)
|
||||
printf("No of threads: %d\n", nb_threads);
|
||||
}
|
||||
|
||||
bool is_port_opened(const e_state states[6], e_scantype type)
|
||||
bool is_port_opened(const e_state states[6], uint8_t type)
|
||||
{
|
||||
if (type == SCAN_ALL) {
|
||||
for (e_scantype i = SCAN_NULL; i < SCAN_ALL; i++)
|
||||
for (uint8_t i = 0; i < NB_SCAN; i++)
|
||||
if (states[i] == OPENED)
|
||||
return true;
|
||||
return false;
|
||||
@ -52,20 +50,19 @@ bool is_port_opened(const e_state states[6], e_scantype type)
|
||||
return states[type] == OPENED;
|
||||
}
|
||||
|
||||
static void print_port_state(uint16_t port, e_scantype type,
|
||||
static void print_port_state(uint16_t port, uint8_t type,
|
||||
const struct response *response)
|
||||
{
|
||||
printf("%-5d %-12s ", port,
|
||||
response->service ? response->service : "Unassigned");
|
||||
if (response->service)
|
||||
free(response->service);
|
||||
if (type == SCAN_ALL)
|
||||
for (e_scantype i = SCAN_NULL; i < SCAN_ALL; i++)
|
||||
for (uint8_t i = 0; i < NB_SCAN; i++)
|
||||
{
|
||||
if ((1 << i) & type)
|
||||
printf("%s(%s) ", types_str[i],
|
||||
states_str[response->states[i]]);
|
||||
else
|
||||
printf("%s(%s) ", types_str[type],
|
||||
states_str[response->states[type]]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
108
src/response.c
108
src/response.c
@ -23,29 +23,39 @@ static char *get_service_name(int port, char *proto)
|
||||
|
||||
void tcp_response(const struct tcphdr *tcphdr, const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
if (type == SCAN_UDP) {
|
||||
if (data->type & SCAN_UDP) {
|
||||
dprintf(2,
|
||||
"ft_nmap: error: received a TCP responses for an UDP "
|
||||
"scan\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t type_index;
|
||||
for (uint8_t i = 0; i < NB_SCAN; i++)
|
||||
{
|
||||
if (data->type & (1 << i))
|
||||
{
|
||||
type_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->responses->service == NULL)
|
||||
data->responses->service =
|
||||
get_service_name(data->port_start, "tcp");
|
||||
if (type == SCAN_SYN) {
|
||||
if (data->type & SCAN_SYN) {
|
||||
if (tcphdr->ack == 1 && tcphdr->syn == 1)
|
||||
data->responses->states[type] = OPENED;
|
||||
data->responses->states[type_index] = OPENED;
|
||||
else if (tcphdr->ack == 1 && tcphdr->rst == 1)
|
||||
data->responses->states[type] = CLOSED;
|
||||
} else if (type == SCAN_ACK && tcphdr->rst == 1)
|
||||
data->responses->states[type] = UNFILTERED;
|
||||
else if (type == SCAN_NULL && tcphdr->rst == 1)
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_FIN && tcphdr->rst == 1)
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_XMAS && tcphdr->rst == 1)
|
||||
data->responses->states[type] = CLOSED;
|
||||
data->responses->states[type_index] = CLOSED;
|
||||
} else if (data->type & SCAN_ACK && tcphdr->rst == 1)
|
||||
data->responses->states[type_index] = UNFILTERED;
|
||||
else if (data->type & SCAN_NULL && tcphdr->rst == 1)
|
||||
data->responses->states[type_index] = CLOSED;
|
||||
else if (data->type & SCAN_FIN && tcphdr->rst == 1)
|
||||
data->responses->states[type_index] = CLOSED;
|
||||
else if (data->type & SCAN_XMAS && tcphdr->rst == 1)
|
||||
data->responses->states[type_index] = CLOSED;
|
||||
}
|
||||
|
||||
void udp_response(const struct udphdr *udphdr, const struct scan *data)
|
||||
@ -65,46 +75,62 @@ void udp_response(const struct udphdr *udphdr, const struct scan *data)
|
||||
|
||||
void icmp_response(const struct icmphdr *icmphdr, const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
uint8_t type_index;
|
||||
for (uint8_t i = 0; i < NB_SCAN; i++)
|
||||
{
|
||||
if (data->type & (1 << i))
|
||||
{
|
||||
type_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_ACK && icmphdr->type == 3)
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_NULL && icmphdr->type == 3)
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_FIN && icmphdr->type == 3)
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_XMAS && icmphdr->type == 3)
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
||||
data->responses->states[type] = CLOSED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
||||
data->responses->states[type] = FILTERED;
|
||||
if (data->type & SCAN_SYN && icmphdr->type == 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_ACK && icmphdr->type == 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_NULL && icmphdr->type == 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_FIN && icmphdr->type == 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_XMAS && icmphdr->type == 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
||||
data->responses->states[type_index] = CLOSED;
|
||||
else if (data->type & SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
}
|
||||
|
||||
void no_response(const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
uint8_t type_index;
|
||||
for (uint8_t i = 0; i < NB_SCAN; i++)
|
||||
{
|
||||
if (data->type & (1 << i))
|
||||
{
|
||||
type_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_ACK)
|
||||
data->responses->states[type] = FILTERED;
|
||||
else if (type == SCAN_NULL)
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_FIN)
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_XMAS)
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_UDP)
|
||||
data->responses->states[type] = OPENFILTERED;
|
||||
if (data->type & SCAN_SYN)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_ACK)
|
||||
data->responses->states[type_index] = FILTERED;
|
||||
else if (data->type & SCAN_NULL)
|
||||
data->responses->states[type_index] = OPENFILTERED;
|
||||
else if (data->type & SCAN_FIN)
|
||||
data->responses->states[type_index] = OPENFILTERED;
|
||||
else if (data->type & SCAN_XMAS)
|
||||
data->responses->states[type_index] = OPENFILTERED;
|
||||
else if (data->type & SCAN_UDP)
|
||||
data->responses->states[type_index] = OPENFILTERED;
|
||||
}
|
||||
|
17
src/scan.c
17
src/scan.c
@ -107,20 +107,19 @@ int scan(struct scan *data)
|
||||
|
||||
pcap_setnonblock(handle, 1, errbuf);
|
||||
|
||||
if (data->type == SCAN_ALL) {
|
||||
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) {
|
||||
data->type = type;
|
||||
for (uint8_t type = 0; type < NB_SCAN; type++) {
|
||||
uint8_t type_bak = data->type;
|
||||
data->type = data->type & (1 << type);
|
||||
if (data->type)
|
||||
{
|
||||
for (uint8_t retries = 0; retries < data->max_retries;
|
||||
retries++)
|
||||
{
|
||||
if (send_recv_packet(data, sockfd, handle))
|
||||
break;
|
||||
}
|
||||
data->type = SCAN_ALL;
|
||||
} else {
|
||||
for (uint8_t retries = 0; retries < data->max_retries;
|
||||
retries++)
|
||||
if (send_recv_packet(data, sockfd, handle))
|
||||
break;
|
||||
}
|
||||
data->type = type_bak;
|
||||
}
|
||||
|
||||
pcap_close(handle);
|
||||
|
Reference in New Issue
Block a user