branching out now to a pipeline design
This commit is contained in:
parent
14dcfdcafc
commit
3f86775ec2
9 changed files with 284 additions and 123 deletions
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 21:27:51 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 16:14:18 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -32,33 +32,23 @@
|
|||
|
||||
# include "libdill.h"
|
||||
|
||||
# define SCAN_TCP (1 << 0)
|
||||
# define SCAN_SYN (1 << 1)
|
||||
# define SCAN_NULL (1 << 2)
|
||||
# define SCAN_ACK (1 << 3)
|
||||
# define SCAN_FIN (1 << 4)
|
||||
# define SCAN_XMAS (1 << 5)
|
||||
# define SCAN_UDP (1 << 6)
|
||||
# define SCAN_MAX 7
|
||||
|
||||
typedef struct s_data t_data;
|
||||
typedef struct s_host t_host;
|
||||
typedef struct s_tcp_packet t_tcp_packet;
|
||||
typedef enum e_port_status t_port_status;
|
||||
typedef enum e_scan_type t_scan_type;
|
||||
|
||||
struct s_data
|
||||
enum e_scan_type
|
||||
{
|
||||
t_flag flag;
|
||||
char **av_data;
|
||||
t_list *host;
|
||||
|
||||
int sock_tcp;
|
||||
int threads;
|
||||
int scan;
|
||||
SCAN_TCP,
|
||||
SCAN_SYN,
|
||||
SCAN_ACK,
|
||||
SCAN_FIN,
|
||||
SCAN_XMAS,
|
||||
SCAN_UDP,
|
||||
SCAN_MAX
|
||||
};
|
||||
|
||||
struct
|
||||
|
||||
enum e_port_status
|
||||
{
|
||||
OPEN,
|
||||
|
|
@ -68,20 +58,36 @@ enum e_port_status
|
|||
OPEN_FILTERED,
|
||||
};
|
||||
|
||||
struct s_data
|
||||
{
|
||||
t_flag flag;
|
||||
char **av_data;
|
||||
|
||||
int sock[SCAN_MAX];
|
||||
struct sockaddr sock_a[SCAN_MAX];
|
||||
int threads;
|
||||
|
||||
t_list *host;
|
||||
BITFIELD(ports, USHRT_MAX + 1);
|
||||
BITFIELD(scans, SCAN_MAX);
|
||||
};
|
||||
|
||||
struct s_host
|
||||
{
|
||||
char *host; // user input host (ip or dn)
|
||||
char *dn; // ai_canonname
|
||||
char ip[INET6_ADDRSTRLEN]; // readable ip address (4 or 6)
|
||||
struct s_target ports[USHRT_MAX + 1];
|
||||
char *host; // user input host (ip or dn)
|
||||
char *dn; // ai_canonname
|
||||
char ip[INET6_ADDRSTRLEN]; // humain readable ip address
|
||||
struct sockaddr *addr;
|
||||
size_t addrlen;
|
||||
int chan[USHRT_MAX + 1][SCAN_MAX];
|
||||
};
|
||||
|
||||
struct s_target
|
||||
{
|
||||
int in_channel;
|
||||
t_port_status results[SCAN_MAX];
|
||||
t_host *host;
|
||||
uint16_t port;
|
||||
t_scan_type scan;
|
||||
#define capture_chan(t) (t.host.chan[t.port][t.scan])
|
||||
};
|
||||
|
||||
struct s_tcp_packet
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/03/20 15:41:59 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 12:57:23 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 14:46:46 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -36,4 +36,8 @@ size_t ft_lllen_base(long long n, int base);
|
|||
int ft_addrcmp(void *a, void *b);
|
||||
void *id(void *data);
|
||||
|
||||
extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
||||
extern inline void bitfield_bitoff(t_bitblock field[], uint64_t bit)
|
||||
extern inline uint64_t bitfield_lsb(t_bitblock field[], uint64_t size)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
68
nmap/libft/srcs/math/bitfield.c
Normal file
68
nmap/libft/srcs/math/bitfield.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* bitfield.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/09 14:44:16 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/09 15:57:25 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
** ==== Wrapper around GCC builtins for ====
|
||||
** ==== arbitrarily large sized bitfields ====
|
||||
**
|
||||
** todo
|
||||
** - up and down iterator
|
||||
**
|
||||
*/
|
||||
typedef uint64_t t_bitblock;
|
||||
|
||||
#define BITFIELD(var, size) t_bitblock var[size / sizeof(t_bitblock)]
|
||||
#define BLOCKSIZE (8 * sizeof(t_bitblock))
|
||||
|
||||
/*
|
||||
** Turn bit on
|
||||
*/
|
||||
extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
||||
{
|
||||
field[bit / BLOCKSIZE] |= (1 << bit % BLOCKSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Turn bit off
|
||||
*/
|
||||
extern inline void bitfield_bitoff(t_bitblock field[], uint64_t bit)
|
||||
{
|
||||
field[bit / BLOCKSIZE] &= ~(1 << bit % BLOCKSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Least Significant Bit (rightmost)
|
||||
*/
|
||||
extern inline uint64_t bitfield_lsb(t_bitblock field[], uint64_t size)
|
||||
{
|
||||
int block = -1;
|
||||
|
||||
while (!field[++block])
|
||||
if ((block+1) * BLOCKSIZE > size)
|
||||
return (-1);
|
||||
return (block * BLOCKSIZE + __builtin_ctzll(field[block] ^ (~field[block] + 1)) - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Count the number of 1-bits in field
|
||||
*/
|
||||
extern inline uint64_t bitfield_popcount(t_bitblock field[], uint64_t size)
|
||||
{
|
||||
int block = -1;
|
||||
int count = 0;
|
||||
|
||||
while (++block * BLOCKSIZE < size)
|
||||
count += __builtin_popcountll(field[block]);
|
||||
return (count);
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/07 18:02:55 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 21:21:55 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 10:48:18 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ static void packet_callback(u_char *arg, const struct pcap_pkthdr *pkthdr, const
|
|||
t_data *data = (t_data*)arg;
|
||||
ft_printf("received packet !!!\n");
|
||||
hexdump(&packet, sizeof(packet));
|
||||
host = extract_host(pkt);
|
||||
dport = extract_dport(pkt);
|
||||
sport = extract_sport(pkt);
|
||||
|
||||
chan = get_chan(host, dport, sport);
|
||||
chsend(ch, &pkt, sizeof(pkt), -1);
|
||||
}
|
||||
|
||||
coroutine void nmap_listener(t_data *data)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/08 19:10:04 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 21:27:57 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 15:58:02 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -15,7 +15,34 @@
|
|||
#define NMAP_USAGE1 " [--ip HOST] [--file FILE]"
|
||||
#define NMAP_USAGE2 " [--ports PORTS] [--speedup [NUMBER]] [--scan [TYPE]] HOST"
|
||||
|
||||
int nmap_ports(t_data *data, int ch)
|
||||
/*
|
||||
** only IPv4
|
||||
** only default network if
|
||||
** one per port per scan type
|
||||
*/
|
||||
int fill_ports(t_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
while (++i < SCAN_MAX)
|
||||
{
|
||||
if ((data->sock[i] = socket(AF_INET, SOCK_RAW, 0)) < 0)
|
||||
{
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
/* if (setsockopt(data->sock[i], IPPROTO_IP, IP_HDRINCL, (int[]){1}, sizeof(val)) == -1) */
|
||||
/* return (1); */
|
||||
data->sock_a[i].sin_family = AF_INET;
|
||||
data->sock_a[i].sin_addr.s_addr = INADDR_ANY;
|
||||
if (reserve_port(data.sock[i], &data.sock_a[i]))
|
||||
{
|
||||
fprintf(stderr, "couldn't reserve port\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
|
|
@ -32,19 +59,8 @@ int main(int ac, char **av)
|
|||
printf("or nmap"NMAP_USAGE1 NMAP_USAGE2"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// single tcp port
|
||||
struct sockaddr_in sa;
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = INADDR_ANY;
|
||||
if (reserve_port(data.sock_tcp, &sa))
|
||||
{
|
||||
fprintf(stderr, "couldn't reserve port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fill_ports(&data);
|
||||
go(nmap_listener(&data));
|
||||
int chan = nmap(&data);
|
||||
nmap_collector(chan, &data);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
144
nmap/srcs/nmap.c
144
nmap/srcs/nmap.c
|
|
@ -6,83 +6,111 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/08 19:10:07 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 21:27:50 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 17:12:31 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "nmap.h"
|
||||
|
||||
unsigned short cksum(void *b, int len)
|
||||
t_scanner g_scanners[SCAN_MAX]
|
||||
{
|
||||
unsigned short *buf = b;
|
||||
unsigned int sum=0;
|
||||
|
||||
for (sum = 0; len > 1; len -= 2)
|
||||
sum += *((unsigned short*)buf++);
|
||||
if (len == 1)
|
||||
sum += *(unsigned char*)buf;
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
return (~(sum + (sum >> 16)));
|
||||
scan_tcp,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/* scan_syn, */
|
||||
/* scan_ack, */
|
||||
/* scan_fin, */
|
||||
/* scan_xmas, */
|
||||
/* scan_udp, */
|
||||
}
|
||||
|
||||
coroutine void nmap_scan_node(t_host *host, struct iphdr *iph, int port)
|
||||
coroutine void nmap_scan_port(int ch, t_data *data, t_target target)
|
||||
{
|
||||
int channel;
|
||||
t_tcp_packet packet;
|
||||
int fan_in;
|
||||
int fan_in_local;
|
||||
int scan;
|
||||
|
||||
channel = host.channels[port];
|
||||
|
||||
packet.iph = *iph;
|
||||
tcphdr_init(&packet.tcph);
|
||||
packet.tcph.dest = htons(port);
|
||||
packet.tcph.source = ;
|
||||
/* packet.tcph.syn = 1; */
|
||||
packet.tcph.check = cksum(&packet, sizeof(t_tcp_packet));
|
||||
|
||||
if ((host.sock_tcp = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
|
||||
perror("server: socket");
|
||||
|
||||
int val = 1;
|
||||
if (setsockopt(host.sock_tcp, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) == -1)
|
||||
return (1);
|
||||
|
||||
|
||||
if (sendto(data->sock_tcp, &packet, sizeof(packet), 0,
|
||||
host->addr, host->addrlen) < 0)
|
||||
fan_in = chmake(sizeof(t_scan_result));
|
||||
while (scan = bitfield_lsb(data.scans, USHRT_MAX + 1))
|
||||
{
|
||||
perror("sendto");
|
||||
exit(1);
|
||||
data.scans &= ~scan;
|
||||
fan_in_local = hdup(fan_in);
|
||||
scanner = g_scanners[scan];
|
||||
go(scanner(fan_in_local, sock, target));
|
||||
}
|
||||
/* chrecv(channel, &buf, sizeof()) */
|
||||
printf("packet sent\n");
|
||||
hexdump(&packet, sizeof(packet));
|
||||
|
||||
while (nport)
|
||||
{
|
||||
int res;
|
||||
if ((res = choose(clauses, nport, -1)) < 0)
|
||||
printf("choose failed\n");
|
||||
nhost--;
|
||||
printf("finished scanning port %i\n", res);
|
||||
}
|
||||
|
||||
chsend(ch, &host, sizeof(host), -1);
|
||||
hclose(ch);
|
||||
}
|
||||
|
||||
coroutine void nmap_scan_host(int ch, t_data *data, t_target target)
|
||||
{
|
||||
int fan_in;
|
||||
int fan_in_local;
|
||||
t_target target;
|
||||
int port;
|
||||
|
||||
fan_in = chmake(sizeof(t_scan_result * SCAN_MAX));
|
||||
while (port = bitfield_lsb(data.ports, USHRT_MAX + 1))
|
||||
{
|
||||
data.ports &= ~port;
|
||||
fan_in_local = hdup(fan_in);
|
||||
target.port = port;
|
||||
go(nmap_scan_port(fan_in_local, data, port));
|
||||
}
|
||||
|
||||
while (nport)
|
||||
{
|
||||
int res;
|
||||
if ((res = choose(clauses, nport, -1)) < 0)
|
||||
printf("choose failed\n");
|
||||
nhost--;
|
||||
printf("finished scanning port #%i\n", res);
|
||||
}
|
||||
|
||||
chsend(ch, &host, sizeof(host), -1);
|
||||
hclose(ch);
|
||||
}
|
||||
|
||||
void nmap(t_data *data)
|
||||
{
|
||||
t_list *list;
|
||||
t_host *host;
|
||||
struct iphdr iph;
|
||||
t_list *list;
|
||||
t_host *host;
|
||||
int nhost;
|
||||
int fan_in_local;
|
||||
struct chclause clause[ft_lstsize(data->host)];
|
||||
int buf;
|
||||
|
||||
iphdr_init(&iph);
|
||||
iph.protocol = IPPROTO_TCP;
|
||||
iph.daddr = *(uint32_t*)&((struct sockaddr_in*)host->addr)->sin_addr;
|
||||
iph.saddr = *(uint32_t*)&((struct sockaddr_in*)&data->source_addr)->sin_addr;
|
||||
iph.tot_len = htons(sizeof(t_tcp_packet));
|
||||
int fan_in = chmake(sizeof());
|
||||
nhost = 0;
|
||||
for (t_list *list = data->host; list != NULL; list = list->next)
|
||||
{
|
||||
t_host *host = list->content;
|
||||
printf("scanning %s...\n", host->dn);
|
||||
for (port = 1; port < USHRT_MAX; port++;)
|
||||
{
|
||||
if (data.ports[port])
|
||||
{
|
||||
int fan_in_local = hdup(fan_in);
|
||||
go(nmap_scan_node(data, iph, port, fan_in_local));
|
||||
}
|
||||
}
|
||||
host = list->content;
|
||||
fan_in_local = hdup(fan_in);
|
||||
target.host = host;
|
||||
go(nmap_scan_host(fan_in_local, data, target));
|
||||
nhost++;
|
||||
}
|
||||
|
||||
while (nhost)
|
||||
{
|
||||
int res;
|
||||
if ((res = choose(clauses, nhost, -1)) < 0)
|
||||
printf("choose failed\n");
|
||||
nhost--;
|
||||
printf("host %s has finished scanning\n", host->dn);
|
||||
}
|
||||
printf("nmap has finished\n");
|
||||
return (fan_in);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/08 19:10:05 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/08 21:05:14 by jhalford ### ########.fr */
|
||||
/* Updated: 2017/10/09 14:51:21 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -82,19 +82,17 @@ static int nmap_get_scan(char *opt_arg, t_data *data)
|
|||
while (*opt_arg)
|
||||
{
|
||||
if (*opt_arg == 'T')
|
||||
data->scan |= SCAN_TCP;
|
||||
bitfield_biton(data->scans, SCAN_TCP);
|
||||
else if (*opt_arg == 'S')
|
||||
data->scan |= SCAN_SYN;
|
||||
else if (*opt_arg == 'N')
|
||||
data->scan |= SCAN_NULL;
|
||||
bitfield_biton(data->scans, SCAN_SYN);
|
||||
else if (*opt_arg == 'A')
|
||||
data->scan |= SCAN_ACK;
|
||||
bitfield_biton(data->scans, SCAN_ACK);
|
||||
else if (*opt_arg == 'F')
|
||||
data->scan |= SCAN_FIN;
|
||||
bitfield_biton(data->scans, SCAN_FIN);
|
||||
else if (*opt_arg == 'X')
|
||||
data->scan |= SCAN_XMAS;
|
||||
bitfield_biton(data->scans, SCAN_XMAS);
|
||||
else if (*opt_arg == 'U')
|
||||
data->scan |= SCAN_UDP;
|
||||
bitfield_biton(data->scans, SCAN_UDP);
|
||||
else
|
||||
return (1);
|
||||
opt_arg++;
|
||||
|
|
@ -107,7 +105,7 @@ int nmap_parse(int ac, char **av, t_data *data)
|
|||
struct ifaddrs *ifaddrs, *ifa_first;
|
||||
(void)ac;
|
||||
data->host = NULL;
|
||||
bzero(data->ports, USHRT_MAX + 1);
|
||||
bzero(data->ports, sizeof(data->ports));
|
||||
data->threads = 0;
|
||||
data->scan = 0;
|
||||
|
||||
|
|
@ -132,18 +130,6 @@ int nmap_parse(int ac, char **av, t_data *data)
|
|||
exit(1);
|
||||
}
|
||||
freeifaddrs(ifa_first);
|
||||
|
||||
for (t_list *list = data->host; list != NULL; list = list->next)
|
||||
{
|
||||
t_host *host = list->content;
|
||||
printf("scanning %s...\n", host->dn);
|
||||
for (port = 1; port < USHRT_MAX; port++;)
|
||||
{
|
||||
if (data.ports[port])
|
||||
host->channels[port] = chmake(sizeof(t_tcp_packet));
|
||||
}
|
||||
}
|
||||
|
||||
bitfield_biton(data->ports, 80);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
47
nmap/srcs/scanners.c
Normal file
47
nmap/srcs/scanners.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scanners.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/10/09 15:28:42 by jhalford #+# #+# */
|
||||
/* Updated: 2017/10/09 16:14:35 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "nmap.h"
|
||||
|
||||
coroutine void nmap_scan_tcp(int ch, t_data *data, t_target target)
|
||||
{
|
||||
int listen;
|
||||
t_scan_result res;
|
||||
t_tcp_packet pkt;
|
||||
|
||||
listen = capture_chan(target);
|
||||
|
||||
iphdr_init(&pkt.iph);
|
||||
|
||||
pkt.iph.protocol = IPPROTO_TCP;
|
||||
pkt.iph.saddr = *(uint32_t*)&((struct sockaddr_in*)&data->out_sa[target.scan])->sin_addr;
|
||||
pkt.iph.daddr = *(uint32_t*)&((struct sockaddr_in*)target.host->addr)->sin_addr;
|
||||
pkt.iph.tot_len = htons(sizeof(t_tcp_packet));
|
||||
|
||||
tcphdr_init(&pkt.tcph);
|
||||
packet.tcph.dest = htons(target.port);
|
||||
packet.tcph.check = cksum(&packet, sizeof(t_tcp_packet));
|
||||
|
||||
if (sendto(sock, &packet, sizeof(packet), 0,
|
||||
host->addr, host->addrlen) < 0)
|
||||
{
|
||||
perror("sendto");
|
||||
exit(1);
|
||||
}
|
||||
/* chrecv(channel, &buf, sizeof()) */
|
||||
hexdump(&packet, sizeof(packet));
|
||||
|
||||
|
||||
chsend(ch, res, sizeof(res), -1);
|
||||
printf("result sent\n");
|
||||
hclose(ch);
|
||||
}
|
||||
Loading…
Reference in a new issue