diff --git a/nmap/Makefile b/nmap/Makefile index 1851414d..de378f28 100644 --- a/nmap/Makefile +++ b/nmap/Makefile @@ -33,6 +33,7 @@ OBJ_DIR = objs/ SRC_BASE = \ main.c\ nmap.c\ +parser.c\ listener.c\ SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) diff --git a/nmap/includes/nmap.h b/nmap/includes/nmap.h index 61e78762..ffe34318 100644 --- a/nmap/includes/nmap.h +++ b/nmap/includes/nmap.h @@ -24,7 +24,6 @@ # include # include # include -# include # include # include # include @@ -36,8 +35,12 @@ # define SCAN_FIN (1 << 4) # define SCAN_XMAS (1 << 5) # define SCAN_UDP (1 << 6) +# define SCAN_MAX 7 typedef struct s_data t_data; +typedef struct s_host t_host; +typedef struct s_tcp_packet t_tcp_packet; +typedef enum e_port_status t_port_status; struct s_data { @@ -47,12 +50,46 @@ struct s_data t_list *port; int threads; int scan; + int src_port; +}; + +/* enum e_scan_type */ +/* { */ +/* SCAN_SYN, */ +/* SCAN_NULL, */ +/* SCAN_ACK, */ +/* SCAN_FIN, */ +/* SCAN_XMAS, */ +/* SCAN_UDP, */ +/* }; */ + +enum e_port_status +{ + OPEN, + FILTERED, + CLOSED, + UNFILTERED, + OPEN_FILTERED, }; struct s_host { - struct sockaddr_in *addr; - char * + char *node; // user inputed node (ip or dn) + char *dn; // ai_canonname + char ip[INET6_ADDRSTRLEN]; // readable ip address (4 or 6) + int sock_tcp; + int sock_udp; + int sock_icmp; + t_port_status results[USHRT_MAX + 1]; + char scanning[USHRT_MAX + 1]; + struct sockaddr *addr; + size_t addrlen; +}; + +struct s_tcp_packet +{ + struct iphdr iph; + struct tcphdr tcph; }; static t_cliopts g_opts[]; @@ -60,4 +97,10 @@ static t_cliopts g_opts[]; void nmap(t_data *data); void *nmap_listener(void *arg); +int nmap_get_host(char *node, t_data *data); +int nmap_get_file(char *opt_arg, t_data *data); +int nmap_get_ports(char *opt_arg, t_data *data); +int nmap_get_threads(char *opt_arg, t_data *data); +int nmap_get_scan(char *opt_arg, t_data *data); + #endif diff --git a/nmap/srcs/listener.c b/nmap/srcs/listener.c index 99b7de85..0a92f385 100644 --- a/nmap/srcs/listener.c +++ b/nmap/srcs/listener.c @@ -8,7 +8,7 @@ static void packet_callback(u_char *tmp, const struct pcap_pkthdr *pkthdr, const (void)tmp; (void)pkthdr; (void)packet; - printf("received packet !!!"); + printf("received packet !!!\n"); } void *nmap_listener(void *arg) @@ -30,7 +30,7 @@ void *nmap_listener(void *arg) fprintf(stderr, "pcap_open_live: %s", errbuf); exit(EXIT_FAILURE); } - if (!(str = ft_str3join("host ", data->host, " and (tcp or icmp)"))) + if (!(str = ft_str3join("host ", ((t_host*)data->host->content)->ip, " and (tcp or icmp)"))) { exit(EXIT_FAILURE); } diff --git a/nmap/srcs/main.c b/nmap/srcs/main.c index 9f813a1e..88da3329 100644 --- a/nmap/srcs/main.c +++ b/nmap/srcs/main.c @@ -3,79 +3,6 @@ #define NMAP_USAGE1 " [--ip HOST] [--file FILE]" #define NMAP_USAGE2 " [--ports PORTS] [--speedup [NOMBRE]] [--scan [TYPE]] HOST" -int nmap_get_host(char *opt_arg, t_data *data) -{ - t_host *host; - - host = opt_arg; - struct sockaddr_in *addr; - struct addrinfo *servinfo, hints; - char addrstr[INET_ADDRSTRLEN]; - int sockfd; - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_RAW; - hints.ai_flags = AI_CANONNAME; - - if (getaddrinfo(host, NULL, &hints, &servinfo)) - { - fprintf(stderr, "Failed to resolve \"%s\"\n", host); - return (1); - } - host->addr = (struct sockaddr_in*)servinfo->ai_addr; - inet_ntop(AF_INET, &(addr->sin_addr), addrstr, INET_ADDRSTRLEN); - host->addrstr = addrstr; - - /* MUST DO AND rDNS search here */ - /* printf("rDNS record for %s: %s\n", addrstr, DOMAIN NAME WITH RDNS); */ - - if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) - perror("server: socket"); - - ft_lsteadd(&data->host, &host); - return (0); -} - -/* int nmap_get_file(char *opt_arg, t_data *data) */ -/* { */ -/* } */ - -/* int nmap_get_ports(char *opt_arg, t_data *data) */ -/* { */ -/* } */ - -int nmap_get_threads(char *opt_arg, t_data *data) -{ - data->threads = ft_atoi(opt_arg); - return (0); -} - -int nmap_get_scan(char *opt_arg, t_data *data) -{ - while (*opt_arg) - { - if (*opt_arg == 'T') - data->scan |= SCAN_TCP; - else if (*opt_arg == 'S') - data->scan |= SCAN_SYN; - else if (*opt_arg == 'N') - data->scan |= SCAN_NULL; - else if (*opt_arg == 'A') - data->scan |= SCAN_ACK; - else if (*opt_arg == 'F') - data->scan |= SCAN_FIN; - else if (*opt_arg == 'X') - data->scan |= SCAN_XMAS; - else if (*opt_arg == 'U') - data->scan |= SCAN_UDP; - else - return (1); - opt_arg++; - } - return (0); -} - static t_cliopts g_opts[] = { {'i', "ip", 0, 0, nmap_get_host, 0}, @@ -86,7 +13,6 @@ static t_cliopts g_opts[] = {0, 0, 0, 0, 0, 0}, }; - int nmap_parse(int ac, char **av, t_data *data) { (void)ac; @@ -97,8 +23,8 @@ int nmap_parse(int ac, char **av, t_data *data) if (cliopts_get(av, g_opts, data)) return (ft_perror("nmap")); - if (!data->host && data->av_data) - data->host = *data->av_data; + if (!data->host && data->av_data && data->av_data) + nmap_get_host(*data->av_data, data); if (!data->scan) data->scan = SCAN_TCP; return (0); @@ -108,6 +34,12 @@ int main(int ac, char **av) { t_data data; + if (getuid() != 0) + { + fprintf(stderr, "You must have root privileges to use nmap!\n"); + return(1); + } + if (nmap_parse(ac, av, &data)) { printf("usage: nmap --help\n"); @@ -115,6 +47,12 @@ int main(int ac, char **av) exit(1); } + if (reserve_port(&data.src_port)) + { + fprintf(stderr, "couldn't reserve port\n"); + exit(1); + } + pthread_t listener; pthread_create(&listener, NULL, &nmap_listener, &data); nmap(&data); diff --git a/nmap/srcs/nmap.c b/nmap/srcs/nmap.c index 88038090..a4c3d985 100644 --- a/nmap/srcs/nmap.c +++ b/nmap/srcs/nmap.c @@ -12,31 +12,67 @@ #include "nmap.h" -int nmap_scan_syn(int sockfd, struct addrinfo *p) +unsigned short cksum(void *b, int len) { - if (connect(sockfd, p->ai_addr, p->ai_addrlen)) - printf("connect failed"); - else - printf("connect success"); + unsigned short *buf = b; + unsigned int sum=0; + + for (sum = 0; len > 1; len -= 2) + sum += *((unsigned short*)buf++); + if (len == 1) + sum += *(unsigned char*)buf; + + sum = (sum >> 16) + (sum & 0xFFFF); + return (~(sum + (sum >> 16))); +} + +int nmap_scan_tcp(t_data *data, struct iphdr *iph, t_host *host, int port) +{ + t_tcp_packet packet; + + packet.iph = *iph; + + tcphdr_init(&packet.tcph); + packet.tcph.dest = htons(port); + packet.tcph.source = htons(data->src_port); + packet.tcph.syn = 1; + packet.tcph.check = cksum(&packet, sizeof(t_tcp_packet)); + if (sendto(host->sock_tcp, &packet, sizeof(packet), 0, host->addr, host->addrlen) < 0) + { + perror("sendto"); + exit(1); + } + printf("packet sent\n"); + sleep(2); return (0); } -int nmap_scan(char *host, int port, int scan) -{ - - - nmap_scan_syn(sockfd, servinfo); - - freeaddrinfo(servinfo); - - return (0); -} +/* int nmap_scan(char *host, int port, int scan) */ +/* { */ +/* (void)scan; */ +/* nmap_scan_syn(sockfd, servinfo); */ +/* return (0); */ +/* } */ void nmap(t_data *data) { - while (data->host) + t_list *list; + t_host *host; + struct iphdr iph; + + list = data->host; + if (!list) + return ; + for (host = list->content; list != NULL; list = list->next ) { - nmap_scan(data->host, 80, SCAN_TCP); + printf("scanning %s...\n", host->dn); + + iphdr_init(&iph); + iph.protocol = IPPROTO_TCP; + iph.daddr = *(int32_t*)host->addr; + iph.tot_len = sizeof(t_tcp_packet); + + nmap_scan_tcp(data, &iph, host, 80); break ; } } diff --git a/nmap/srcs/parser.c b/nmap/srcs/parser.c new file mode 100644 index 00000000..455c05c4 --- /dev/null +++ b/nmap/srcs/parser.c @@ -0,0 +1,91 @@ +#include "nmap.h" + +int nmap_get_host(char *node, t_data *data) +{ + t_host host; + struct addrinfo *servinfo, hints; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_RAW; + hints.ai_flags = AI_CANONNAME; + + 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.node = node; + host.dn = servinfo->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); + } + + // convert the IP to a string and print it: + inet_ntop(servinfo->ai_family, addr, host.ip, sizeof(host.ip)); + + + printf("dn=%s\n", host.dn); + printf("ip=%s\n", host.ip); + + /* MUST DO AND rDNS search here */ + /* printf("rDNS record for %s: %s\n", addrstr, DOMAIN NAME WITH RDNS); */ + + if ((host.sock_tcp = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) + perror("server: socket"); + + int val = 1; + if (setsockopt(host.sock_tcp, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) == -1) + return (1); + + ft_lsteadd(&data->host, ft_lstnew(&host, sizeof(host))); + return (0); +} + +/* int nmap_get_file(char *opt_arg, t_data *data) */ +/* { */ +/* } */ + +/* int nmap_get_ports(char *opt_arg, t_data *data) */ +/* { */ +/* } */ + +int nmap_get_threads(char *opt_arg, t_data *data) +{ + data->threads = ft_atoi(opt_arg); + return (0); +} + +int nmap_get_scan(char *opt_arg, t_data *data) +{ + while (*opt_arg) + { + if (*opt_arg == 'T') + data->scan |= SCAN_TCP; + else if (*opt_arg == 'S') + data->scan |= SCAN_SYN; + else if (*opt_arg == 'N') + data->scan |= SCAN_NULL; + else if (*opt_arg == 'A') + data->scan |= SCAN_ACK; + else if (*opt_arg == 'F') + data->scan |= SCAN_FIN; + else if (*opt_arg == 'X') + data->scan |= SCAN_XMAS; + else if (*opt_arg == 'U') + data->scan |= SCAN_UDP; + else + return (1); + opt_arg++; + } + return (0); +} +