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> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# 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/
|
||||
|
||||
SRC_BASE = \
|
||||
main.c\
|
||||
nmap.c\
|
||||
parser.c\
|
||||
format.c\
|
||||
ip.c\
|
||||
listener.c\
|
||||
main.c\
|
||||
parser.c\
|
||||
scanners.c
|
||||
|
||||
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
||||
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
||||
|
|
@ -52,7 +54,7 @@ $(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(CLIENT_OBJ)
|
|||
-I $(LIBFT_INC) \
|
||||
-L $(HOME)/.bin/lib \
|
||||
$(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"
|
||||
|
||||
$(LIBFT_LIB):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 <netinet/in.h>
|
||||
# include <netinet/ip.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <netinet/ip_icmp.h>
|
||||
# include <netinet/if_ether.h>
|
||||
# include <pcap.h>
|
||||
|
|
@ -30,11 +31,13 @@
|
|||
# include <pthread.h>
|
||||
# include <ifaddrs.h>
|
||||
|
||||
# include "libdill.h"
|
||||
# include "libmill.h"
|
||||
|
||||
typedef struct s_data t_data;
|
||||
typedef struct s_host t_host;
|
||||
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_scan_type t_scan_type;
|
||||
|
||||
|
|
@ -62,14 +65,6 @@ 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
|
||||
|
|
@ -79,27 +74,35 @@ struct s_host
|
|||
char ip[INET6_ADDRSTRLEN]; // humain readable ip address
|
||||
struct sockaddr *addr;
|
||||
size_t addrlen;
|
||||
int chan[USHRT_MAX + 1][SCAN_MAX];
|
||||
};
|
||||
|
||||
struct s_target
|
||||
struct s_job
|
||||
{
|
||||
t_host *host;
|
||||
uint16_t port;
|
||||
t_scan_type scan;
|
||||
#define capture_chan(t) (t.host.chan[t.port][t.scan])
|
||||
ipaddr dest;
|
||||
void (*scan)();
|
||||
};
|
||||
|
||||
struct s_tcp_packet
|
||||
struct s_result
|
||||
{
|
||||
struct iphdr iph;
|
||||
struct tcphdr tcph;
|
||||
}__attribute__((packed));
|
||||
ipaddr dest;
|
||||
char scan[4];
|
||||
t_port_status status;
|
||||
};
|
||||
|
||||
static t_cliopts g_opts[];
|
||||
int nmap_parse(int ac, char **av, t_data *data);
|
||||
extern t_cliopts g_opts[];
|
||||
extern int g_njobs;
|
||||
chan nmap_parse(int ac, char **av);
|
||||
void nmap_format(chan results);
|
||||
|
||||
void nmap(t_data *data);
|
||||
void nmap_listener(void *arg);
|
||||
coroutine void nmap_scan_tcp(chan results, t_job job);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ lst/lst_insert_sort.c\
|
|||
lst/pop.c\
|
||||
lst/push.c\
|
||||
lst/top.c\
|
||||
math/bitfield.c\
|
||||
math/ft_addrcmp.c\
|
||||
math/ft_ilen.c\
|
||||
math/ft_ilen_base.c\
|
||||
|
|
@ -138,6 +139,7 @@ net/host.c\
|
|||
net/ip.c\
|
||||
net/net_get.c\
|
||||
net/net_send.c\
|
||||
net/prettypacket.c\
|
||||
net/reserve_port.c\
|
||||
net/tcp.c\
|
||||
path/ft_path_notdir.c\
|
||||
|
|
@ -204,6 +206,7 @@ str/ft_strstr.c\
|
|||
str/ft_strsub.c\
|
||||
str/ft_strtok.c\
|
||||
str/ft_strtrim.c\
|
||||
str/hexstring.c\
|
||||
sys/open_new.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> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 "mytime.h"
|
||||
# include "get_next_line.h"
|
||||
# include "net.h"
|
||||
# include "sys.h"
|
||||
# include "net.h"
|
||||
# include "prettypacket.h"
|
||||
|
||||
struct s_stos
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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);
|
||||
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)
|
||||
typedef uint64_t t_bitblock;
|
||||
#define BITFIELD(var, size) t_bitblock var[size / sizeof(t_bitblock) + 1]\
|
||||
= {[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
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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
|
||||
*/
|
||||
|
||||
int reserve_port(int *port);
|
||||
int reserve_port(int s, struct sockaddr *sa);
|
||||
unsigned short cksum(void *b, int len);
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
** prettypacket
|
||||
*/
|
||||
int prettypacket(void *pkt, size_t size);
|
||||
|
||||
#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> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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>
|
||||
|
||||
/*
|
||||
|
|
@ -20,17 +21,13 @@
|
|||
** - 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);
|
||||
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)
|
||||
{
|
||||
field[bit / BLOCKSIZE] &= ~(1 << bit % BLOCKSIZE);
|
||||
field[bit / BLOCKSIZE + 1] &= ~(1 << bit % BLOCKSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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])
|
||||
if ((block+1) * BLOCKSIZE > size)
|
||||
return (-1);
|
||||
if ((block+1) * BLOCKSIZE > size) return (-1);
|
||||
return (block * BLOCKSIZE + __builtin_ctzll(field[block] ^ (~field[block] + 1)) - 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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;
|
||||
while (i < 65535)
|
||||
{
|
||||
sa->sin_port = htons(i);
|
||||
((struct sockaddr_in*)sa)->sin_port = htons(i);
|
||||
if (bind(s, sa, sizeof(sa)) == 0)
|
||||
return (0);
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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"
|
||||
|
||||
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)packet;
|
||||
t_data *data = (t_data*)arg;
|
||||
chan ch = (chan)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);
|
||||
prettypacket((void*)packet, pkthdr->len);
|
||||
(void)ch;
|
||||
/* chs(ch, struct tcphdr, *(t_tcp_packet*)packet); */
|
||||
}
|
||||
|
||||
coroutine void nmap_listener(t_data *data)
|
||||
coroutine void listener_loop(chan ch, pcap_t *pcap_obj)
|
||||
{
|
||||
t_data *data;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
bpf_u_int32 netp;
|
||||
bpf_u_int32 maskp;
|
||||
struct bpf_program fp;
|
||||
char *str;
|
||||
ft_printf("listener loop\n");
|
||||
if (pcap_loop(pcap_obj, -1, packet_callback, (u_char*)ch) == -1)
|
||||
{
|
||||
ft_printf("pcap_loop fail\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -37,24 +58,13 @@ coroutine void nmap_listener(t_data *data)
|
|||
fprintf(stderr, "pcap_open_live: %s", errbuf);
|
||||
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);
|
||||
}
|
||||
if (pcap_compile(pcap_obj, &fp, str, 1, netp) == -1)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (pcap_setfilter(pcap_obj, &fp) == -1)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
/* signal(SIGALRM, sigalrm_handler); */
|
||||
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);
|
||||
go(listener_loop(pkts, pcap_obj));
|
||||
return (chdup(pkts));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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_USAGE2 " [--ports PORTS] [--speedup [NUMBER]] [--scan [TYPE]] HOST"
|
||||
|
||||
/*
|
||||
** only IPv4
|
||||
** only default network if
|
||||
** one per port per scan type
|
||||
*/
|
||||
int fill_ports(t_data *data)
|
||||
{
|
||||
int i;
|
||||
t_data *g_data;
|
||||
|
||||
i = -1;
|
||||
while (++i < SCAN_MAX)
|
||||
coroutine void jobs_loop(chan jobs, chan results)
|
||||
{
|
||||
t_job job;
|
||||
chan copy;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (true)
|
||||
{
|
||||
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);
|
||||
}
|
||||
job = chr(jobs, t_job);
|
||||
if (job.scan == NULL)
|
||||
break ;
|
||||
copy = chdup(results);
|
||||
go(job.scan(copy, job));
|
||||
i++;
|
||||
}
|
||||
printf("finished starting jobs\n");
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
static chan nmap(chan jobs)
|
||||
{
|
||||
t_data data;
|
||||
chan results;
|
||||
|
||||
if (getuid() != 0)
|
||||
{
|
||||
fprintf(stderr, "You must have root privileges to use nmap!\n");
|
||||
return(1);
|
||||
}
|
||||
if (nmap_parse(ac, av, &data))
|
||||
results = chmake(t_result, 0);
|
||||
go(jobs_loop(jobs, results));
|
||||
return (results);
|
||||
}
|
||||
|
||||
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("or nmap"NMAP_USAGE1 NMAP_USAGE2"\n");
|
||||
exit(1);
|
||||
}
|
||||
fill_ports(&data);
|
||||
go(nmap_listener(&data));
|
||||
int chan = nmap(&data);
|
||||
results = nmap(jobs);
|
||||
nmap_format(results);
|
||||
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> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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"
|
||||
|
||||
static t_cliopts g_opts[] =
|
||||
{
|
||||
{'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},
|
||||
};
|
||||
extern int g_njobs;
|
||||
|
||||
static int nmap_get_host(char *node, t_data *data)
|
||||
{
|
||||
t_host host;
|
||||
struct addrinfo *servinfo, hints;
|
||||
/* static t_cliopts g_opts[] = */
|
||||
/* { */
|
||||
/* {'h', "host", 0, 0, nmap_get_host, 0}, */
|
||||
/* /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));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_RAW;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
/* static t_host nmap_get_host(char *node) */
|
||||
/* { */
|
||||
/* t_host host; */
|
||||
/* struct addrinfo *servinfo, hints; */
|
||||
|
||||
if (getaddrinfo(node, NULL, &hints, &servinfo))
|
||||
{
|
||||
fprintf(stderr, "Failed to resolve \"%s\"\n", node);
|
||||
return (1);
|
||||
}
|
||||
host.addr = servinfo->ai_addr;
|
||||
host.addrlen = servinfo->ai_addrlen;
|
||||
host.host = node;
|
||||
host.dn = servinfo->ai_canonname;
|
||||
/* memset (&hints, 0, sizeof (hints)); */
|
||||
/* hints.ai_family = PF_UNSPEC; */
|
||||
/* hints.ai_socktype = SOCK_RAW; */
|
||||
/* hints.ai_flags = AI_CANONNAME; */
|
||||
|
||||
void *addr;
|
||||
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);
|
||||
}
|
||||
/* if (getaddrinfo(node, NULL, &hints, &servinfo)) */
|
||||
/* { */
|
||||
/* fprintf(stderr, "Failed to resolve \"%s\"\n", node); */
|
||||
/* return (host); */
|
||||
/* } */
|
||||
/* host.addr = servinfo->ai_addr; */
|
||||
/* host.addrlen = servinfo->ai_addrlen; */
|
||||
/* host.host = node; */
|
||||
/* host.dn = servinfo->ai_canonname; */
|
||||
|
||||
// convert the IP to a string and print it:
|
||||
inet_ntop(servinfo->ai_family, addr, host.ip, sizeof(host.ip));
|
||||
/* void *addr; */
|
||||
/* 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("rDNS record for %s: %s\n", addrstr, DOMAIN NAME WITH RDNS); */
|
||||
/* printf("dn=%s, ip=%s\n", host.dn, host.ip); */
|
||||
|
||||
ft_lsteadd(&data->host, ft_lstnew(&host, sizeof(host)));
|
||||
return (0);
|
||||
}
|
||||
/* /1* MUST DO rDNS search here *1/ */
|
||||
/* /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) */
|
||||
/* { */
|
||||
|
|
@ -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);
|
||||
return (0);
|
||||
t_job job;
|
||||
|
||||
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;
|
||||
data->host = NULL;
|
||||
bzero(data->ports, sizeof(data->ports));
|
||||
data->threads = 0;
|
||||
data->scan = 0;
|
||||
(void)av;
|
||||
/* if (cliopts_get(av, g_opts, data)) */
|
||||
/* return (ft_perror("nmap")); */
|
||||
/* if (!data->host && data->av_data && data->av_data) */
|
||||
/* nmap_get_host(*data->av_data, data); */
|
||||
|
||||
if (cliopts_get(av, g_opts, data))
|
||||
return (ft_perror("nmap"));
|
||||
if (!data->host && data->av_data && data->av_data)
|
||||
nmap_get_host(*data->av_data, data);
|
||||
if (!data->scan)
|
||||
data->scan = SCAN_TCP;
|
||||
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);
|
||||
chan jobs;
|
||||
jobs = chmake(t_job, 0);
|
||||
go(coarse_dispatcher(jobs));
|
||||
g_njobs = 2;
|
||||
|
||||
return (jobs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,42 +6,44 @@
|
|||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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"
|
||||
|
||||
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_scan_result res;
|
||||
t_tcp_packet pkt;
|
||||
t_result result;
|
||||
chan pkts;
|
||||
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;
|
||||
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));
|
||||
struct tcphdr pkt;
|
||||
result.status = CLOSED;
|
||||
|
||||
tcphdr_init(&pkt.tcph);
|
||||
packet.tcph.dest = htons(target.port);
|
||||
packet.tcph.check = cksum(&packet, sizeof(t_tcp_packet));
|
||||
tcp_hdrinit(&pkt);
|
||||
pkt.th_dport = htons(ipport(job.dest));
|
||||
pkt.th_sport = htons(ipport(src));
|
||||
/* pkt.th_flags = 0; */
|
||||
pkt.th_sum = cksum(&pkt, sizeof(pkt));
|
||||
|
||||
if (sendto(sock, &packet, sizeof(packet), 0,
|
||||
host->addr, host->addrlen) < 0)
|
||||
if (sendto(sock, &pkt, sizeof(pkt), 0,
|
||||
(struct sockaddr*)&job.dest, sizeof(job.dest)) < 0)
|
||||
{
|
||||
perror("sendto");
|
||||
exit(1);
|
||||
}
|
||||
/* chrecv(channel, &buf, sizeof()) */
|
||||
hexdump(&packet, sizeof(packet));
|
||||
pkt = chr(pkts, struct tcphdr);
|
||||
|
||||
|
||||
chsend(ch, res, sizeof(res), -1);
|
||||
printf("result sent\n");
|
||||
hclose(ch);
|
||||
chs(results, t_result, result);
|
||||
chclose(results);
|
||||
return ;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue