changed pattern completely, much better
This commit is contained in:
parent
3f86775ec2
commit
73b7fbcd2a
22 changed files with 1370 additions and 358 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
# By: wescande <wescande@student.42.fr> +#+ +:+ +#+ #
|
# By: wescande <wescande@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2016/08/29 21:32:58 by wescande #+# #+# #
|
# Created: 2016/08/29 21:32:58 by wescande #+# #+# #
|
||||||
# Updated: 2017/10/08 19:09:21 by jhalford ### ########.fr #
|
# Updated: 2017/10/24 14:33:26 by jhalford ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
|
@ -31,10 +31,12 @@ INC_DIR = includes/
|
||||||
OBJ_DIR = objs/
|
OBJ_DIR = objs/
|
||||||
|
|
||||||
SRC_BASE = \
|
SRC_BASE = \
|
||||||
main.c\
|
format.c\
|
||||||
nmap.c\
|
ip.c\
|
||||||
parser.c\
|
|
||||||
listener.c\
|
listener.c\
|
||||||
|
main.c\
|
||||||
|
parser.c\
|
||||||
|
scanners.c
|
||||||
|
|
||||||
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
||||||
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
||||||
|
|
@ -52,7 +54,7 @@ $(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(CLIENT_OBJ)
|
||||||
-I $(LIBFT_INC) \
|
-I $(LIBFT_INC) \
|
||||||
-L $(HOME)/.bin/lib \
|
-L $(HOME)/.bin/lib \
|
||||||
$(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS) \
|
$(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS) \
|
||||||
-lm -lpcap -lpthread /usr/local/lib/libdill.a
|
-lm -lpcap -lpthread $(HOME)/.bin/lib/libmill.a
|
||||||
@printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n"
|
@printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n"
|
||||||
|
|
||||||
$(LIBFT_LIB):
|
$(LIBFT_LIB):
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */
|
/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 16:14:18 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:29:35 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
# include <net/if.h>
|
# include <net/if.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# include <netinet/ip.h>
|
# include <netinet/ip.h>
|
||||||
|
# include <netinet/tcp.h>
|
||||||
# include <netinet/ip_icmp.h>
|
# include <netinet/ip_icmp.h>
|
||||||
# include <netinet/if_ether.h>
|
# include <netinet/if_ether.h>
|
||||||
# include <pcap.h>
|
# include <pcap.h>
|
||||||
|
|
@ -30,11 +31,13 @@
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
# include <ifaddrs.h>
|
# include <ifaddrs.h>
|
||||||
|
|
||||||
# include "libdill.h"
|
# include "libmill.h"
|
||||||
|
|
||||||
typedef struct s_data t_data;
|
typedef struct s_data t_data;
|
||||||
typedef struct s_host t_host;
|
typedef struct s_host t_host;
|
||||||
typedef struct s_tcp_packet t_tcp_packet;
|
typedef struct s_tcp_packet t_tcp_packet;
|
||||||
|
typedef struct s_job t_job;
|
||||||
|
typedef struct s_result t_result;
|
||||||
typedef enum e_port_status t_port_status;
|
typedef enum e_port_status t_port_status;
|
||||||
typedef enum e_scan_type t_scan_type;
|
typedef enum e_scan_type t_scan_type;
|
||||||
|
|
||||||
|
|
@ -62,14 +65,6 @@ struct s_data
|
||||||
{
|
{
|
||||||
t_flag flag;
|
t_flag flag;
|
||||||
char **av_data;
|
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
|
struct s_host
|
||||||
|
|
@ -79,27 +74,35 @@ struct s_host
|
||||||
char ip[INET6_ADDRSTRLEN]; // humain readable ip address
|
char ip[INET6_ADDRSTRLEN]; // humain readable ip address
|
||||||
struct sockaddr *addr;
|
struct sockaddr *addr;
|
||||||
size_t addrlen;
|
size_t addrlen;
|
||||||
int chan[USHRT_MAX + 1][SCAN_MAX];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct s_target
|
struct s_job
|
||||||
{
|
{
|
||||||
t_host *host;
|
ipaddr dest;
|
||||||
uint16_t port;
|
void (*scan)();
|
||||||
t_scan_type scan;
|
|
||||||
#define capture_chan(t) (t.host.chan[t.port][t.scan])
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct s_tcp_packet
|
struct s_result
|
||||||
{
|
{
|
||||||
struct iphdr iph;
|
ipaddr dest;
|
||||||
struct tcphdr tcph;
|
char scan[4];
|
||||||
}__attribute__((packed));
|
t_port_status status;
|
||||||
|
};
|
||||||
|
|
||||||
static t_cliopts g_opts[];
|
extern t_cliopts g_opts[];
|
||||||
int nmap_parse(int ac, char **av, t_data *data);
|
extern int g_njobs;
|
||||||
|
chan nmap_parse(int ac, char **av);
|
||||||
|
void nmap_format(chan results);
|
||||||
|
|
||||||
void nmap(t_data *data);
|
coroutine void nmap_scan_tcp(chan results, t_job job);
|
||||||
void nmap_listener(void *arg);
|
chan nmap_listener(ipaddr dst, ipaddr src);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** IP helpers
|
||||||
|
*/
|
||||||
|
uint16_t ipport(ipaddr ip);
|
||||||
|
uint16_t ipmode(ipaddr ip);
|
||||||
|
uint16_t ipfamily(ipaddr ip);
|
||||||
|
ipaddr iplocal_randport(const char *name, int mode, int sock);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ lst/lst_insert_sort.c\
|
||||||
lst/pop.c\
|
lst/pop.c\
|
||||||
lst/push.c\
|
lst/push.c\
|
||||||
lst/top.c\
|
lst/top.c\
|
||||||
|
math/bitfield.c\
|
||||||
math/ft_addrcmp.c\
|
math/ft_addrcmp.c\
|
||||||
math/ft_ilen.c\
|
math/ft_ilen.c\
|
||||||
math/ft_ilen_base.c\
|
math/ft_ilen_base.c\
|
||||||
|
|
@ -138,6 +139,7 @@ net/host.c\
|
||||||
net/ip.c\
|
net/ip.c\
|
||||||
net/net_get.c\
|
net/net_get.c\
|
||||||
net/net_send.c\
|
net/net_send.c\
|
||||||
|
net/prettypacket.c\
|
||||||
net/reserve_port.c\
|
net/reserve_port.c\
|
||||||
net/tcp.c\
|
net/tcp.c\
|
||||||
path/ft_path_notdir.c\
|
path/ft_path_notdir.c\
|
||||||
|
|
@ -204,6 +206,7 @@ str/ft_strstr.c\
|
||||||
str/ft_strsub.c\
|
str/ft_strsub.c\
|
||||||
str/ft_strtok.c\
|
str/ft_strtok.c\
|
||||||
str/ft_strtrim.c\
|
str/ft_strtrim.c\
|
||||||
|
str/hexstring.c\
|
||||||
sys/open_new.c\
|
sys/open_new.c\
|
||||||
time/epoch.c
|
time/epoch.c
|
||||||
|
|
||||||
|
|
|
||||||
36
nmap/libft/includes/hexstring.h
Normal file
36
nmap/libft/includes/hexstring.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* hexstring.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/24 21:37:32 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:46:12 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HEXSTRING HEADER
|
||||||
|
*
|
||||||
|
* Functions used to convert, and manipulate hexstrings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEXSTRING_H_
|
||||||
|
# define HEXSTRING_H_
|
||||||
|
|
||||||
|
# include "libft.h"
|
||||||
|
|
||||||
|
# include <ctype.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include <assert.h>
|
||||||
|
# include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
char *raw_to_hexstr(const char *raw, int size);
|
||||||
|
char *hexstr_to_raw(const char *hexstr, int *size);
|
||||||
|
void hex_to_str(uint8_t hex, char *str);
|
||||||
|
uint8_t str_to_hex(char *str);
|
||||||
|
|
||||||
|
#endif /* HEXSTRING_H_ */
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2016/11/07 13:49:04 by jhalford #+# #+# */
|
/* Created: 2016/11/07 13:49:04 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/08 15:59:49 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:38:26 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -37,8 +37,9 @@
|
||||||
# include "math.h"
|
# include "math.h"
|
||||||
# include "mytime.h"
|
# include "mytime.h"
|
||||||
# include "get_next_line.h"
|
# include "get_next_line.h"
|
||||||
# include "net.h"
|
|
||||||
# include "sys.h"
|
# include "sys.h"
|
||||||
|
# include "net.h"
|
||||||
|
# include "prettypacket.h"
|
||||||
|
|
||||||
struct s_stos
|
struct s_stos
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/03/20 15:41:59 by jhalford #+# #+# */
|
/* Created: 2017/03/20 15:41:59 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 14:46:46 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:04:50 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -36,8 +36,14 @@ size_t ft_lllen_base(long long n, int base);
|
||||||
int ft_addrcmp(void *a, void *b);
|
int ft_addrcmp(void *a, void *b);
|
||||||
void *id(void *data);
|
void *id(void *data);
|
||||||
|
|
||||||
extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
typedef uint64_t t_bitblock;
|
||||||
extern inline void bitfield_bitoff(t_bitblock field[], uint64_t bit)
|
#define BITFIELD(var, size) t_bitblock var[size / sizeof(t_bitblock) + 1]\
|
||||||
extern inline uint64_t bitfield_lsb(t_bitblock field[], uint64_t size)
|
= {[0] = size}
|
||||||
|
#define BLOCKSIZE (8 * sizeof(t_bitblock))
|
||||||
|
|
||||||
|
|
||||||
|
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[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/07 18:06:12 by jhalford #+# #+# */
|
/* Created: 2017/10/07 18:06:12 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/08 16:52:48 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 20:55:02 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
** utilities
|
** utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int reserve_port(int *port);
|
int reserve_port(int s, struct sockaddr *sa);
|
||||||
unsigned short cksum(void *b, int len);
|
unsigned short cksum(void *b, int len);
|
||||||
int host_format(struct sockaddr *addr);
|
int host_format(struct sockaddr *addr);
|
||||||
|
|
||||||
|
|
@ -64,4 +64,10 @@ void ip_load_icmp(struct icmp *icmp, void *buf);
|
||||||
*/
|
*/
|
||||||
void tcp_hdrinit(struct tcphdr *header);
|
void tcp_hdrinit(struct tcphdr *header);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** prettypacket
|
||||||
|
*/
|
||||||
|
int prettypacket(void *pkt, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
98
nmap/libft/includes/prettypacket.h
Normal file
98
nmap/libft/includes/prettypacket.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* prettypacket.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/24 21:38:38 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:41:44 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __PRETTYPACKET_H__
|
||||||
|
#define __PRETTYPACKET_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "hexstring.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable disable colored output (enabled by default)
|
||||||
|
*/
|
||||||
|
static int colored_output = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of available colors
|
||||||
|
*/
|
||||||
|
static const char *colors[] = {
|
||||||
|
/// Black
|
||||||
|
"\\e[0;30m",
|
||||||
|
/// Red
|
||||||
|
"\\e[0;31m",
|
||||||
|
/// Green
|
||||||
|
"\\e[0;32m",
|
||||||
|
/// Yellow
|
||||||
|
"\\e[0;33m",
|
||||||
|
/// Blue
|
||||||
|
"\\e[0;34m",
|
||||||
|
/// Purple
|
||||||
|
"\\e[0;35m",
|
||||||
|
/// Cyan
|
||||||
|
"\\e[0;36m",
|
||||||
|
/// White
|
||||||
|
"\\e[0;37m",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset color
|
||||||
|
*/
|
||||||
|
static const char *color_reset = "\\e[0m";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default terminal rows
|
||||||
|
*/
|
||||||
|
static const int rows = 24;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default terminal columns
|
||||||
|
*/
|
||||||
|
static const int cols = 80;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example ARP packet
|
||||||
|
*/
|
||||||
|
static const char arp_packet[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xAA\x00\x04\x00\x0A\x04\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\xAA\x00\x04\x00\x0A\x04\xC0\xA8\x01\x09\x00\x00\x00\x00\x00\x00\xC0\xA8\x01\x04";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example TCP packet
|
||||||
|
*/
|
||||||
|
static const char tcp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x34\x5A\xAE\x40\x00\x40\x06\x5E\x67\xC0\xA8\x01\x09\x58\xBF\x67\x3E\x9B\x44\x00\x50\x8E\xB5\xC6\xAC\x15\x93\x47\x9E\x80\x10\x00\x58\xA5\xA0\x00\x00\x01\x01\x08\x0A\x00\x09\xC3\xB2\x42\x5B\xFA\xD6";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example ICMP packet
|
||||||
|
*/
|
||||||
|
static const char icmp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x54\x00\x00\x40\x00\x40\x01\x54\x4E\xC0\xA8\x01\x09\xC0\xA8\x64\x01\x08\x00\x34\x98\xD7\x10\x00\x01\x5B\x68\x98\x4C\x00\x00\x00\x00\x2D\xCE\x0C\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example UDP packet
|
||||||
|
*/
|
||||||
|
static const char udp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x3C\x9B\x23\x00\x00\x40\x11\x70\xBC\xC0\xA8\x01\x09\xD0\x43\xDC\xDC\x91\x02\x00\x35\x00\x28\x6F\x0B\xAE\x9C\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x06\x67\x6F\x6F\x67\x6C\x65\x03\x63\x6F\x6D\x00\x00\x01\x00\x01";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example IGMP packet
|
||||||
|
*/
|
||||||
|
static const char igmp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x1C\x00\x00\x40\x00\x40\x02\x54\x4E\xC0\xA8\x01\x09\xC0\xA8\x64\x01\x11\xFF\x0D\xFF\xE0\x00\x00\x01";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example Spanning Tree Protocol (STP) packet
|
||||||
|
*/
|
||||||
|
static const char stp_packet[]="\x01\x80\xc2\x00\x00\x00\x00\x1c\x0e\x87\x85\x04\x00\x26\x42\x42\x03\x00\x00\x00\x00\x00\x80\x64\x00\x1c\x0e\x87\x78\x00\x00\x00\x00\x04\x80\x64\x00\x1c\x0e\x87\x85\x00\x80\x04\x01\x00\x14\x00\x02\x00\x0f\x00";
|
||||||
|
|
||||||
|
// functions that need prototypes
|
||||||
|
void layer_2_dispatcher(const char *, int, uint64_t);
|
||||||
|
void layer_3_dispatcher(const char *, int, uint64_t);
|
||||||
|
void layer_4_dispatcher(const char *, int, uint64_t);
|
||||||
|
|
||||||
|
#endif /* __PRETTYPACKET_H__ */
|
||||||
|
|
@ -6,10 +6,11 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/09 14:44:16 by jhalford #+# #+# */
|
/* Created: 2017/10/09 14:44:16 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 15:57:25 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:04:39 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "libft.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -20,17 +21,13 @@
|
||||||
** - up and down iterator
|
** - 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
|
** Turn bit on
|
||||||
*/
|
*/
|
||||||
extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
||||||
{
|
{
|
||||||
field[bit / BLOCKSIZE] |= (1 << bit % BLOCKSIZE);
|
field[bit / BLOCKSIZE + 1] |= (1 << (bit % BLOCKSIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -38,19 +35,21 @@ extern inline void bitfield_biton(t_bitblock field[], uint64_t bit)
|
||||||
*/
|
*/
|
||||||
extern inline void bitfield_bitoff(t_bitblock field[], uint64_t bit)
|
extern inline void bitfield_bitoff(t_bitblock field[], uint64_t bit)
|
||||||
{
|
{
|
||||||
field[bit / BLOCKSIZE] &= ~(1 << bit % BLOCKSIZE);
|
field[bit / BLOCKSIZE + 1] &= ~(1 << bit % BLOCKSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Least Significant Bit (rightmost)
|
** Least Significant Bit (rightmost)
|
||||||
*/
|
*/
|
||||||
extern inline uint64_t bitfield_lsb(t_bitblock field[], uint64_t size)
|
extern inline uint64_t bitfield_lsb(t_bitblock field[])
|
||||||
{
|
{
|
||||||
int block = -1;
|
int block;
|
||||||
|
uint64_t size;
|
||||||
|
|
||||||
|
block = 0;
|
||||||
|
size = field[0];
|
||||||
while (!field[++block])
|
while (!field[++block])
|
||||||
if ((block+1) * BLOCKSIZE > size)
|
if ((block+1) * BLOCKSIZE > size) return (-1);
|
||||||
return (-1);
|
|
||||||
return (block * BLOCKSIZE + __builtin_ctzll(field[block] ^ (~field[block] + 1)) - 1);
|
return (block * BLOCKSIZE + __builtin_ctzll(field[block] ^ (~field[block] + 1)) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/07 18:02:39 by jhalford #+# #+# */
|
/* Created: 2017/10/07 18:02:39 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/08 15:52:39 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 12:44:35 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
|
||||||
666
nmap/libft/srcs/net/prettypacket.c
Normal file
666
nmap/libft/srcs/net/prettypacket.c
Normal file
|
|
@ -0,0 +1,666 @@
|
||||||
|
/*
|
||||||
|
* prettypacket.c
|
||||||
|
*
|
||||||
|
* Created on: 03/dec/2012
|
||||||
|
* Author: Acri Emanuele <crossbower@gmail.com>
|
||||||
|
*
|
||||||
|
* Disassemble network packet and print their fields.
|
||||||
|
* Uses the stdin to receive raw packet data. Prints on stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "prettypacket.h"
|
||||||
|
|
||||||
|
#define VERSION "1.5"
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 8192
|
||||||
|
/**
|
||||||
|
* Byte multiplier: a printed byte uses 3 characters
|
||||||
|
*/
|
||||||
|
#define BYTE_MULT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet type arguments
|
||||||
|
*/
|
||||||
|
enum packet_type {
|
||||||
|
no_type = 0,
|
||||||
|
tcp,
|
||||||
|
udp,
|
||||||
|
icmp,
|
||||||
|
igmp,
|
||||||
|
arp,
|
||||||
|
stp
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Packets disassembling loop
|
||||||
|
** layer 2: isl, llc1, llc2, ethenet or payload
|
||||||
|
** layer 3: IPv4, IPv6, arp or payload
|
||||||
|
** layer 4: icmp, igmp, tcp, udp or payload
|
||||||
|
*/
|
||||||
|
int prettypacket(void *pkt, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
layer_2_dispatcher(pkt, size, 0);
|
||||||
|
puts("\n ----------- ");
|
||||||
|
fflush(stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the successive color iterating on colors
|
||||||
|
*
|
||||||
|
* @return pointer to the next color string
|
||||||
|
*/
|
||||||
|
const char *next_color() {
|
||||||
|
static int total_colors = sizeof(colors)/sizeof(char *);
|
||||||
|
static int index = -1;
|
||||||
|
|
||||||
|
return colors[ (++index) % total_colors ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract protocol number (8bit version)
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network
|
||||||
|
* @param counter protocol number offset
|
||||||
|
* @return protocol number in host format
|
||||||
|
*/
|
||||||
|
static inline uint8_t protocol_8bit_extract(const char *packet_buffer, int counter) {
|
||||||
|
return *(packet_buffer + counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract protocol number (16bit version)
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network
|
||||||
|
* @param counter protocol number offset
|
||||||
|
* @return protocol number in host format
|
||||||
|
*/
|
||||||
|
static inline uint16_t protocol_16bit_extract(const char *packet_buffer, int counter) {
|
||||||
|
return ntohs(*((uint16_t *)(packet_buffer + counter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract protocol type from ethernet Destination MAC Address (48bit)
|
||||||
|
* @param packet_buffer raw packet captured from the network
|
||||||
|
* @param counter protocol number offset
|
||||||
|
* @return protocol number in host format
|
||||||
|
*/
|
||||||
|
static inline uint64_t protocol_48bit_extract(const char *packet_buffer, int counter) {
|
||||||
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i=0; i < 6; i++) {
|
||||||
|
uint8_t byte = *((uint8_t *)(packet_buffer + counter + i));
|
||||||
|
|
||||||
|
value = byte + (value * 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diplay a single field of an header
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param field_size size in bytes of the field to print
|
||||||
|
* @param counter read bytes counter
|
||||||
|
* @param field_text description of the field
|
||||||
|
*/
|
||||||
|
static inline void field_print (const char *packet_buffer, int field_size,
|
||||||
|
int *counter, const char *field_text) {
|
||||||
|
|
||||||
|
char *tmp_hexstr = raw_to_hexstr(packet_buffer + *counter, field_size);
|
||||||
|
*counter += field_size;
|
||||||
|
|
||||||
|
printf(" %-24s %s\n", tmp_hexstr, field_text);
|
||||||
|
|
||||||
|
free(tmp_hexstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the payload part of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void payload_print (const char *packet_buffer, int size) {
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("\nPayload or Trailer:");
|
||||||
|
|
||||||
|
int bytes_per_row = cols / BYTE_MULT;
|
||||||
|
|
||||||
|
int i, j=0;
|
||||||
|
|
||||||
|
// new line
|
||||||
|
while (j < size) {
|
||||||
|
|
||||||
|
// bytes in the line
|
||||||
|
for (i = 0; (i < bytes_per_row) && (j < size); i++, j++) { // columns
|
||||||
|
char str[BYTE_MULT];
|
||||||
|
|
||||||
|
hex_to_str(packet_buffer[j], str);
|
||||||
|
|
||||||
|
printf(" %s", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the TCP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void tcp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nTCP Header:");
|
||||||
|
|
||||||
|
if (size < 8) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 2, &counter, "Source port");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Destination port");
|
||||||
|
field_print(packet_buffer, 4, &counter, "Sequence number");
|
||||||
|
field_print(packet_buffer, 4, &counter, "Acknowledgement number");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Header length");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Flags");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Window");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Checksum");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Urgent pointer");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the UDP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void udp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nUDP Header:");
|
||||||
|
|
||||||
|
if (size < 8) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 2, &counter, "Source port");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Destination port");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Length");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Checksum");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the ICMP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void icmp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nICMP Header:");
|
||||||
|
|
||||||
|
if (size < 8) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 1, &counter, "Type");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Code");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Checksum");
|
||||||
|
field_print(packet_buffer, 2, &counter, "ID");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Sequence number");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the IGMP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void igmp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nIGMP Header:");
|
||||||
|
|
||||||
|
if (size < 8) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 1, &counter, "Type");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Max response time");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Checksum");
|
||||||
|
field_print(packet_buffer, 4, &counter, "Group address");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the IP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void ip_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nIP Header:");
|
||||||
|
|
||||||
|
if (size < 20) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 1, &counter, "Version / Header length");
|
||||||
|
field_print(packet_buffer, 1, &counter, "ToS / DFS");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Total length");
|
||||||
|
field_print(packet_buffer, 2, &counter, "ID");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Flags / Fragment offset");
|
||||||
|
field_print(packet_buffer, 1, &counter, "TTL");
|
||||||
|
|
||||||
|
int next_protocol = protocol_8bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 1, &counter, "Protocol");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 2, &counter, "Checksum");
|
||||||
|
field_print(packet_buffer, 4, &counter, "Source address");
|
||||||
|
field_print(packet_buffer, 4, &counter, "Destination address");
|
||||||
|
|
||||||
|
// go up to the next layer
|
||||||
|
layer_4_dispatcher(packet_buffer + counter, size - counter, next_protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the ARP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void arp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nARP Header:");
|
||||||
|
|
||||||
|
if (size < 28) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 2, &counter, "Hardware type");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Protocol type");
|
||||||
|
|
||||||
|
int hs = *(packet_buffer + counter);
|
||||||
|
field_print(packet_buffer, 1, &counter, "Hardware size");
|
||||||
|
|
||||||
|
int ps = *(packet_buffer + counter);
|
||||||
|
field_print(packet_buffer, 1, &counter, "Protocol size");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 2, &counter, "Opcode");
|
||||||
|
|
||||||
|
field_print(packet_buffer, hs, &counter, "Sender hardware address");
|
||||||
|
field_print(packet_buffer, ps, &counter, "Sender protocol address");
|
||||||
|
field_print(packet_buffer, hs, &counter, "Target hardware address");
|
||||||
|
field_print(packet_buffer, ps, &counter, "Target protocol address");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the ETHERNET header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void ethernet_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nEthernet Header:");
|
||||||
|
|
||||||
|
if (size < 14) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
uint64_t dst_mac = protocol_48bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 6, &counter, "Destination hardware address");
|
||||||
|
field_print(packet_buffer, 6, &counter, "Source hardware address");
|
||||||
|
|
||||||
|
int next_protocol = protocol_16bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 2, &counter, "Lenght/Type");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the last field value is less or equal to 1500 is a lenght
|
||||||
|
* otherwise is a protocol type (check IEEE 802.3 documentation...)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (next_protocol > 1500) {
|
||||||
|
|
||||||
|
// go up to the next layer
|
||||||
|
layer_3_dispatcher(packet_buffer + counter, size - counter, next_protocol);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// remain on the same layer
|
||||||
|
layer_2_dispatcher(packet_buffer + counter, size - counter, dst_mac);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the ISL header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void isl_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nISL Header:");
|
||||||
|
|
||||||
|
if (size < 30) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 5, &counter, "Destination");
|
||||||
|
|
||||||
|
|
||||||
|
int next_protocol = protocol_8bit_extract(packet_buffer, counter);
|
||||||
|
next_protocol >>= 4;
|
||||||
|
|
||||||
|
field_print(packet_buffer, 1, &counter, "Type/User");
|
||||||
|
field_print(packet_buffer, 6, &counter, "Source");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Length");
|
||||||
|
field_print(packet_buffer, 1, &counter, "DSAP");
|
||||||
|
field_print(packet_buffer, 1, &counter, "SSAP");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Control");
|
||||||
|
field_print(packet_buffer, 3, &counter, "HSA");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Vlan ID/BPDU");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Index");
|
||||||
|
field_print(packet_buffer, 2, &counter, "RES");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: we subtrack 4 to the size of the packet to exclude
|
||||||
|
* the final frame check sequence
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (next_protocol == 0) {
|
||||||
|
|
||||||
|
// go up to the next layer
|
||||||
|
ethernet_print(packet_buffer + counter, size - counter - 4);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// go up to the next layer
|
||||||
|
payload_print(packet_buffer + counter, size - counter - 4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
counter = size - 4;
|
||||||
|
|
||||||
|
puts("\nISL Header (end):");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 4, &counter, "Frame check seq.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the DTP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void dtp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nDinamic Trunking Protocol Header:");
|
||||||
|
|
||||||
|
if (size < 29) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 1, &counter, "Version");
|
||||||
|
field_print(packet_buffer, 8, &counter, "Domain");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 5, &counter, "Status");
|
||||||
|
field_print(packet_buffer, 5, &counter, "DTP Type");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 8, &counter, "Neighbor");
|
||||||
|
field_print(packet_buffer, 2, &counter, ""); // splitted since too long...
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the STP header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void stp_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nSpanning Tree Protocol Header:");
|
||||||
|
|
||||||
|
if (size < 38) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
field_print(packet_buffer, 2, &counter, "Protocol Identifier");
|
||||||
|
field_print(packet_buffer, 1, &counter, "Protocol Version Identifier");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 1, &counter, "BPDU Type");
|
||||||
|
field_print(packet_buffer, 1, &counter, "BPDU Flags");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 2, &counter, "Root Priority/System ID Extension");
|
||||||
|
field_print(packet_buffer, 6, &counter, "Root System ID");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 4, &counter, "Root Path Cost");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 2, &counter, "Bridge Priority/System ID Extension");
|
||||||
|
field_print(packet_buffer, 6, &counter, "Bridge System ID");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 2, &counter, "Port Identifier");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Message Age");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Max Age");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Hello Time");
|
||||||
|
field_print(packet_buffer, 2, &counter, "Forward Delay");
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the LLC header of the packet
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at the part to process
|
||||||
|
* @param size packet_buffer size
|
||||||
|
*/
|
||||||
|
void llc_print (const char *packet_buffer, int size) {
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
puts("\nLogical-Link Control Header:");
|
||||||
|
|
||||||
|
if (size < 3) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print header fields
|
||||||
|
int dsap = protocol_8bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 1, &counter, "DSAP");
|
||||||
|
|
||||||
|
int ssap = protocol_8bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 1, &counter, "SSAP");
|
||||||
|
|
||||||
|
field_print(packet_buffer, 1, &counter, "Control field");
|
||||||
|
|
||||||
|
if (dsap == 0x42 && ssap == 0x42) {
|
||||||
|
|
||||||
|
// spanning tree protocol
|
||||||
|
stp_print(packet_buffer + counter, size - counter);
|
||||||
|
|
||||||
|
} else if (dsap == 0xaa && ssap == 0xaa) {
|
||||||
|
|
||||||
|
if (size < 8) {
|
||||||
|
puts (" invalid header size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// continue printing LLC fields
|
||||||
|
field_print(packet_buffer, 3, &counter, "Organization code");
|
||||||
|
|
||||||
|
int pid = protocol_16bit_extract(packet_buffer, counter);
|
||||||
|
field_print(packet_buffer, 2, &counter, "PID");
|
||||||
|
|
||||||
|
if (pid == 0x2004) {
|
||||||
|
|
||||||
|
// dinamic trunking protocol
|
||||||
|
dtp_print(packet_buffer + counter, size - counter);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// print remaining payload
|
||||||
|
payload_print(packet_buffer + counter, size - counter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the packet type and call the appropriate function to disassemble it.
|
||||||
|
* Operates on layer 2 (OSI model) packet's headers.
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at layer 2
|
||||||
|
* @param size packet_buffer size
|
||||||
|
* @param protocol protocol number
|
||||||
|
*/
|
||||||
|
void layer_2_dispatcher (const char *packet_buffer, int size, uint64_t protocol) {
|
||||||
|
|
||||||
|
uint64_t llc1 = 0x0180C20000LLU, llc2 = 0x01000CCCCCCCLLU;
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(packet_buffer, "\x01\x00\x0C\x00\x00", 5)==0 ||
|
||||||
|
memcmp(packet_buffer, "\x03\x00\x0c\x00\x00", 5)==0 ) {
|
||||||
|
|
||||||
|
isl_print(packet_buffer, size);
|
||||||
|
|
||||||
|
} else if ((protocol / 256) == llc1) {
|
||||||
|
|
||||||
|
llc_print(packet_buffer, size); // spanning tree
|
||||||
|
|
||||||
|
} else if (protocol == llc2) {
|
||||||
|
|
||||||
|
llc_print(packet_buffer, size);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ethernet_print(packet_buffer, size);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the packet type and call the appropriate function to disassemble it.
|
||||||
|
* Operates on layer 3 (OSI model) packet's headers.
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at layer 3
|
||||||
|
* @param size packet_buffer size
|
||||||
|
* @param protocol protocol number
|
||||||
|
*/
|
||||||
|
void layer_3_dispatcher (const char *packet_buffer, int size, uint64_t protocol) {
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the last field value (of an ethernet header) is less or equal to 1500
|
||||||
|
* then is a lenght otherwise is a protocol type (check IEEE 802.3 documentation...)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (protocol <= 0xffff) { // check if it's a 16bit field
|
||||||
|
// (i.e. last ethernet field was a protocol)
|
||||||
|
switch (protocol) {
|
||||||
|
|
||||||
|
case 0x0800: ip_print(packet_buffer, size); break;
|
||||||
|
case 0x0806: arp_print(packet_buffer, size); break;
|
||||||
|
|
||||||
|
default: payload_print(packet_buffer, size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
payload_print(packet_buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the packet type and call the appropriate function to disassemble it.
|
||||||
|
* Operates on layer 4 (OSI model) packet's headers.
|
||||||
|
*
|
||||||
|
* @param packet_buffer raw packet captured from the network, starting at layer 4
|
||||||
|
* @param size packet_buffer size
|
||||||
|
* @param protocol protocol number
|
||||||
|
*/
|
||||||
|
void layer_4_dispatcher (const char *packet_buffer, int size, uint64_t protocol) {
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (protocol) {
|
||||||
|
case 1: icmp_print(packet_buffer, size); break;
|
||||||
|
case 2: igmp_print(packet_buffer, size); break;
|
||||||
|
case 6: tcp_print(packet_buffer, size); break;
|
||||||
|
case 17: udp_print(packet_buffer, size); break;
|
||||||
|
default: payload_print(packet_buffer, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/07 18:02:55 by jhalford #+# #+# */
|
/* Created: 2017/10/07 18:02:55 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 10:48:18 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 17:30:41 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ int reserve_port(int s, struct sockaddr *sa)
|
||||||
i = 49152;
|
i = 49152;
|
||||||
while (i < 65535)
|
while (i < 65535)
|
||||||
{
|
{
|
||||||
sa->sin_port = htons(i);
|
((struct sockaddr_in*)sa)->sin_port = htons(i);
|
||||||
if (bind(s, sa, sizeof(sa)) == 0)
|
if (bind(s, sa, sizeof(sa)) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
++i;
|
++i;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/07 18:02:34 by jhalford #+# #+# */
|
/* Created: 2017/10/07 18:02:34 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/08 15:54:16 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 20:24:09 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/07 17:56:14 by jhalford #+# #+# */
|
/* Created: 2017/10/07 17:56:14 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/07 17:56:40 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 14:33:28 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
|
||||||
202
nmap/libft/srcs/str/hexstring.c
Normal file
202
nmap/libft/srcs/str/hexstring.c
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* hexstring.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/24 21:42:59 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:47:58 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "hexstring.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte multiplier: a printed byte uses 3 characters
|
||||||
|
*/
|
||||||
|
#define BYTE_MULT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a 2-bytes string to an uint8_t integer (e.g. "1A\0" -> 0x1A)
|
||||||
|
*
|
||||||
|
* @param str hexstring to convert, of expected size BYTE_MULT
|
||||||
|
* @return converted uint8_t integer
|
||||||
|
*/
|
||||||
|
uint8_t str_to_hex(char *str) {
|
||||||
|
|
||||||
|
assert(str != NULL);
|
||||||
|
|
||||||
|
uint8_t hex = 0;
|
||||||
|
|
||||||
|
if(isdigit(str[0])) {
|
||||||
|
hex |= (str[0] & 0x0F) << 4;
|
||||||
|
} else {
|
||||||
|
hex |= ((str[0]+0x09) & 0x0F) << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isdigit(str[1])) {
|
||||||
|
hex |= (str[1] & 0x0F);
|
||||||
|
} else {
|
||||||
|
hex |= ((str[1]+0x09) & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an uint8_t integer to a 2-bytes hexstring (e.g. 0x1A -> "1A\0")
|
||||||
|
*
|
||||||
|
* @param hex uint8_t integer to convert
|
||||||
|
* @param str destination hexstring, of expected size BYTE_MULT
|
||||||
|
*/
|
||||||
|
void hex_to_str(uint8_t hex, char *str) {
|
||||||
|
|
||||||
|
assert(str != NULL);
|
||||||
|
|
||||||
|
str[0] = (hex & 0xF0) >> 4;
|
||||||
|
str[1] = (hex & 0x0F);
|
||||||
|
str[2] = '\0';
|
||||||
|
|
||||||
|
if(str[0]<0x0A) {
|
||||||
|
str[0] |= 0x30;
|
||||||
|
} else {
|
||||||
|
str[0] |= 0x40;
|
||||||
|
str[0] -= 0x09;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(str[1]<0x0A) {
|
||||||
|
str[1] |= 0x30;
|
||||||
|
} else {
|
||||||
|
str[1] |= 0x40;
|
||||||
|
str[1] -= 0x09;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the character is hexadecimal.
|
||||||
|
*
|
||||||
|
* @param c character to check
|
||||||
|
* @return
|
||||||
|
* - 1 if hexadecimal
|
||||||
|
* - 0 if not hexadecimal
|
||||||
|
*/
|
||||||
|
int is_hex(char c) {
|
||||||
|
if ((c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of the hexstring.
|
||||||
|
*
|
||||||
|
* @param hexstr input string
|
||||||
|
* @return hexstr length
|
||||||
|
*/
|
||||||
|
int hexstr_size(const char *hexstr) {
|
||||||
|
|
||||||
|
assert(hexstr != NULL);
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
const char *p = hexstr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse an hexstring and calculate it's size.
|
||||||
|
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
|
||||||
|
* (Ex. "FF ", "2A ", "EE")
|
||||||
|
*/
|
||||||
|
while ( is_hex(p[0]) && is_hex(p[1]) && (p[2] == ' ' || p[2] == '\n' || p[2] == '\0') ) {
|
||||||
|
//printf("p[0] = %c, p[1] = %c, p[2] = %c\n", p[0], p[1], p[2] == '\0' ? 'N' : p[2]);
|
||||||
|
|
||||||
|
size++;
|
||||||
|
p += BYTE_MULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a raw buffer from an hexstring. The buffer must be manually free()d.
|
||||||
|
*
|
||||||
|
* @param hexstr hexstring to convert
|
||||||
|
* @param size hexstring size
|
||||||
|
* @return pointer to the converted raw buffer
|
||||||
|
*/
|
||||||
|
char *hexstr_to_raw(const char *hexstr, int *size) {
|
||||||
|
|
||||||
|
assert(hexstr != NULL);
|
||||||
|
assert(size != NULL);
|
||||||
|
|
||||||
|
char *raw = NULL;
|
||||||
|
const char *p = hexstr;
|
||||||
|
|
||||||
|
*size = hexstr_size(hexstr);
|
||||||
|
raw = (char *) malloc(*size); // malloc the raw buffer
|
||||||
|
|
||||||
|
char hex[BYTE_MULT];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse an hexstring.
|
||||||
|
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
|
||||||
|
* (Ex. "FF ", "2A ", "EE")
|
||||||
|
*/
|
||||||
|
while ( is_hex(p[0]) && is_hex(p[1]) && (p[2] == ' ' || p[2] == '\n' || p[2] == '\0') ) {
|
||||||
|
//printf("p[0] = %c, p[1] = %c, p[2] = %c\n", p[0], p[1], p[2] == '\0' ? 'N' : p[2]);
|
||||||
|
|
||||||
|
// extract a single byte
|
||||||
|
hex[0] = p[0];
|
||||||
|
hex[1] = p[1];
|
||||||
|
hex[2] = '\0';
|
||||||
|
|
||||||
|
raw[i] = str_to_hex(hex);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
p += BYTE_MULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//hex_dump(raw, size);
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an hexstring from a raw buffer. The hexstring must be manually free()d.
|
||||||
|
*
|
||||||
|
* @param raw raw buffer to convert
|
||||||
|
* @param size raw buffer size
|
||||||
|
* @return converted hexstring
|
||||||
|
*/
|
||||||
|
char *raw_to_hexstr(const char *raw, int size) {
|
||||||
|
|
||||||
|
assert(raw != NULL);
|
||||||
|
if(size == 0) return NULL;
|
||||||
|
|
||||||
|
char *hexstr = NULL;
|
||||||
|
|
||||||
|
hexstr = (char *) malloc(size*BYTE_MULT); // malloc the hexstring
|
||||||
|
|
||||||
|
char hex[BYTE_MULT];
|
||||||
|
int i = 0;
|
||||||
|
char *p = hexstr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse an hexstring.
|
||||||
|
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
|
||||||
|
* (Ex. "FF ", "2A ", "EE")
|
||||||
|
*/
|
||||||
|
for (i=0; i<size; i++, p+=BYTE_MULT) {
|
||||||
|
|
||||||
|
// extract a single byte
|
||||||
|
hex_to_str(raw[i], hex);
|
||||||
|
|
||||||
|
p[0] = hex[0];
|
||||||
|
p[1] = hex[1];
|
||||||
|
p[2] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hexstr[(size*BYTE_MULT)-1] = '\0';
|
||||||
|
return hexstr;
|
||||||
|
}
|
||||||
|
|
||||||
42
nmap/srcs/format.c
Normal file
42
nmap/srcs/format.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* format.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/24 15:07:14 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:48:03 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "nmap.h"
|
||||||
|
|
||||||
|
int g_njobs;
|
||||||
|
char g_port_status[][20] =
|
||||||
|
{
|
||||||
|
"OPEN",
|
||||||
|
"FILTERED",
|
||||||
|
"CLOSED",
|
||||||
|
"UNFILTERED",
|
||||||
|
"OPEN_FILTERED",
|
||||||
|
};
|
||||||
|
|
||||||
|
void nmap_format(chan results)
|
||||||
|
{
|
||||||
|
t_result result;
|
||||||
|
char buf[IPADDR_MAXSTRLEN];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i++ < g_njobs)
|
||||||
|
{
|
||||||
|
result = chr(results, t_result);
|
||||||
|
printf("%s:%i %s(%s)\n",
|
||||||
|
ipaddrstr(result.dest, buf),
|
||||||
|
ipport(result.dest),
|
||||||
|
g_port_status[result.status],
|
||||||
|
result.scan);
|
||||||
|
}
|
||||||
|
printf("finished reading %i jobs\n", g_njobs);
|
||||||
|
}
|
||||||
52
nmap/srcs/ip.c
Normal file
52
nmap/srcs/ip.c
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* ip.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/24 17:22:16 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:36:52 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "nmap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** some libmill ip extensions
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t ipport(ipaddr ip)
|
||||||
|
{
|
||||||
|
return (ntohs(((struct sockaddr_in*)&ip)->sin_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ipfamily(ipaddr ip)
|
||||||
|
{
|
||||||
|
return (((struct sockaddr*)&ip)->sa_family);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ipmode(ipaddr ip)
|
||||||
|
{
|
||||||
|
if (((struct sockaddr*)&ip)->sa_family == AF_INET)
|
||||||
|
return (IPADDR_IPV4);
|
||||||
|
else
|
||||||
|
return (IPADDR_IPV6);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipaddr iplocal_randport(const char *name, int mode, int sock)
|
||||||
|
{
|
||||||
|
unsigned short port;
|
||||||
|
ipaddr ip;
|
||||||
|
|
||||||
|
port = 49152;
|
||||||
|
while (port < 65535)
|
||||||
|
{
|
||||||
|
ip = iplocal(name, port, mode);
|
||||||
|
if (bind(sock, (struct sockaddr*)&ip, sizeof(ip)) == 0)
|
||||||
|
return (ip);
|
||||||
|
++port;
|
||||||
|
}
|
||||||
|
errno = EBUSY;
|
||||||
|
return (ip);
|
||||||
|
}
|
||||||
|
|
@ -1,33 +1,54 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* listener.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/10/23 19:16:39 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/10/24 21:28:44 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "nmap.h"
|
#include "nmap.h"
|
||||||
|
|
||||||
static pcap_t *pcap_obj = NULL;
|
#define PCAP_FILTER\
|
||||||
|
"src host %s and src port %i and dst host %s and dst port %i"
|
||||||
|
|
||||||
static void packet_callback(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
|
static void packet_callback(u_char *arg, const struct pcap_pkthdr *pkthdr,
|
||||||
|
const u_char *packet)
|
||||||
|
|
||||||
{
|
{
|
||||||
(void)pkthdr;
|
(void)pkthdr;
|
||||||
(void)packet;
|
(void)packet;
|
||||||
t_data *data = (t_data*)arg;
|
chan ch = (chan)arg;
|
||||||
ft_printf("received packet !!!\n");
|
ft_printf("received packet !!!\n");
|
||||||
hexdump(&packet, sizeof(packet));
|
prettypacket((void*)packet, pkthdr->len);
|
||||||
host = extract_host(pkt);
|
(void)ch;
|
||||||
dport = extract_dport(pkt);
|
/* chs(ch, struct tcphdr, *(t_tcp_packet*)packet); */
|
||||||
sport = extract_sport(pkt);
|
|
||||||
|
|
||||||
chan = get_chan(host, dport, sport);
|
|
||||||
chsend(ch, &pkt, sizeof(pkt), -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
coroutine void nmap_listener(t_data *data)
|
coroutine void listener_loop(chan ch, pcap_t *pcap_obj)
|
||||||
{
|
{
|
||||||
t_data *data;
|
ft_printf("listener loop\n");
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
if (pcap_loop(pcap_obj, -1, packet_callback, (u_char*)ch) == -1)
|
||||||
bpf_u_int32 netp;
|
{
|
||||||
bpf_u_int32 maskp;
|
ft_printf("pcap_loop fail\n");
|
||||||
struct bpf_program fp;
|
exit(EXIT_FAILURE);
|
||||||
char *str;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data = (t_data*)arg;
|
chan nmap_listener(ipaddr dst, ipaddr src)
|
||||||
|
{
|
||||||
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
pcap_t *pcap_obj;
|
||||||
|
bpf_u_int32 netp;
|
||||||
|
bpf_u_int32 maskp;
|
||||||
|
struct bpf_program fp;
|
||||||
|
char str[100];
|
||||||
|
chan pkts;
|
||||||
|
|
||||||
|
pkts = chmake(struct tcphdr, 10);
|
||||||
if (pcap_lookupnet("any", &netp, &maskp, errbuf) == -1)
|
if (pcap_lookupnet("any", &netp, &maskp, errbuf) == -1)
|
||||||
{
|
{
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
@ -37,24 +58,13 @@ coroutine void nmap_listener(t_data *data)
|
||||||
fprintf(stderr, "pcap_open_live: %s", errbuf);
|
fprintf(stderr, "pcap_open_live: %s", errbuf);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (!(str = ft_str3join("host ", ((t_host*)data->host->content)->ip, " and (tcp or icmp)")))
|
if (!(sprintf(str, PCAP_FILTER, ipaddrstr(dst, str), ipport(dst),
|
||||||
{
|
ipaddrstr(src, str), ipport(src))))
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
|
||||||
if (pcap_compile(pcap_obj, &fp, str, 1, netp) == -1)
|
if (pcap_compile(pcap_obj, &fp, str, 1, netp) == -1)
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
|
||||||
if (pcap_setfilter(pcap_obj, &fp) == -1)
|
if (pcap_setfilter(pcap_obj, &fp) == -1)
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
go(listener_loop(pkts, pcap_obj));
|
||||||
/* signal(SIGALRM, sigalrm_handler); */
|
return (chdup(pkts));
|
||||||
ft_printf("listener loop\n");
|
|
||||||
if (pcap_loop(pcap_obj, -1, packet_callback, (u_char*)data) == -1)
|
|
||||||
{
|
|
||||||
ft_printf("pcap_loop fail\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
free(str);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/08 19:10:04 by jhalford #+# #+# */
|
/* Created: 2017/10/08 19:10:04 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 15:58:02 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 20:08:00 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -15,52 +15,53 @@
|
||||||
#define NMAP_USAGE1 " [--ip HOST] [--file FILE]"
|
#define NMAP_USAGE1 " [--ip HOST] [--file FILE]"
|
||||||
#define NMAP_USAGE2 " [--ports PORTS] [--speedup [NUMBER]] [--scan [TYPE]] HOST"
|
#define NMAP_USAGE2 " [--ports PORTS] [--speedup [NUMBER]] [--scan [TYPE]] HOST"
|
||||||
|
|
||||||
/*
|
t_data *g_data;
|
||||||
** only IPv4
|
|
||||||
** only default network if
|
coroutine void jobs_loop(chan jobs, chan results)
|
||||||
** one per port per scan type
|
|
||||||
*/
|
|
||||||
int fill_ports(t_data *data)
|
|
||||||
{
|
{
|
||||||
|
t_job job;
|
||||||
|
chan copy;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = -1;
|
i = 0;
|
||||||
while (++i < SCAN_MAX)
|
while (true)
|
||||||
{
|
{
|
||||||
if ((data->sock[i] = socket(AF_INET, SOCK_RAW, 0)) < 0)
|
job = chr(jobs, t_job);
|
||||||
{
|
if (job.scan == NULL)
|
||||||
perror("socket");
|
break ;
|
||||||
exit(1);
|
copy = chdup(results);
|
||||||
}
|
go(job.scan(copy, job));
|
||||||
/* if (setsockopt(data->sock[i], IPPROTO_IP, IP_HDRINCL, (int[]){1}, sizeof(val)) == -1) */
|
i++;
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
printf("finished starting jobs\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
static chan nmap(chan jobs)
|
||||||
{
|
{
|
||||||
t_data data;
|
chan results;
|
||||||
|
|
||||||
if (getuid() != 0)
|
results = chmake(t_result, 0);
|
||||||
{
|
go(jobs_loop(jobs, results));
|
||||||
fprintf(stderr, "You must have root privileges to use nmap!\n");
|
return (results);
|
||||||
return(1);
|
}
|
||||||
}
|
|
||||||
if (nmap_parse(ac, av, &data))
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
chan jobs;
|
||||||
|
chan results;
|
||||||
|
|
||||||
|
/* if (getuid() != 0) */
|
||||||
|
/* { */
|
||||||
|
/* fprintf(stderr, "You must have root privileges to use nmap!\n"); */
|
||||||
|
/* return(1); */
|
||||||
|
/* } */
|
||||||
|
if ((jobs = nmap_parse(ac, av)) < 0)
|
||||||
{
|
{
|
||||||
printf("usage: nmap --help\n");
|
printf("usage: nmap --help\n");
|
||||||
printf("or nmap"NMAP_USAGE1 NMAP_USAGE2"\n");
|
printf("or nmap"NMAP_USAGE1 NMAP_USAGE2"\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fill_ports(&data);
|
results = nmap(jobs);
|
||||||
go(nmap_listener(&data));
|
nmap_format(results);
|
||||||
int chan = nmap(&data);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
116
nmap/srcs/nmap.c
116
nmap/srcs/nmap.c
|
|
@ -1,116 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* nmap.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2017/10/08 19:10:07 by jhalford #+# #+# */
|
|
||||||
/* Updated: 2017/10/09 17:12:31 by jhalford ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "nmap.h"
|
|
||||||
|
|
||||||
t_scanner g_scanners[SCAN_MAX]
|
|
||||||
{
|
|
||||||
scan_tcp,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
/* scan_syn, */
|
|
||||||
/* scan_ack, */
|
|
||||||
/* scan_fin, */
|
|
||||||
/* scan_xmas, */
|
|
||||||
/* scan_udp, */
|
|
||||||
}
|
|
||||||
|
|
||||||
coroutine void nmap_scan_port(int ch, t_data *data, t_target target)
|
|
||||||
{
|
|
||||||
int fan_in;
|
|
||||||
int fan_in_local;
|
|
||||||
int scan;
|
|
||||||
|
|
||||||
fan_in = chmake(sizeof(t_scan_result));
|
|
||||||
while (scan = bitfield_lsb(data.scans, USHRT_MAX + 1))
|
|
||||||
{
|
|
||||||
data.scans &= ~scan;
|
|
||||||
fan_in_local = hdup(fan_in);
|
|
||||||
scanner = g_scanners[scan];
|
|
||||||
go(scanner(fan_in_local, sock, target));
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
int nhost;
|
|
||||||
int fan_in_local;
|
|
||||||
struct chclause clause[ft_lstsize(data->host)];
|
|
||||||
int buf;
|
|
||||||
|
|
||||||
nhost = 0;
|
|
||||||
for (t_list *list = data->host; list != NULL; list = list->next)
|
|
||||||
{
|
|
||||||
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,62 +6,62 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/08 19:10:05 by jhalford #+# #+# */
|
/* Created: 2017/10/08 19:10:05 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 14:51:21 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:00:10 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "nmap.h"
|
#include "nmap.h"
|
||||||
|
|
||||||
static t_cliopts g_opts[] =
|
extern int g_njobs;
|
||||||
{
|
|
||||||
{'h', "host", 0, 0, nmap_get_host, 0},
|
|
||||||
/* {'f', "file", 0, 0, nmap_get_file, 0}, */
|
|
||||||
/* {'p', "ports", 0, 0, nmap_get_ports, 0}, */
|
|
||||||
{'t', "threads", 0, 0, nmap_get_threads, 0},
|
|
||||||
{'s', "scan", 0, 0, nmap_get_scan, 0},
|
|
||||||
{0, 0, 0, 0, 0, 0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int nmap_get_host(char *node, t_data *data)
|
/* static t_cliopts g_opts[] = */
|
||||||
{
|
/* { */
|
||||||
t_host host;
|
/* {'h', "host", 0, 0, nmap_get_host, 0}, */
|
||||||
struct addrinfo *servinfo, hints;
|
/* /1* {'f', "file", 0, 0, nmap_get_file, 0}, *1/ */
|
||||||
|
/* /1* {'p', "ports", 0, 0, nmap_get_ports, 0}, *1/ */
|
||||||
|
/* {'t', "threads", 0, 0, nmap_get_threads, 0}, */
|
||||||
|
/* {'s', "scan", 0, 0, nmap_get_scan, 0}, */
|
||||||
|
/* {0, 0, 0, 0, 0, 0}, */
|
||||||
|
/* }; */
|
||||||
|
|
||||||
memset (&hints, 0, sizeof (hints));
|
/* static t_host nmap_get_host(char *node) */
|
||||||
hints.ai_family = PF_UNSPEC;
|
/* { */
|
||||||
hints.ai_socktype = SOCK_RAW;
|
/* t_host host; */
|
||||||
hints.ai_flags = AI_CANONNAME;
|
/* struct addrinfo *servinfo, hints; */
|
||||||
|
|
||||||
if (getaddrinfo(node, NULL, &hints, &servinfo))
|
/* memset (&hints, 0, sizeof (hints)); */
|
||||||
{
|
/* hints.ai_family = PF_UNSPEC; */
|
||||||
fprintf(stderr, "Failed to resolve \"%s\"\n", node);
|
/* hints.ai_socktype = SOCK_RAW; */
|
||||||
return (1);
|
/* hints.ai_flags = AI_CANONNAME; */
|
||||||
}
|
|
||||||
host.addr = servinfo->ai_addr;
|
|
||||||
host.addrlen = servinfo->ai_addrlen;
|
|
||||||
host.host = node;
|
|
||||||
host.dn = servinfo->ai_canonname;
|
|
||||||
|
|
||||||
void *addr;
|
/* if (getaddrinfo(node, NULL, &hints, &servinfo)) */
|
||||||
if (servinfo->ai_family == AF_INET) { // IPv4
|
/* { */
|
||||||
struct sockaddr_in *ipv4 = (struct sockaddr_in *)servinfo->ai_addr;
|
/* fprintf(stderr, "Failed to resolve \"%s\"\n", node); */
|
||||||
addr = &(ipv4->sin_addr);
|
/* return (host); */
|
||||||
} else { // IPv6
|
/* } */
|
||||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr;
|
/* host.addr = servinfo->ai_addr; */
|
||||||
addr = &(ipv6->sin6_addr);
|
/* host.addrlen = servinfo->ai_addrlen; */
|
||||||
}
|
/* host.host = node; */
|
||||||
|
/* host.dn = servinfo->ai_canonname; */
|
||||||
|
|
||||||
// convert the IP to a string and print it:
|
/* void *addr; */
|
||||||
inet_ntop(servinfo->ai_family, addr, host.ip, sizeof(host.ip));
|
/* if (servinfo->ai_family == AF_INET) { // IPv4 */
|
||||||
|
/* struct sockaddr_in *ipv4 = (struct sockaddr_in *)servinfo->ai_addr; */
|
||||||
|
/* addr = &(ipv4->sin_addr); */
|
||||||
|
/* } else { // IPv6 */
|
||||||
|
/* struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr; */
|
||||||
|
/* addr = &(ipv6->sin6_addr); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
printf("dn=%s, ip=%s\n", host.dn, host.ip);
|
/* // convert the IP to a string and print it: */
|
||||||
|
/* inet_ntop(servinfo->ai_family, addr, host.ip, sizeof(host.ip)); */
|
||||||
|
|
||||||
/* MUST DO rDNS search here */
|
/* printf("dn=%s, ip=%s\n", host.dn, host.ip); */
|
||||||
/* printf("rDNS record for %s: %s\n", addrstr, DOMAIN NAME WITH RDNS); */
|
|
||||||
|
|
||||||
ft_lsteadd(&data->host, ft_lstnew(&host, sizeof(host)));
|
/* /1* MUST DO rDNS search here *1/ */
|
||||||
return (0);
|
/* /1* printf("rDNS record for %s: %s\n", addrstr, DOMAIN NAME WITH RDNS); *1/ */
|
||||||
}
|
/* return (host); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
/* int nmap_get_file(char *opt_arg, t_data *data) */
|
/* int nmap_get_file(char *opt_arg, t_data *data) */
|
||||||
/* { */
|
/* { */
|
||||||
|
|
@ -71,65 +71,64 @@ static int nmap_get_host(char *node, t_data *data)
|
||||||
/* { */
|
/* { */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
static int nmap_get_threads(char *opt_arg, t_data *data)
|
/* static int nmap_get_threads(char *opt_arg, t_data *data) */
|
||||||
|
/* { */
|
||||||
|
/* data->threads = ft_atoi(opt_arg); */
|
||||||
|
/* return (0); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
/* static int nmap_get_scan(char *opt_arg, t_data *data) */
|
||||||
|
/* { */
|
||||||
|
/* while (*opt_arg) */
|
||||||
|
/* { */
|
||||||
|
/* if (*opt_arg == 'T') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_TCP); */
|
||||||
|
/* else if (*opt_arg == 'S') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_SYN); */
|
||||||
|
/* else if (*opt_arg == 'A') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_ACK); */
|
||||||
|
/* else if (*opt_arg == 'F') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_FIN); */
|
||||||
|
/* else if (*opt_arg == 'X') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_XMAS); */
|
||||||
|
/* else if (*opt_arg == 'U') */
|
||||||
|
/* bitfield_biton(data->scans, SCAN_UDP); */
|
||||||
|
/* else */
|
||||||
|
/* return (1); */
|
||||||
|
/* opt_arg++; */
|
||||||
|
/* } */
|
||||||
|
/* return (0); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
coroutine void coarse_dispatcher(chan jobs)
|
||||||
{
|
{
|
||||||
data->threads = ft_atoi(opt_arg);
|
t_job job;
|
||||||
return (0);
|
|
||||||
|
job.scan = nmap_scan_tcp;
|
||||||
|
|
||||||
|
job.dest = ipremote("scanme.nmap.org", 80, IPADDR_IPV4, -1);
|
||||||
|
chs(jobs, t_job, job);
|
||||||
|
job.dest = ipremote("scanme.nmap.org", 81, IPADDR_IPV4, -1);
|
||||||
|
chs(jobs, t_job, job);
|
||||||
|
|
||||||
|
job.scan = 0;
|
||||||
|
chdone(jobs, t_job, job);
|
||||||
|
chclose(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nmap_get_scan(char *opt_arg, t_data *data)
|
chan nmap_parse(int ac, char **av)
|
||||||
{
|
{
|
||||||
while (*opt_arg)
|
|
||||||
{
|
|
||||||
if (*opt_arg == 'T')
|
|
||||||
bitfield_biton(data->scans, SCAN_TCP);
|
|
||||||
else if (*opt_arg == 'S')
|
|
||||||
bitfield_biton(data->scans, SCAN_SYN);
|
|
||||||
else if (*opt_arg == 'A')
|
|
||||||
bitfield_biton(data->scans, SCAN_ACK);
|
|
||||||
else if (*opt_arg == 'F')
|
|
||||||
bitfield_biton(data->scans, SCAN_FIN);
|
|
||||||
else if (*opt_arg == 'X')
|
|
||||||
bitfield_biton(data->scans, SCAN_XMAS);
|
|
||||||
else if (*opt_arg == 'U')
|
|
||||||
bitfield_biton(data->scans, SCAN_UDP);
|
|
||||||
else
|
|
||||||
return (1);
|
|
||||||
opt_arg++;
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nmap_parse(int ac, char **av, t_data *data)
|
|
||||||
{
|
|
||||||
struct ifaddrs *ifaddrs, *ifa_first;
|
|
||||||
(void)ac;
|
(void)ac;
|
||||||
data->host = NULL;
|
(void)av;
|
||||||
bzero(data->ports, sizeof(data->ports));
|
/* if (cliopts_get(av, g_opts, data)) */
|
||||||
data->threads = 0;
|
/* return (ft_perror("nmap")); */
|
||||||
data->scan = 0;
|
/* if (!data->host && data->av_data && data->av_data) */
|
||||||
|
/* nmap_get_host(*data->av_data, data); */
|
||||||
|
|
||||||
if (cliopts_get(av, g_opts, data))
|
chan jobs;
|
||||||
return (ft_perror("nmap"));
|
jobs = chmake(t_job, 0);
|
||||||
if (!data->host && data->av_data && data->av_data)
|
go(coarse_dispatcher(jobs));
|
||||||
nmap_get_host(*data->av_data, data);
|
g_njobs = 2;
|
||||||
if (!data->scan)
|
|
||||||
data->scan = SCAN_TCP;
|
return (jobs);
|
||||||
getifaddrs(&ifa_first);
|
|
||||||
for (ifaddrs = ifa_first; ifaddrs && ifaddrs->ifa_flags & IFF_LOOPBACK; ifaddrs = ifaddrs->ifa_next)
|
|
||||||
;
|
|
||||||
if (ifaddrs)
|
|
||||||
{
|
|
||||||
ifaddrs=ifaddrs->ifa_next;
|
|
||||||
printf("if=%s\n", ifaddrs->ifa_name);
|
|
||||||
data->source_addr = *ifaddrs->ifa_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "couldn't find an internet interface\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
freeifaddrs(ifa_first);
|
|
||||||
bitfield_biton(data->ports, 80);
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,42 +6,44 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/10/09 15:28:42 by jhalford #+# #+# */
|
/* Created: 2017/10/09 15:28:42 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/10/09 16:14:35 by jhalford ### ########.fr */
|
/* Updated: 2017/10/24 21:48:11 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "nmap.h"
|
#include "nmap.h"
|
||||||
|
|
||||||
coroutine void nmap_scan_tcp(int ch, t_data *data, t_target target)
|
coroutine void nmap_scan_tcp(chan results, t_job job)
|
||||||
{
|
{
|
||||||
int listen;
|
t_result result;
|
||||||
t_scan_result res;
|
chan pkts;
|
||||||
t_tcp_packet pkt;
|
ipaddr src;
|
||||||
|
int sock;
|
||||||
|
|
||||||
listen = capture_chan(target);
|
sock = socket(ipfamily(job.dest), SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
src = iplocal_randport(NULL, ipmode(job.dest), sock);
|
||||||
|
pkts = nmap_listener(job.dest, src);
|
||||||
|
|
||||||
iphdr_init(&pkt.iph);
|
result.dest = job.dest;
|
||||||
|
ft_strcpy(result.scan, "TCP");
|
||||||
|
|
||||||
pkt.iph.protocol = IPPROTO_TCP;
|
struct tcphdr pkt;
|
||||||
pkt.iph.saddr = *(uint32_t*)&((struct sockaddr_in*)&data->out_sa[target.scan])->sin_addr;
|
result.status = CLOSED;
|
||||||
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);
|
tcp_hdrinit(&pkt);
|
||||||
packet.tcph.dest = htons(target.port);
|
pkt.th_dport = htons(ipport(job.dest));
|
||||||
packet.tcph.check = cksum(&packet, sizeof(t_tcp_packet));
|
pkt.th_sport = htons(ipport(src));
|
||||||
|
/* pkt.th_flags = 0; */
|
||||||
|
pkt.th_sum = cksum(&pkt, sizeof(pkt));
|
||||||
|
|
||||||
if (sendto(sock, &packet, sizeof(packet), 0,
|
if (sendto(sock, &pkt, sizeof(pkt), 0,
|
||||||
host->addr, host->addrlen) < 0)
|
(struct sockaddr*)&job.dest, sizeof(job.dest)) < 0)
|
||||||
{
|
{
|
||||||
perror("sendto");
|
perror("sendto");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* chrecv(channel, &buf, sizeof()) */
|
pkt = chr(pkts, struct tcphdr);
|
||||||
hexdump(&packet, sizeof(packet));
|
|
||||||
|
|
||||||
|
chs(results, t_result, result);
|
||||||
chsend(ch, res, sizeof(res), -1);
|
chclose(results);
|
||||||
printf("result sent\n");
|
return ;
|
||||||
hclose(ch);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue