fix: pcap_dispatch is non blocking
feature: no response handle
This commit is contained in:
parent
936c277d02
commit
f35cad887d
@ -7,14 +7,20 @@
|
||||
|
||||
#include "scan.h"
|
||||
|
||||
#define TIMEOUT 1
|
||||
|
||||
typedef enum {
|
||||
OPEN = 1,
|
||||
CLOSE,
|
||||
OPENED,
|
||||
CLOSED,
|
||||
FILTERED,
|
||||
UNFILTERED,
|
||||
OPENFILTERED,
|
||||
} e_state;
|
||||
|
||||
[[__maybe_unused__]] static const char *states_str[] = {
|
||||
"OPENED", "CLOSED", "FILTERED", "UNFILTERED", "OPENFILTERED",
|
||||
};
|
||||
|
||||
struct response {
|
||||
uint16_t port;
|
||||
e_state states[SCAN_ALL];
|
||||
@ -24,3 +30,4 @@ struct response {
|
||||
void tcp_response(const struct tcphdr *tcphdr, const struct scan *data);
|
||||
void udp_response(const struct udphdr *udphdr, const struct scan *data);
|
||||
void icmp_response(const struct icmphdr *icmphdr, const struct scan *data);
|
||||
void no_response(const struct scan *data);
|
||||
|
11
src/main.c
11
src/main.c
@ -28,6 +28,17 @@ static int scan_host(char *host, const struct option_lst *options)
|
||||
struct response responses[1024] = {0};
|
||||
if (create_threads(options, ip_addr, responses) < 0)
|
||||
return 1;
|
||||
static const char *types_str[] = {
|
||||
"NULL", "SYN", "ACK", "FIN", "XMAS", "UDP",
|
||||
};
|
||||
for (uint16_t i = 0; i < 50; i++) {
|
||||
printf("%d: ", i + 1);
|
||||
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) {
|
||||
printf("%s(%s) ", types_str[type],
|
||||
states_str[responses[i].states[type]]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ char *get_option_arg(const struct option_lst *options, e_flag flag)
|
||||
e_scantype parse_type(const char *arg)
|
||||
{
|
||||
const char *types[] = {
|
||||
"SYN", "NULL", "ACK", "FIN", "XMAS", "UDP",
|
||||
"NULL", "SYN", "ACK", "FIN", "XMAS", "UDP",
|
||||
};
|
||||
|
||||
if (!arg)
|
||||
@ -53,15 +53,17 @@ int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
|
||||
for (; isdigit(arg[i]); i++)
|
||||
;
|
||||
int start = atoi(arg);
|
||||
if (arg[i] == '\0')
|
||||
return 0;
|
||||
if (arg[i++] != '-')
|
||||
return -1;
|
||||
goto error;
|
||||
int end = atoi(arg + i);
|
||||
for (; isdigit(arg[i]); i++)
|
||||
;
|
||||
if (arg[i])
|
||||
return -1;
|
||||
goto error;
|
||||
if (start >= end)
|
||||
return -1;
|
||||
goto error;
|
||||
if (end > UINT16_MAX) {
|
||||
dprintf(2,
|
||||
"ft_nmap: invalid argument: '%s': out of range: 0 "
|
||||
@ -72,6 +74,9 @@ int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
|
||||
*p_start = start;
|
||||
*p_end = end;
|
||||
return 0;
|
||||
error:
|
||||
dprintf(2, "ft_nmap: invalid argument: '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int check_arg(e_flag flag, const char *arg)
|
||||
|
@ -15,17 +15,17 @@ void tcp_response(const struct tcphdr *tcphdr, const struct scan *data)
|
||||
}
|
||||
if (type == SCAN_SYN) {
|
||||
if (tcphdr->ack == 1 && tcphdr->syn == 1)
|
||||
data->response->states[type] = OPEN;
|
||||
data->response->states[type] = OPENED;
|
||||
else if (tcphdr->ack == 1 && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSE;
|
||||
data->response->states[type] = CLOSED;
|
||||
} else if (type == SCAN_ACK && tcphdr->rst == 1)
|
||||
data->response->states[type] = UNFILTERED;
|
||||
else if (type == SCAN_NULL && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSE;
|
||||
data->response->states[type] = CLOSED;
|
||||
else if (type == SCAN_FIN && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSE;
|
||||
data->response->states[type] = CLOSED;
|
||||
else if (type == SCAN_XMAS && tcphdr->rst == 1)
|
||||
data->response->states[type] = CLOSE;
|
||||
data->response->states[type] = CLOSED;
|
||||
}
|
||||
|
||||
void udp_response(const struct udphdr *udphdr, const struct scan *data)
|
||||
@ -36,7 +36,7 @@ void udp_response(const struct udphdr *udphdr, const struct scan *data)
|
||||
"scan\n");
|
||||
return;
|
||||
}
|
||||
data->response->states[SCAN_UDP] = OPEN;
|
||||
data->response->states[SCAN_UDP] = OPENED;
|
||||
}
|
||||
|
||||
void icmp_response(const struct icmphdr *icmphdr, const struct scan *data)
|
||||
@ -54,7 +54,25 @@ void icmp_response(const struct icmphdr *icmphdr, const struct scan *data)
|
||||
else if (type == SCAN_XMAS && icmphdr->type == 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
||||
data->response->states[type] = CLOSE;
|
||||
data->response->states[type] = CLOSED;
|
||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
||||
data->response->states[type] = FILTERED;
|
||||
}
|
||||
|
||||
void no_response(const struct scan *data)
|
||||
{
|
||||
const e_scantype type = data->type;
|
||||
|
||||
if (type == SCAN_SYN)
|
||||
data->response->states[type] = FILTERED;
|
||||
else if (type == SCAN_ACK)
|
||||
data->response->states[type] = FILTERED;
|
||||
else if (type == SCAN_NULL)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_FIN)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_XMAS)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
else if (type == SCAN_UDP)
|
||||
data->response->states[type] = OPENFILTERED;
|
||||
}
|
||||
|
27
src/scan.c
27
src/scan.c
@ -39,6 +39,21 @@ static void dispatch_callback(u_char *user, const struct pcap_pkthdr *h,
|
||||
}
|
||||
}
|
||||
|
||||
static void send_recv_packet(const struct scan *data, int sockfd,
|
||||
pcap_t *handle)
|
||||
{
|
||||
send_packet(data, sockfd);
|
||||
uint8_t timer = 0;
|
||||
for (; timer < TIMEOUT * 100; timer++) {
|
||||
if (pcap_dispatch(handle, 1, dispatch_callback, (u_char *)data))
|
||||
break;
|
||||
usleep(100000);
|
||||
}
|
||||
if (timer == TIMEOUT * 100)
|
||||
no_response(data);
|
||||
pcap_breakloop(handle);
|
||||
}
|
||||
|
||||
int scan(struct scan *data)
|
||||
{
|
||||
int sockfd = socket(AF_INET, SOCK_RAW,
|
||||
@ -82,20 +97,16 @@ int scan(struct scan *data)
|
||||
|
||||
pcap_freecode(&fp);
|
||||
|
||||
pcap_setnonblock(handle, 1, errbuf);
|
||||
|
||||
if (data->type == SCAN_ALL) {
|
||||
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) {
|
||||
data->type = type;
|
||||
send_packet(data, sockfd);
|
||||
if (!pcap_dispatch(handle, 1, dispatch_callback,
|
||||
(u_char *)data))
|
||||
printf("timeout\n"); // TODO handle no response
|
||||
send_recv_packet(data, sockfd, handle);
|
||||
}
|
||||
data->type = SCAN_ALL;
|
||||
} else {
|
||||
send_packet(data, sockfd);
|
||||
if (!pcap_dispatch(handle, 1, dispatch_callback,
|
||||
(u_char *)data))
|
||||
printf("timeout\n");
|
||||
send_recv_packet(data, sockfd, handle);
|
||||
}
|
||||
|
||||
pcap_close(handle);
|
||||
|
@ -80,7 +80,7 @@ error:
|
||||
int create_threads(const struct option_lst *options, char *ip_addr,
|
||||
struct response *responses)
|
||||
{
|
||||
uint16_t port_start, port_end;
|
||||
uint16_t port_start = 0, port_end = 0;
|
||||
const char *ports = get_option_arg(options, FL_PORTS);
|
||||
if (parse_ports(ports, &port_start, &port_end) < 0)
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user