From adc4965e383cf076b8091f03c2858155575b2ab1 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Sun, 14 May 2017 22:26:43 +0200 Subject: [PATCH] first commit, seems almost finished. gotta see bonus option and linux compatibility issues --- traceroute/.gitmodules | 3 + traceroute/Makefile | 93 +++++++++++++++++ traceroute/ft_traceroute | Bin 0 -> 13664 bytes traceroute/includes/traceroute.h | 35 +++++++ traceroute/libft | 1 + traceroute/srcs/traceroute.c | 168 +++++++++++++++++++++++++++++++ 6 files changed, 300 insertions(+) create mode 100644 traceroute/.gitmodules create mode 100644 traceroute/Makefile create mode 100755 traceroute/ft_traceroute create mode 100644 traceroute/includes/traceroute.h create mode 160000 traceroute/libft create mode 100644 traceroute/srcs/traceroute.c diff --git a/traceroute/.gitmodules b/traceroute/.gitmodules new file mode 100644 index 00000000..c82793fb --- /dev/null +++ b/traceroute/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libft"] + path = libft + url = https://github.com/jzck/libft diff --git a/traceroute/Makefile b/traceroute/Makefile new file mode 100644 index 00000000..0ce6ee61 --- /dev/null +++ b/traceroute/Makefile @@ -0,0 +1,93 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: wescande +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2016/08/29 21:32:58 by wescande #+# #+# # +# Updated: 2017/04/22 19:26:34 by jhalford ### ########.fr # +# # +# **************************************************************************** # + +NAME = ft_traceroute + +CC = gcc +W_FLAGS = -Wall -Wextra -Werror +D_FLAGS = +FLAGS = $(W_FLAGS) $(D_FLAGS) + +LEN_NAME = `printf "%s" $(NAME) |wc -c` +DELTA = $$(echo "$$(tput cols)-31-$(LEN_NAME)"|bc) + +LIBFT_DIR = libft/ +LIBFT_LIB = $(LIBFT_DIR)libft.a +LIBFT_INC = $(LIBFT_DIR)includes/ + +SRC_DIR = srcs/ +INC_DIR = includes/ +OBJ_DIR = objs/ + +SRC_BASE = \ +traceroute.c\ + +SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) +OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) +NB = $(words $(SRC_BASE)) +INDEX = 0 + +all : + @make -C $(LIBFT_DIR) + @make -j $(NAME) + +$(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(CLIENT_OBJ) + @$(CC) $(OBJS) -o $@ \ + -I $(INC_DIR) \ + -I $(LIBFT_INC) \ + $(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS) + @printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n" + +$(LIBFT_LIB): + @make -C $(LIBFT_DIR) + +$(OBJ_DIR) : + @mkdir -p $(OBJ_DIR) + +$(OBJ_DIR)%.o : $(SRC_DIR)%.c | $(OBJ_DIR) + @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) + @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) + @$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB) - 1)))) + @$(eval COLOR=$(shell list=(160 196 202 208 215 221 226 227 190 154 118 82 46); index=$$(($(PERCENT) * $${#list[@]} / 100)); echo "$${list[$$index]}")) + @printf "\r\033[38;5;%dm⌛ [%s]: %2d%% `printf '█%.0s' {0..$(DONE)}`%*s❙%*.*s\033[0m\033[K" $(COLOR) ft_p $(PERCENT) $(TO_DO) "" $(DELTA) $(DELTA) "$(shell echo "$@" | sed 's/^.*\///')" + @$(CC) $(FLAGS) $(OBJ_FLAG) -MMD -c $< -o $@\ + -I $(INC_DIR)\ + -I $(LIBFT_INC) + @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) + +clean: cleanlib + @if [ -e $(OBJ_DIR) ]; then \ + rm -rf $(OBJ_DIR); \ + printf "\r\033[38;5;202m✗ clean $(NAME) \033[0m\033[K\n"; \ + fi; + +cleanlib: + @make -C $(LIBFT_DIR) clean + +fclean: clean fcleanlib + @for file in $(NAME); do \ + if [ -e $$file ]; then \ + rm -f $$file ; \ + printf "\r\033[38;5;196m✗ fclean $$file\033[0m\033[K\n"; \ + fi; \ + done; + +fcleanlib: cleanlib + @make -C $(LIBFT_DIR) fclean + +re: fclean all + +relib: fcleanlib $(LIBFT_LIB) + +.PHONY : fclean clean re relib cleanlib fcleanlib + +-include $(OBJS:.o=.d) diff --git a/traceroute/ft_traceroute b/traceroute/ft_traceroute new file mode 100755 index 0000000000000000000000000000000000000000..560582dfbb54b91d8dc21e69051ae509e05cb20f GIT binary patch literal 13664 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 F;J=7n6rlhB literal 0 HcmV?d00001 diff --git a/traceroute/includes/traceroute.h b/traceroute/includes/traceroute.h new file mode 100644 index 00000000..ba996d9a --- /dev/null +++ b/traceroute/includes/traceroute.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ping.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */ +/* Updated: 2017/04/22 15:52:07 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PING_H +# define FT_PING_H + +# include "libft.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include + +#define PACKETSIZE 56 + +struct s_packet +{ + struct icmp hdr; + char msg[PACKETSIZE - sizeof(struct icmp)]; +}; + +#endif diff --git a/traceroute/libft b/traceroute/libft new file mode 160000 index 00000000..23c69f13 --- /dev/null +++ b/traceroute/libft @@ -0,0 +1 @@ +Subproject commit 23c69f13242ecbff493356c57cb1384eb1dd45f5 diff --git a/traceroute/srcs/traceroute.c b/traceroute/srcs/traceroute.c new file mode 100644 index 00000000..02b37fd6 --- /dev/null +++ b/traceroute/srcs/traceroute.c @@ -0,0 +1,168 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */ +/* Updated: 2017/04/23 18:18:41 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "traceroute.h" + +int g_pid=-1; + +unsigned short checksum(void *b, int len) +{ + unsigned short *buf = b; + unsigned int sum=0; + unsigned short result; + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + if (len == 1) + sum += *(unsigned char*)buf; + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + result = ~sum; + return (result); +} + +int wait_for_reply(struct sockaddr_in *addr, unsigned char buf[1024]) +{ + static int sd = 0; + + if (sd == 0) + { + if ((sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0) + { + perror("socket"); + exit(0); + } + struct timeval tv; + tv.tv_sec = 5; + tv.tv_usec = 0; + setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(struct timeval)); + } + bzero(buf, 1024); + + socklen_t len = sizeof(*addr); + return (recvfrom(sd, buf, 1024, 0, (struct sockaddr*)addr, &len)); +} + +struct icmp *get_icmp(void *buf) +{ + struct ip *ip = buf; + struct icmp *icmp; + struct s_packet *pkt; + + int hlen = ip->ip_hl << 2; + pkt = (struct s_packet*)(buf + hlen); + icmp = &pkt->hdr; + return (icmp); +} + +int traceroute(struct sockaddr_in *dest) +{ + int ttl; + int sd; + char addrstr[INET_ADDRSTRLEN]; + unsigned char buf[1024]; + struct s_packet pkt; + struct sockaddr_in addr; + struct timeval t1, t2, trip; + double diff; + + if ((sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0) + { + perror("socket"); + return (1); + } + if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0) + perror("Request non blocking IO"); + for (ttl = 1; ttl < 255; ttl++) + { + if (setsockopt(sd, 0, IP_TTL, &ttl, sizeof(ttl)) != 0) + perror("set TTL option"); + printf("%2d ", ttl); + fflush(stdout); + int addrshow = 0; + for (int probe = 0; probe < 3; probe++) + { + bzero(&pkt, sizeof(pkt)); + pkt.hdr.icmp_type = ICMP_ECHO; + pkt.hdr.icmp_id = g_pid; + pkt.hdr.icmp_seq = (ttl - 1) * 3 + probe; + pkt.hdr.icmp_cksum = checksum(&pkt, sizeof(pkt)); + if (sendto(sd, &pkt, sizeof(pkt), 0, (struct sockaddr*)dest, sizeof(*dest)) <= 0) + perror("sendto"); + + if (gettimeofday(&t1, NULL) != 0) + return (1); + + int bytes = wait_for_reply(&addr, buf); + + if (gettimeofday(&t2, NULL) != 0) + return (1); + + if (bytes < 0) + { + printf(" *"); + fflush(stdout); + continue ; + } + timersub(&t2, &t1, &trip); + diff = (trip.tv_sec + trip.tv_usec / 1000000.0) * 1000.0; + if (!addrshow) + { + char hostname[1024]; + char servname[20]; + + if (getnameinfo((struct sockaddr*)&addr, sizeof(addr), hostname, sizeof(hostname), servname, sizeof(servname), 0)) + { + perror("getnameinfo"); + exit(1); + } + printf(" %s (%s)", hostname, inet_ntop(AF_INET, &(addr.sin_addr), addrstr, INET_ADDRSTRLEN)); addrshow = 1; + } + printf(" %.3f ms", diff); + } + printf("\n"); + struct icmp *icmp = get_icmp(buf); + if (icmp->icmp_type == ICMP_ECHOREPLY) + break ; + } + exit(0); +} + +int main(int ac, char **av) +{ + struct sockaddr_in *addr; + struct addrinfo *result, hints; + char addrstr[INET_ADDRSTRLEN]; + + if (ac != 2) + { + printf("usage: %s \n", av[0]); + exit(1); + } + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags |= AI_CANONNAME; + if (getaddrinfo(av[1], NULL, &hints, &result) != 0) + { + perror("getaddrinfo"); + exit(1); + } + addr = (struct sockaddr_in*)result->ai_addr; + inet_ntop(AF_INET, &(addr->sin_addr), addrstr, INET_ADDRSTRLEN); + g_pid = getpid(); + if (result->ai_next) + printf("traceroute: Warning: %s has multiple addresses; using %s\n", result->ai_canonname, addrstr); + printf("traceroute to %s (%s), %i hops max %i byte packets\n", + FT_TRY(result->ai_canonname, addrstr), addrstr, 64, PACKETSIZE); + exit(traceroute(addr)); +}