Compare commits
12 Commits
3ebface620
...
master
Author | SHA1 | Date | |
---|---|---|---|
05dd5478c3 | |||
4c0230cd39 | |||
6f3bcc5ac7 | |||
65116f38d1 | |||
e09c9711ed | |||
317dfe747d | |||
afde93c7cf | |||
a5d663fa9a | |||
ff89de7fdc | |||
ddbaef1826 | |||
67e6707d7d | |||
8299154ee1 |
9
.clang-format
Normal file
9
.clang-format
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 8
|
||||||
|
UseTab: AlignWithSpaces
|
||||||
|
BreakBeforeBraces: Linux
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
IndentCaseLabels: false
|
||||||
|
ColumnLimit: 80
|
||||||
|
AlignConsecutiveMacros: true
|
2
Makefile
2
Makefile
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
11
src/main.c
11
src/main.c
@ -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,14 +63,16 @@ 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) {
|
||||||
general.dest_addr = dest_addr;
|
general.dest_addr = dest_addr;
|
||||||
|
28
src/packet.c
28
src/packet.c
@ -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));
|
||||||
|
103
src/parsing.c
103
src/parsing.c
@ -40,15 +40,34 @@ 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)
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
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,11 +140,11 @@ 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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -142,11 +155,11 @@ 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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -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,16 +224,18 @@ 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;
|
||||||
}
|
}
|
||||||
|
38
src/print.c
38
src/print.c
@ -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);
|
||||||
|
126
src/response.c
126
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)
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data->responses->service = get_service_name(data->port_start, "udp");
|
|
||||||
if (data->responses->service == NULL)
|
if (data->responses->service == NULL)
|
||||||
data->responses->service =
|
{
|
||||||
get_service_name(data->port_start, "tcp");
|
data->responses->service = get_service_name(data->port_start, "udp");
|
||||||
if (type == SCAN_SYN && icmphdr->type == 3)
|
if (data->responses->service == NULL)
|
||||||
data->responses->states[type] = FILTERED;
|
data->responses->service =
|
||||||
else if (type == SCAN_ACK && icmphdr->type == 3)
|
get_service_name(data->port_start, "tcp");
|
||||||
data->responses->states[type] = FILTERED;
|
}
|
||||||
else if (type == SCAN_NULL && icmphdr->type == 3)
|
if (data->type & SCAN_SYN && icmphdr->type == 3)
|
||||||
data->responses->states[type] = FILTERED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_FIN && icmphdr->type == 3)
|
else if (data->type & SCAN_ACK && icmphdr->type == 3)
|
||||||
data->responses->states[type] = FILTERED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_XMAS && icmphdr->type == 3)
|
else if (data->type & SCAN_NULL && icmphdr->type == 3)
|
||||||
data->responses->states[type] = FILTERED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code == 3)
|
else if (data->type & SCAN_FIN && icmphdr->type == 3)
|
||||||
data->responses->states[type] = CLOSED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_UDP && icmphdr->type == 3 && icmphdr->code != 3)
|
else if (data->type & SCAN_XMAS && icmphdr->type == 3)
|
||||||
data->responses->states[type] = FILTERED;
|
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)
|
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)
|
if (data->responses->service == NULL)
|
||||||
data->responses->service =
|
{
|
||||||
get_service_name(data->port_start, "tcp");
|
data->responses->service = get_service_name(data->port_start, "udp");
|
||||||
if (type == SCAN_SYN)
|
if (data->responses->service == NULL)
|
||||||
data->responses->states[type] = FILTERED;
|
data->responses->service =
|
||||||
else if (type == SCAN_ACK)
|
get_service_name(data->port_start, "tcp");
|
||||||
data->responses->states[type] = FILTERED;
|
}
|
||||||
else if (type == SCAN_NULL)
|
if (data->type & SCAN_SYN)
|
||||||
data->responses->states[type] = OPENFILTERED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_FIN)
|
else if (data->type & SCAN_ACK)
|
||||||
data->responses->states[type] = OPENFILTERED;
|
data->responses->states[type_index] = FILTERED;
|
||||||
else if (type == SCAN_XMAS)
|
else if (data->type & SCAN_NULL)
|
||||||
data->responses->states[type] = OPENFILTERED;
|
data->responses->states[type_index] = OPENFILTERED;
|
||||||
else if (type == SCAN_UDP)
|
else if (data->type & SCAN_FIN)
|
||||||
data->responses->states[type] = OPENFILTERED;
|
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;
|
||||||
}
|
}
|
||||||
|
27
src/scan.c
27
src/scan.c
@ -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;
|
data->type = type_bak;
|
||||||
} else {
|
|
||||||
for (uint8_t retries = 0; retries < data->max_retries;
|
|
||||||
retries++)
|
|
||||||
if (send_recv_packet(data, sockfd, handle))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_close(handle);
|
pcap_close(handle);
|
||||||
|
@ -25,10 +25,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user