Compare commits

...

12 Commits

Author SHA1 Message Date
05dd5478c3 fix: leaks and conditional jumps in the parsing 2025-07-02 16:41:02 +02:00
4c0230cd39 fix: leak 2025-07-02 09:18:41 -05:00
6f3bcc5ac7 fix: multiple scans (more than 2 now works)
fix: more threads than ports to scan works too
2025-07-02 16:01:06 +02:00
65116f38d1 fix: is_port_opened 2025-07-02 08:26:58 -05:00
e09c9711ed fix: start with without threads 2025-07-02 07:32:08 -05:00
317dfe747d fix: leak 2025-07-02 07:31:00 -05:00
afde93c7cf add: multi scan 2025-07-02 07:09:54 -05:00
a5d663fa9a fix: parsing handling negative values for the ports and threads 2025-06-17 21:47:13 +02:00
ff89de7fdc fix: timeout changed to 2s + invalid free fix when the socket creation fails 2025-06-16 01:16:16 +02:00
ddbaef1826 fix: remove breakloop 2025-06-15 22:58:06 +02:00
67e6707d7d fix: parsing continue with short options 2025-06-13 11:52:16 +02:00
8299154ee1 fix: print and free last opened port 2025-06-12 07:37:24 -05:00
12 changed files with 211 additions and 165 deletions

9
.clang-format Normal file
View File

@ -0,0 +1,9 @@
BasedOnStyle: LLVM
IndentWidth: 8
UseTab: AlignWithSpaces
BreakBeforeBraces: Linux
AllowShortIfStatementsOnASingleLine: Never
AllowShortFunctionsOnASingleLine: Empty
IndentCaseLabels: false
ColumnLimit: 80
AlignConsecutiveMacros: true

View File

@ -16,7 +16,7 @@ obj/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
$(NAME): $(OBJ) $(NAME): $(OBJ)
$(LD) $(LDFLAGS) -o $(NAME) $(OBJ) $(LD) -o $(NAME) $(OBJ) $(LDFLAGS)
clean: clean:
rm -rf obj rm -rf obj

View File

@ -28,6 +28,6 @@ struct option_lst {
struct option_lst *parse_options(int ac, char *const *av); struct option_lst *parse_options(int ac, char *const *av);
char *get_option_arg(const struct option_lst *options, e_flag flag); char *get_option_arg(const struct option_lst *options, e_flag flag);
bool option_isset(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); void free_options(struct option_lst *options);
int parsing(struct scan *general, const struct option_lst *options); int parsing(struct scan *general, const struct option_lst *options);

View File

@ -7,7 +7,7 @@
#include "scan.h" #include "scan.h"
#define TIMEOUT 5 #define TIMEOUT 2
typedef enum { typedef enum {
CLOSED, CLOSED,
@ -22,7 +22,7 @@ typedef enum {
}; };
struct response { struct response {
e_state states[SCAN_ALL]; e_state states[NB_SCAN];
char *service; char *service;
}; };

View File

@ -4,26 +4,26 @@
#include "host.h" #include "host.h"
typedef enum { #define SCAN_NULL (1 << 0)
SCAN_NULL, #define SCAN_SYN (1 << 1)
SCAN_SYN, #define SCAN_ACK (1 << 2)
SCAN_ACK, #define SCAN_FIN (1 << 3)
SCAN_FIN, #define SCAN_XMAS (1 << 4)
SCAN_XMAS, #define SCAN_UDP (1 << 5)
SCAN_UDP, #define SCAN_ALL (SCAN_NULL | SCAN_SYN | SCAN_ACK | SCAN_FIN | SCAN_XMAS | SCAN_UDP)
SCAN_ALL,
} e_scantype;
[[__maybe_unused__]] static const char *types_str[] = { [[__maybe_unused__]] static const char *types_str[] = {
"NULL", "SYN", "ACK", "FIN", "XMAS", "UDP", "NULL", "SYN", "ACK", "FIN", "XMAS", "UDP",
}; };
#define NB_SCAN (sizeof(types_str) / sizeof(*types_str))
struct scan { struct scan {
struct host host; struct host host;
char *dest_addr; char *dest_addr;
uint16_t port_start; uint16_t port_start;
uint16_t port_end; uint16_t port_end;
e_scantype type; uint8_t type;
uint8_t ttl; uint8_t ttl;
uint8_t max_retries; uint8_t max_retries;
struct response *responses; struct response *responses;

View File

@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <sys/param.h>
#include "dns.h" #include "dns.h"
#include "interface.h" #include "interface.h"
@ -62,13 +63,15 @@ int main(int ac, char **av)
return 1; return 1;
} }
if (get_interface_name(&general.host) < 0) if (get_interface_name(&general.host) < 0) {
free_options(options);
return -1; return -1;
}
char *nb_threads_str = get_option_arg(options, FL_SPEEDUP); char *nb_threads_str = get_option_arg(options, FL_SPEEDUP);
uint8_t nb_threads = 1; uint8_t nb_threads = 0;
if (nb_threads_str) if (nb_threads_str)
nb_threads = atoi(nb_threads_str); nb_threads = MIN(atoi(nb_threads_str), general.port_end - general.port_start + 1);
char *dest_addr = get_option_arg(options, FL_IP); char *dest_addr = get_option_arg(options, FL_IP);
if (dest_addr) { if (dest_addr) {

View File

@ -23,11 +23,11 @@ int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
tcphdr->source = htons(1234); tcphdr->source = htons(1234);
tcphdr->dest = htons(data->port_start); tcphdr->dest = htons(data->port_start);
tcphdr->doff = sizeof(struct tcphdr) / sizeof(int); tcphdr->doff = sizeof(struct tcphdr) / sizeof(int);
tcphdr->fin = data->type == SCAN_XMAS || data->type == SCAN_FIN; tcphdr->fin = ((data->type & SCAN_XMAS) != 0) || ((data->type & SCAN_FIN) != 0);
tcphdr->syn = data->type == SCAN_SYN; tcphdr->syn = ((data->type & SCAN_SYN) != 0);
tcphdr->psh = data->type == SCAN_XMAS; tcphdr->psh = ((data->type & SCAN_XMAS) != 0);
tcphdr->ack = data->type == SCAN_ACK; tcphdr->ack = ((data->type & SCAN_ACK) != 0);
tcphdr->urg = data->type == SCAN_XMAS; tcphdr->urg = ((data->type & SCAN_XMAS) != 0);
tcphdr->window = htons(5840); tcphdr->window = htons(5840);
tcphdr->urg_ptr = 0; 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) 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); void *packet = calloc(packet_size, 1);
if (!packet) { if (!packet) {
dprintf(2, dprintf(2,
@ -74,14 +74,10 @@ static void *create_packet(const struct scan *data, size_t packet_size)
iphdr->check = checksum(packet, packet_size); iphdr->check = checksum(packet, packet_size);
// this is starnakin stuff if (isudp)
switch ((int)isudp) {
case true:
create_udp_packet(packet + sizeof(struct iphdr), data); create_udp_packet(packet + sizeof(struct iphdr), data);
break; else
default:
create_tcp_packet(packet + sizeof(struct iphdr), data); create_tcp_packet(packet + sizeof(struct iphdr), data);
}
return packet; return packet;
} }
@ -94,16 +90,10 @@ int send_packet(const struct scan *data, int sockfd)
conn_addr.sin_addr.s_addr = inet_addr(data->dest_addr); conn_addr.sin_addr.s_addr = inet_addr(data->dest_addr);
size_t packet_size = sizeof(struct iphdr) + 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)); : sizeof(struct tcphdr));
void *packet = create_packet(data, packet_size); void *packet = create_packet(data, packet_size);
int one = 1;
const int *val = &one;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) {
perror("Error setting IP_HDRINCL");
return -1;
}
sendto(sockfd, packet, packet_size, 0, (struct sockaddr *)&conn_addr, sendto(sockfd, packet, packet_size, 0, (struct sockaddr *)&conn_addr,
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));

View File

@ -40,16 +40,35 @@ char *get_option_arg(const struct option_lst *options, e_flag flag)
return NULL; return NULL;
} }
e_scantype parse_type(const char *arg) uint8_t parse_type(char *arg)
{ {
if (!arg) if (!arg)
return SCAN_ALL; return SCAN_ALL;
for (size_t i = 0; i < 6; i++) uint8_t type = 0;
if (!strcmp(arg, types_str[i])) char *current_arg = strtok(arg, ",");
return i; while (current_arg) {
dprintf(2, "ft_nmap: type: invalid argument: '%s'\n", arg); if (strcmp(current_arg, "NULL") == 0)
type |= SCAN_NULL;
else if (strcmp(current_arg, "SYN") == 0)
type |= SCAN_SYN;
else if (strcmp(current_arg, "ACK") == 0)
type |= SCAN_ACK;
else if (strcmp(current_arg, "FIN") == 0)
type |= SCAN_FIN;
else if (strcmp(current_arg, "XMAS") == 0)
type |= SCAN_XMAS;
else if (strcmp(current_arg, "UDP") == 0)
type |= SCAN_UDP;
else {
dprintf(2,
"ft_nmap: invalid argument to --scan: '%s'\n",
arg);
return -1; return -1;
} }
current_arg = strtok(NULL, ",");
}
return type;
}
int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end) int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
{ {
@ -80,6 +99,10 @@ int parse_ports(const char *arg, uint16_t *p_start, uint16_t *p_end)
arg, UINT16_MAX); arg, UINT16_MAX);
return -1; return -1;
} }
if (start < 0 || end < 0) {
dprintf(2, "ft_nmap: invalid port value: %d\n", start);
return -1;
}
*p_start = start; *p_start = start;
*p_end = end; *p_end = end;
return 0; return 0;
@ -92,9 +115,13 @@ static int check_arg(e_flag flag, const char *arg)
{ {
switch (flag) { switch (flag) {
case FL_SPEEDUP: { case FL_SPEEDUP: {
for (size_t i = 0; arg[i]; i++) for (size_t i = 0; arg[i]; i++) {
if (!isdigit(arg[i])) if (!isdigit(arg[i])) {
dprintf(2, "ft_nmap: invalid argument: %s\n",
arg);
return -1; return -1;
}
}
int value = atoi(arg); int value = atoi(arg);
if (value < 0 || value > 250) { if (value < 0 || value > 250) {
dprintf(2, dprintf(2,
@ -106,20 +133,6 @@ static int check_arg(e_flag flag, const char *arg)
} }
break; 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: { case FL_TTL: {
int nb = atoi(arg); int nb = atoi(arg);
if (nb == 0) { if (nb == 0) {
@ -127,9 +140,9 @@ static int check_arg(e_flag flag, const char *arg)
"Invalid argument\n"); "Invalid argument\n");
return -1; return -1;
} else if (nb < 0 || nb > 255) { } else if (nb < 0 || nb > 255) {
dprintf( dprintf(2,
2, "ft_nmap: invalid argument: '%s': out "
"ft_nmap: invalid argument: '%s': out of range: 0 " "of range: 0 "
"<= value <= 255\n", "<= value <= 255\n",
arg); arg);
return -1; return -1;
@ -142,9 +155,9 @@ static int check_arg(e_flag flag, const char *arg)
dprintf(2, "ft_nmap: cannot set max_retries to 0\n"); dprintf(2, "ft_nmap: cannot set max_retries to 0\n");
return -1; return -1;
} else if (nb < 0 || nb > 255) { } else if (nb < 0 || nb > 255) {
dprintf( dprintf(2,
2, "ft_nmap: invalid argument: '%s': out "
"ft_nmap: invalid argument: '%s': out of range: 0 " "of range: 0 "
"<= value <= 255\n", "<= value <= 255\n",
arg); arg);
return -1; return -1;
@ -199,6 +212,7 @@ struct option_lst *parse_options(int ac, char *const *av)
{"scan", required_argument, 0, 0}, {"scan", required_argument, 0, 0},
{"max_retries", required_argument, 0, 0}, {"max_retries", required_argument, 0, 0},
{"ttl", required_argument, 0, 0}, {"ttl", required_argument, 0, 0},
{NULL, 0, 0, 0},
}; };
int c; int c;
@ -210,17 +224,19 @@ struct option_lst *parse_options(int ac, char *const *av)
switch (c) { switch (c) {
case 'F': case 'F':
add_option(&head, FL_FAST, optarg); add_option(&head, FL_FAST, optarg);
break; continue;
case '?': case '?':
free_options(head);
return NULL; return NULL;
default: default:
break; break;
} }
if (check_arg(option_index, optarg) < 0) if (check_arg(option_index, optarg) < 0 ||
return NULL; add_option(&head, option_index, optarg) < 0) {
if (add_option(&head, option_index, optarg) < 0) free_options(head);
return NULL; return NULL;
} }
}
return head; return head;
} }
@ -233,19 +249,18 @@ int parsing(struct scan *general, const struct option_lst *options)
if (parse_ports(get_option_arg(options, FL_PORTS), &general->port_start, if (parse_ports(get_option_arg(options, FL_PORTS), &general->port_start,
&general->port_end)) &general->port_end))
return -1; return -1;
if (general->port_start <= 0 || general->port_end <= 0) {
dprintf(2, "ft_nmap: invalid port value: %d\n",
general->port_start <= 0 ? general->port_start
: general->port_end);
return -1;
}
general->type = parse_type(get_option_arg(options, FL_TYPE)); general->type = parse_type(get_option_arg(options, FL_TYPE));
if ((int)general->type == -1) if (general->type == (uint8_t)-1)
return -1; return -1;
const char *max_retries = get_option_arg(options, FL_MAXRETRIES); const char *max_retries = get_option_arg(options, FL_MAXRETRIES);
general->max_retries = max_retries ? atoi(max_retries) : 1; general->max_retries = max_retries ? atoi(max_retries) : 1;
const char *ttl = get_option_arg(options, FL_TTL); const char *ttl = get_option_arg(options, FL_TTL);
general->ttl = ttl ? atoi(ttl) : 48; general->ttl = ttl ? atoi(ttl) : 48;
const char *nb_threads_str = get_option_arg(options, FL_SPEEDUP);
uint8_t nb_threads = nb_threads_str ? atoi(nb_threads_str) : 1;
if (general->port_end - general->port_start + 1 < nb_threads) {
dprintf(2, "ft_nmap: number of threads to use must be superior "
"or equals to the ports range\n");
return -1;
}
return 0; return 0;
} }

View File

@ -31,41 +31,35 @@ void print_config(const struct scan *general, const char *hosts_path,
printf("Number of scans to be performed: %d\n", printf("Number of scans to be performed: %d\n",
general->port_end - general->port_start + 1); general->port_end - general->port_start + 1);
printf("Scans to be performed: "); printf("Scans to be performed: ");
if (general->type == SCAN_ALL) for (uint8_t type = 0; type < NB_SCAN; type++)
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) if (general->type & (1 << type))
printf("%s ", types_str[type]); printf("%s ", types_str[type]);
else
printf("%s", types_str[general->type]);
printf("\n"); printf("\n");
if (nb_threads > 1) if (nb_threads > 1)
printf("No of threads: %d\n", nb_threads); 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])
{ {
if (type == SCAN_ALL) { for (uint8_t i = 0; i < NB_SCAN; i++)
for (e_scantype i = SCAN_NULL; i < SCAN_ALL; i++)
if (states[i] == OPENED) if (states[i] == OPENED)
return true; return true;
return false; return false;
} }
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) const struct response *response)
{ {
printf("%-5d %-12s ", port, printf("%-5d %-12s ", port,
response->service ? response->service : "Unassigned"); response->service ? response->service : "Unassigned");
if (response->service) if (response->service)
free(response->service); free(response->service);
if (type == SCAN_ALL) for (uint8_t i = 0; i < NB_SCAN; i++)
for (e_scantype i = SCAN_NULL; i < SCAN_ALL; i++) {
if ((1 << i) & type)
printf("%s(%s) ", types_str[i], printf("%s(%s) ", types_str[i],
states_str[response->states[i]]); states_str[response->states[i]]);
else }
printf("%s(%s) ", types_str[type],
states_str[response->states[type]]);
printf("\n"); printf("\n");
} }
@ -73,11 +67,11 @@ void print_host_results(const struct scan *general, double scan_time)
{ {
printf("IP address: %s\n", general->dest_addr); printf("IP address: %s\n", general->dest_addr);
printf("Opened ports:\n"); printf("Opened ports:\n");
for (uint16_t port = general->port_start; port < general->port_end; for (uint16_t port = general->port_start; port <= general->port_end;
port++) { port++) {
const struct response *response = const struct response *response =
&general->responses[port - general->port_start]; &general->responses[port - general->port_start];
if (is_port_opened(response->states, general->type)) if (is_port_opened(response->states))
print_port_state(port, general->type, response); print_port_state(port, general->type, response);
} }
printf("\n"); printf("\n");
@ -86,7 +80,7 @@ void print_host_results(const struct scan *general, double scan_time)
port++) { port++) {
const struct response *response = const struct response *response =
&general->responses[port - general->port_start]; &general->responses[port - general->port_start];
if (!is_port_opened(response->states, general->type)) if (!is_port_opened(response->states))
print_port_state(port, general->type, response); print_port_state(port, general->type, response);
} }
printf("\nScan took %lf secs\n", scan_time); printf("\nScan took %lf secs\n", scan_time);

View File

@ -23,29 +23,39 @@ static char *get_service_name(int port, char *proto)
void tcp_response(const struct tcphdr *tcphdr, const struct scan *data) void tcp_response(const struct tcphdr *tcphdr, const struct scan *data)
{ {
const e_scantype type = data->type; if (data->type & SCAN_UDP) {
if (type == SCAN_UDP) {
dprintf(2, dprintf(2,
"ft_nmap: error: received a TCP responses for an UDP " "ft_nmap: error: received a TCP responses for an UDP "
"scan\n"); "scan\n");
return; 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) if (data->responses->service == NULL)
data->responses->service = data->responses->service =
get_service_name(data->port_start, "tcp"); get_service_name(data->port_start, "tcp");
if (type == SCAN_SYN) { if (data->type & SCAN_SYN) {
if (tcphdr->ack == 1 && tcphdr->syn == 1) 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) else if (tcphdr->ack == 1 && tcphdr->rst == 1)
data->responses->states[type] = CLOSED; data->responses->states[type_index] = CLOSED;
} else if (type == SCAN_ACK && tcphdr->rst == 1) } else if (data->type & SCAN_ACK && tcphdr->rst == 1)
data->responses->states[type] = UNFILTERED; data->responses->states[type_index] = UNFILTERED;
else if (type == SCAN_NULL && tcphdr->rst == 1) else if (data->type & SCAN_NULL && tcphdr->rst == 1)
data->responses->states[type] = CLOSED; data->responses->states[type_index] = CLOSED;
else if (type == SCAN_FIN && tcphdr->rst == 1) else if (data->type & SCAN_FIN && tcphdr->rst == 1)
data->responses->states[type] = CLOSED; data->responses->states[type_index] = CLOSED;
else if (type == SCAN_XMAS && tcphdr->rst == 1) else if (data->type & SCAN_XMAS && tcphdr->rst == 1)
data->responses->states[type] = CLOSED; data->responses->states[type_index] = CLOSED;
} }
void udp_response(const struct udphdr *udphdr, const struct scan *data) void udp_response(const struct udphdr *udphdr, const struct scan *data)
@ -65,46 +75,68 @@ 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)
{ {
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;
}
}
if (data->responses->service == NULL)
{
data->responses->service = get_service_name(data->port_start, "udp"); data->responses->service = get_service_name(data->port_start, "udp");
if (data->responses->service == NULL) if (data->responses->service == NULL)
data->responses->service = data->responses->service =
get_service_name(data->port_start, "tcp"); get_service_name(data->port_start, "tcp");
if (type == SCAN_SYN && icmphdr->type == 3) }
data->responses->states[type] = FILTERED; if (data->type & SCAN_SYN && icmphdr->type == 3)
else if (type == SCAN_ACK && icmphdr->type == 3) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = FILTERED; else if (data->type & SCAN_ACK && icmphdr->type == 3)
else if (type == SCAN_NULL && icmphdr->type == 3) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = FILTERED; else if (data->type & SCAN_NULL && icmphdr->type == 3)
else if (type == SCAN_FIN && icmphdr->type == 3) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = FILTERED; else if (data->type & SCAN_FIN && icmphdr->type == 3)
else if (type == SCAN_XMAS && icmphdr->type == 3) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = FILTERED; else if (data->type & SCAN_XMAS && icmphdr->type == 3)
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = CLOSED; else if (data->type & SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3) data->responses->states[type_index] = CLOSED;
data->responses->states[type] = FILTERED; 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) 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;
}
}
if (data->responses->service == NULL)
{
data->responses->service = get_service_name(data->port_start, "udp"); data->responses->service = get_service_name(data->port_start, "udp");
if (data->responses->service == NULL) if (data->responses->service == NULL)
data->responses->service = data->responses->service =
get_service_name(data->port_start, "tcp"); get_service_name(data->port_start, "tcp");
if (type == SCAN_SYN) }
data->responses->states[type] = FILTERED; if (data->type & SCAN_SYN)
else if (type == SCAN_ACK) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = FILTERED; else if (data->type & SCAN_ACK)
else if (type == SCAN_NULL) data->responses->states[type_index] = FILTERED;
data->responses->states[type] = OPENFILTERED; else if (data->type & SCAN_NULL)
else if (type == SCAN_FIN) data->responses->states[type_index] = OPENFILTERED;
data->responses->states[type] = OPENFILTERED; else if (data->type & SCAN_FIN)
else if (type == SCAN_XMAS) data->responses->states[type_index] = OPENFILTERED;
data->responses->states[type] = OPENFILTERED; else if (data->type & SCAN_XMAS)
else if (type == SCAN_UDP) data->responses->states[type_index] = OPENFILTERED;
data->responses->states[type] = OPENFILTERED; else if (data->type & SCAN_UDP)
data->responses->states[type_index] = OPENFILTERED;
} }

View File

@ -48,7 +48,6 @@ static int send_recv_packet(const struct scan *data, int sockfd, pcap_t *handle)
break; break;
usleep(100000); usleep(100000);
} }
pcap_breakloop(handle);
if (timer == TIMEOUT * 10) { if (timer == TIMEOUT * 10) {
no_response(data); no_response(data);
return 0; return 0;
@ -65,6 +64,13 @@ int scan(struct scan *data)
return -1; return -1;
} }
int one = 1;
const int *val = &one;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) {
perror("Error setting IP_HDRINCL");
return -1;
}
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 net, mask; bpf_u_int32 net, mask;
@ -101,20 +107,19 @@ int scan(struct scan *data)
pcap_setnonblock(handle, 1, errbuf); pcap_setnonblock(handle, 1, errbuf);
if (data->type == SCAN_ALL) { for (uint8_t type = 0; type < NB_SCAN; type++) {
for (e_scantype type = SCAN_NULL; type < SCAN_ALL; type++) { uint8_t type_bak = data->type;
data->type = type; data->type = data->type & (1 << type);
if (data->type)
{
for (uint8_t retries = 0; retries < data->max_retries; for (uint8_t retries = 0; retries < data->max_retries;
retries++) retries++)
{
if (send_recv_packet(data, sockfd, handle)) if (send_recv_packet(data, sockfd, handle))
break; break;
} }
data->type = SCAN_ALL; }
} else { data->type = type_bak;
for (uint8_t retries = 0; retries < data->max_retries;
retries++)
if (send_recv_packet(data, sockfd, handle))
break;
} }
pcap_close(handle); pcap_close(handle);

View File

@ -25,11 +25,9 @@ void *routine(void *p_data)
scan_data.port_end = port; scan_data.port_end = port;
scan_data.responses = scan_data.responses =
&thread_data->responses[port - thread_data->port_start]; &thread_data->responses[port - thread_data->port_start];
if (scan(&scan_data)) { if (scan(&scan_data))
free(p_data);
return NULL; return NULL;
} }
}
return NULL; return NULL;
} }
@ -67,7 +65,7 @@ static struct scan *init_threads_data(const struct scan *general,
int create_threads(struct scan *general, uint8_t nb_threads) int create_threads(struct scan *general, uint8_t nb_threads)
{ {
if (nb_threads == 1) { if (nb_threads == 0) {
routine(general); routine(general);
return 0; return 0;
} }