diff --git a/.gitignore b/.gitignore index 82b5272..4dd5c54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ obj -ft_nmap \ No newline at end of file +ft_nmap +.cache +compile_commands.json diff --git a/Makefile b/Makefile index 646df5e..e56b23b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CC := gcc CFLAGS := -Wall -Wextra -Werror -iquoteinclude -g LD := $(CC) -LDFLAGS := +LDFLAGS := -lpcap SRC := $(shell find src -name '*.c') OBJ := $(patsubst src/%.c,obj/%.o,$(SRC)) @@ -28,4 +28,4 @@ re: $(MAKE) fclean $(MAKE) all -.PHONY: all clean fclean re \ No newline at end of file +.PHONY: all clean fclean re diff --git a/include/dns.h b/include/dns.h new file mode 100644 index 0000000..2f33b4a --- /dev/null +++ b/include/dns.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +int dns_lookup(char *ip_addr, char *hostname, struct sockaddr_in *addr_con); +int reverse_dns_lookup(char *ip_addr, char *host); diff --git a/include/error.h b/include/error.h new file mode 100644 index 0000000..fed054a --- /dev/null +++ b/include/error.h @@ -0,0 +1,3 @@ +#pragma once + +int err(char *str); diff --git a/include/interface.h b/include/interface.h new file mode 100644 index 0000000..151765e --- /dev/null +++ b/include/interface.h @@ -0,0 +1,3 @@ +#pragma once + +char *get_interface_name(void); diff --git a/include/print.h b/include/print.h new file mode 100644 index 0000000..711f5a2 --- /dev/null +++ b/include/print.h @@ -0,0 +1,3 @@ +#pragma once + +void print_usage(void); diff --git a/include/scan.h b/include/scan.h new file mode 100644 index 0000000..b09d7b8 --- /dev/null +++ b/include/scan.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +typedef enum { + SCAN_SYN, + SCAN_NULL, + SCAN_ACK, + SCAN_FIN, + SCAN_XMAS, + SCAN_UDP, + SCAN_TCP, +} e_scantype; + +int routine(const char *ip_addr, e_scantype type, uint16_t min_port, + uint16_t max_port); diff --git a/src/dns.c b/src/dns.c new file mode 100644 index 0000000..4ef1c0a --- /dev/null +++ b/src/dns.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include + +int dns_lookup(char *ip_addr, char *hostname, struct sockaddr_in *addr_con) +{ + struct hostent *host = gethostbyname2(hostname, AF_INET); + if (!host) { + dprintf(2, "Hostname %s doesn't exist or has invalid format.", + hostname); + return -1; + } + strcpy(ip_addr, inet_ntoa(*(struct in_addr *)host->h_addr)); + (*addr_con).sin_family = host->h_addrtype; + (*addr_con).sin_port = htons(0); + (*addr_con).sin_addr.s_addr = *(long *)host->h_addr; + + return 0; +} + +int reverse_dns_lookup(char *ip_addr, char *host) +{ + struct sockaddr_in tmp_addr; + + tmp_addr.sin_family = AF_INET; + tmp_addr.sin_addr.s_addr = inet_addr(ip_addr); + if (getnameinfo((struct sockaddr *)&tmp_addr, + sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, + NI_NAMEREQD)) { + dprintf(2, "Could not resolve reverse lookup of %s\n", ip_addr); + return -1; + } + + return 0; +} diff --git a/src/error.c b/src/error.c new file mode 100644 index 0000000..5193795 --- /dev/null +++ b/src/error.c @@ -0,0 +1,9 @@ +#include +#include + +int err(char *str) +{ + int err = errno; + perror(str); + return err; +} diff --git a/src/get_interface.c b/src/get_interface.c new file mode 100644 index 0000000..75b4e34 --- /dev/null +++ b/src/get_interface.c @@ -0,0 +1,24 @@ +#include +#include + +char *get_interface_name(void) +{ + pcap_if_t *alldevs; + char errbuf[PCAP_ERRBUF_SIZE]; + + if (pcap_findalldevs(&alldevs, errbuf) == -1) { + dprintf(2, "Error finding devices: %s\n", errbuf); + return NULL; + } + + for (pcap_if_t *it = alldevs; it != NULL; it = it->next) { + if (!(it->flags & PCAP_IF_LOOPBACK)) { + char *name = strdup(it->name); + pcap_freealldevs(alldevs); + return name; + } + } + + dprintf(2, "No non-loopback interface found.\n"); + return NULL; +} diff --git a/src/main.c b/src/main.c index 22c2bc6..5c01a71 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,35 @@ +#include +#include +#include #include +#include + +#include "dns.h" +#include "print.h" +#include "scan.h" int main(int ac, char **av) { - (void) ac; - (void) av; - printf("%s %s\n", - "gros gras grand grain d'orge, quand te dégros-gras-grand-grain-d'orgeras-tu ?", - "Je me dégros-gras-grand-grain-d'orgerai, quand tous les gros gras grains d'orge se seront dégros-gras-grand-grain- d'orgés."); + if (ac < 2) { + dprintf(2, "Usage: ft_nmap [Scan Type(s)] [Options] {target " + "specification}\n"); + print_usage(); + return 0; + } + // TODO parse arguments + (void)av; - return 0; -} \ No newline at end of file + char ip_addr[INET_ADDRSTRLEN]; + struct sockaddr_in addr_con; + if (dns_lookup(ip_addr, av[1], &addr_con)) { + dprintf(2, "ft_nmap: failed to retrieve ip address from %s\n", + av[1]); + return 1; + } + if (routine(ip_addr, SCAN_SYN, 1, 1024) < 0) { + dprintf(2, "ft_nmap: failed to scan ports\n"); + return 1; + } + + return 0; +} diff --git a/src/print.c b/src/print.c new file mode 100644 index 0000000..17ee1df --- /dev/null +++ b/src/print.c @@ -0,0 +1,6 @@ +#include "print.h" + +void print_usage(void) +{ + // TODO print options list +} diff --git a/src/scan.c b/src/scan.c new file mode 100644 index 0000000..e0a2108 --- /dev/null +++ b/src/scan.c @@ -0,0 +1,26 @@ +#include +#include +#include + +#include "error.h" +#include "interface.h" +#include "scan.h" + +int routine(const char *ip_addr, e_scantype type, uint16_t min_port, + uint16_t max_port) +{ + int sockfd = + socket(AF_INET, type == SCAN_UDP ? SOCK_DGRAM : SOCK_STREAM, 0); + if (sockfd < 0) + return err("Failed to create socket"); + + char *default_if = get_interface_name(); + printf("%s\n", default_if); + + (void)ip_addr; + for (int port = min_port; port <= max_port; port++) { + // scan(ip_addr, type, port); + } + + return 0; +}