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"
|
#include "scan.h"
|
||||||
|
|
||||||
|
#define TIMEOUT 1
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OPEN = 1,
|
OPENED,
|
||||||
CLOSE,
|
CLOSED,
|
||||||
FILTERED,
|
FILTERED,
|
||||||
UNFILTERED,
|
UNFILTERED,
|
||||||
OPENFILTERED,
|
OPENFILTERED,
|
||||||
} e_state;
|
} e_state;
|
||||||
|
|
||||||
|
[[__maybe_unused__]] static const char *states_str[] = {
|
||||||
|
"OPENED", "CLOSED", "FILTERED", "UNFILTERED", "OPENFILTERED",
|
||||||
|
};
|
||||||
|
|
||||||
struct response {
|
struct response {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
e_state states[SCAN_ALL];
|
e_state states[SCAN_ALL];
|
||||||
@ -24,3 +30,4 @@ struct response {
|
|||||||
void tcp_response(const struct tcphdr *tcphdr, const struct scan *data);
|
void tcp_response(const struct tcphdr *tcphdr, const struct scan *data);
|
||||||
void udp_response(const struct udphdr *udphdr, 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 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};
|
struct response responses[1024] = {0};
|
||||||
if (create_threads(options, ip_addr, responses) < 0)
|
if (create_threads(options, ip_addr, responses) < 0)
|
||||||
return 1;
|
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;
|
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)
|
e_scantype parse_type(const char *arg)
|
||||||
{
|
{
|
||||||
const char *types[] = {
|
const char *types[] = {
|
||||||
"SYN", "NULL", "ACK", "FIN", "XMAS", "UDP",
|
"NULL", "SYN", "ACK", "FIN", "XMAS", "UDP",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!arg)
|
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++)
|
for (; isdigit(arg[i]); i++)
|
||||||
;
|
;
|
||||||
int start = atoi(arg);
|
int start = atoi(arg);
|
||||||
|
if (arg[i] == '\0')
|
||||||
|
return 0;
|
||||||
if (arg[i++] != '-')
|
if (arg[i++] != '-')
|
||||||
return -1;
|
goto error;
|
||||||
int end = atoi(arg + i);
|
int end = atoi(arg + i);
|
||||||
for (; isdigit(arg[i]); i++)
|
for (; isdigit(arg[i]); i++)
|
||||||
;
|
;
|
||||||
if (arg[i])
|
if (arg[i])
|
||||||
return -1;
|
goto error;
|
||||||
if (start >= end)
|
if (start >= end)
|
||||||
return -1;
|
goto error;
|
||||||
if (end > UINT16_MAX) {
|
if (end > UINT16_MAX) {
|
||||||
dprintf(2,
|
dprintf(2,
|
||||||
"ft_nmap: invalid argument: '%s': out of range: 0 "
|
"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_start = start;
|
||||||
*p_end = end;
|
*p_end = end;
|
||||||
return 0;
|
return 0;
|
||||||
|
error:
|
||||||
|
dprintf(2, "ft_nmap: invalid argument: '%s'\n", arg);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_arg(e_flag flag, const char *arg)
|
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 (type == SCAN_SYN) {
|
||||||
if (tcphdr->ack == 1 && tcphdr->syn == 1)
|
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)
|
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)
|
} else if (type == SCAN_ACK && tcphdr->rst == 1)
|
||||||
data->response->states[type] = UNFILTERED;
|
data->response->states[type] = UNFILTERED;
|
||||||
else if (type == SCAN_NULL && tcphdr->rst == 1)
|
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)
|
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)
|
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)
|
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");
|
"scan\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data->response->states[SCAN_UDP] = OPEN;
|
data->response->states[SCAN_UDP] = OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void icmp_response(const struct icmphdr *icmphdr, const struct scan *data)
|
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)
|
else if (type == SCAN_XMAS && icmphdr->type == 3)
|
||||||
data->response->states[type] = FILTERED;
|
data->response->states[type] = FILTERED;
|
||||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
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)
|
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
||||||
data->response->states[type] = FILTERED;
|
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 scan(struct scan *data)
|
||||||
{
|
{
|
||||||
int sockfd = socket(AF_INET, SOCK_RAW,
|
int sockfd = socket(AF_INET, SOCK_RAW,
|
||||||
@ -82,20 +97,16 @@ int scan(struct scan *data)
|
|||||||
|
|
||||||
pcap_freecode(&fp);
|
pcap_freecode(&fp);
|
||||||
|
|
||||||
|
pcap_setnonblock(handle, 1, errbuf);
|
||||||
|
|
||||||
if (data->type == SCAN_ALL) {
|
if (data->type == SCAN_ALL) {
|
||||||
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) {
|
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) {
|
||||||
data->type = type;
|
data->type = type;
|
||||||
send_packet(data, sockfd);
|
send_recv_packet(data, sockfd, handle);
|
||||||
if (!pcap_dispatch(handle, 1, dispatch_callback,
|
|
||||||
(u_char *)data))
|
|
||||||
printf("timeout\n"); // TODO handle no response
|
|
||||||
}
|
}
|
||||||
data->type = SCAN_ALL;
|
data->type = SCAN_ALL;
|
||||||
} else {
|
} else {
|
||||||
send_packet(data, sockfd);
|
send_recv_packet(data, sockfd, handle);
|
||||||
if (!pcap_dispatch(handle, 1, dispatch_callback,
|
|
||||||
(u_char *)data))
|
|
||||||
printf("timeout\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_close(handle);
|
pcap_close(handle);
|
||||||
|
@ -80,7 +80,7 @@ error:
|
|||||||
int create_threads(const struct option_lst *options, char *ip_addr,
|
int create_threads(const struct option_lst *options, char *ip_addr,
|
||||||
struct response *responses)
|
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);
|
const char *ports = get_option_arg(options, FL_PORTS);
|
||||||
if (parse_ports(ports, &port_start, &port_end) < 0)
|
if (parse_ports(ports, &port_start, &port_end) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user