fix: pcap_dispatch is non blocking

feature: no response handle
This commit is contained in:
0x35c 2025-05-30 16:12:51 +02:00
parent 936c277d02
commit f35cad887d
6 changed files with 74 additions and 22 deletions

View File

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

View File

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

View File

@ -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)

View File

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

View File

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

View File

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