From 94085f5bb2c1deddad4efd4a8194307b9e38ca29 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 22 May 2025 15:30:34 +0200 Subject: [PATCH] fix ping loss, add ttl from ip header compile .h file to detect changes --- Makefile | 10 ++++++++-- srcs/ft_ping.c | 4 ++-- srcs/icmp.c | 25 +++++++++++++------------ srcs/includes/ft_ping.h | 24 +++++++++++++++--------- srcs/stats.c | 6 +++--- srcs/waitlist_utils.c | 6 +++--- 6 files changed, 44 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 0fbee48..bce7a97 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ NAME = ft_ping CC=cc -FLAGS=-Werror -Wextra -Wall -g -Wno-unused-result +FLAGS=-Werror -Wextra -Wall -g -Wno-unused-result -Qunused-arguments SRCS_DIR = srcs +INCLUDES_DIR = srcs/includes OBJS_DIR = .objs SRCS = main.c\ @@ -13,7 +14,10 @@ SRCS = main.c\ stats.c\ waitlist_utils.c -OBJS = $(addprefix $(OBJS_DIR)/,$(SRCS:.c=.o)) +INCLUDES = ft_ping.h + +OBJS = $(addprefix $(OBJS_DIR)/,$(SRCS:.c=.o))\ + $(addprefix $(OBJS_DIR)/,$(INCLUDES:.h=.pch)) all: $(NAME) @@ -25,6 +29,8 @@ $(OBJS_DIR): $(OBJS_DIR)/%.o: $(SRCS_DIR)/%.c $(CC) $(FLAGS) -c $< -o $@ +$(OBJS_DIR)/%.pch: $(INCLUDES_DIR)/%.h + $(CC) $(FLAGS) -c $< -o $@ clean: rm -rf $(OBJS_DIR) diff --git a/srcs/ft_ping.c b/srcs/ft_ping.c index cafd078..f16c393 100644 --- a/srcs/ft_ping.c +++ b/srcs/ft_ping.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/26 19:54:25 by tomoron #+# #+# */ -/* Updated: 2025/05/02 23:55:50 by tomoron ### ########.fr */ +/* Updated: 2025/05/22 15:24:43 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ void ping_end_print(t_settings *set, char *host, t_stats *stats) if(isnan(stddev) || isinf(stddev)) stddev = 0.0f; printf("--- %s ping statistics ---\n", host); - percent = ((double)stats->sent / 100) * stats->received; + percent = ((double)(stats->sent - stats->received) / stats->sent) * 100.0; printf("%lu packets transmitted, %lu packets received, %d%% packet loss\n", stats->sent, stats->received, percent); printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n", stats->min, stats->avg, stats->max, stddev); } diff --git a/srcs/icmp.c b/srcs/icmp.c index ca8b5a3..84842b2 100644 --- a/srcs/icmp.c +++ b/srcs/icmp.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 22:49:22 by tomoron #+# #+# */ -/* Updated: 2025/05/01 20:19:41 by tomoron ### ########.fr */ +/* Updated: 2025/05/22 15:26:40 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "includes/ft_ping.h" @@ -87,20 +87,21 @@ t_waitlist *send_icmp(t_settings *set, struct addrinfo *host, uint16_t *seq, str void receive_icmp(t_settings *set, struct addrinfo *info, t_waitlist **wl, t_stats *stats) { size_t len; - char buf[256]; - t_icmp_echo *res; + t_icmp_ip_reply res; uint16_t checksum; - len = recvfrom(set->socket, buf, sizeof(t_icmp_echo) + 20, 0, info->ai_addr, &info->ai_addrlen); - res = (void*)(buf + 20); - if(len == (size_t)-1 || len < 84) + len = recvfrom(set->socket, &res, sizeof(t_icmp_ip_reply), 0, info->ai_addr, &info->ai_addrlen); + + if(len < sizeof(t_icmp_ip_reply)) return; - if(res->type != 0 && res->identifier != set->id) + if(len == (size_t)-1 ) + return; + if(res.icmp.type != 0 && res.icmp.identifier != set->id) return ; - checksum = res->checksum; - res->checksum = 0; - if(calc_checksum(res, sizeof(t_icmp_echo)) != checksum) + checksum = res.icmp.checksum; + res.icmp.checksum = 0; + if(calc_checksum(&res.icmp, sizeof(t_icmp_echo)) != checksum) return ; - res->sequence = htons(res->sequence); - waitlist_remove(wl, res->sequence, set, stats); + res.icmp.sequence = htons(res.icmp.sequence); + waitlist_remove(wl, res.icmp.sequence, set, stats, res.header.ttl); } diff --git a/srcs/includes/ft_ping.h b/srcs/includes/ft_ping.h index 95fbaf1..f096c63 100644 --- a/srcs/includes/ft_ping.h +++ b/srcs/includes/ft_ping.h @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -23,13 +24,13 @@ #define HELP_MESSAGE " [OPTION...] HOST ...\n\ Send ICMP ECHO_REQUEST packets to network hosts.\n\ \n\ - -c, --count=N stop after sending NUMBER packets\n\ - --ttl=N specify N as time-to-live\n\ - -w, --timeout=N stop after N seconds\n\ - -i, --interval=N wait N seconds between sending each packet\n\ - -W, --linger=N number of seconds to wait for response\n\ + -c, --count=N Stop after sending NUMBER packets\n\ + --ttl=N Specify N as time-to-live\n\ + -i, --interval=N Wait N seconds between sending each packet\n\ + -w, --timeout=N Stop after N seconds\n\ + -W, --linger=N Number of seconds to wait for response\n\ \n\ - -?, --help give this help list\n" + -?, --help Give this help list\n" extern int g_stop; @@ -63,7 +64,6 @@ typedef struct s_settings char *name; char current_ip[INET_ADDRSTRLEN]; - } t_settings; @@ -78,6 +78,12 @@ typedef struct s_icmp_echo uint8_t data[40]; } t_icmp_echo; +typedef struct __attribute__((__packed__)) +{ + struct iphdr header; + t_icmp_echo icmp; +} t_icmp_ip_reply; + typedef struct s_stats { size_t sent; @@ -99,8 +105,8 @@ void show_help(t_settings *set, char *name); void send_pings(t_settings *set); uint16_t calc_checksum(void *ptr, size_t len); double timediff(struct timeval *from); -void waitlist_remove(t_waitlist **lst, uint16_t seq, t_settings *set, t_stats *stats); -void show_ping_res_line(t_waitlist *cur, t_settings *set, uint16_t seq, t_stats *stats); +void waitlist_remove(t_waitlist **lst, uint16_t seq, t_settings *set, t_stats *stats, uint8_t ttl); +void show_ping_res_line(t_waitlist *cur, t_settings *set, uint16_t seq, t_stats *stats, uint8_t ttl); void waitlist_free(t_waitlist *lst); t_waitlist *send_icmp(t_settings *set, struct addrinfo *host, uint16_t *seq, struct timeval *last, t_stats *stats); void waitlist_add(t_waitlist **waitlist, t_waitlist *elem); diff --git a/srcs/stats.c b/srcs/stats.c index 5956949..f6a990f 100644 --- a/srcs/stats.c +++ b/srcs/stats.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/01 17:41:42 by tomoron #+# #+# */ -/* Updated: 2025/05/02 23:53:28 by tomoron ### ########.fr */ +/* Updated: 2025/05/22 15:28:03 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,12 +28,12 @@ void update_stats(t_stats *stats, double time) stats->prev = time; } -void show_ping_res_line(t_waitlist *cur, t_settings *set, uint16_t seq, t_stats *stats) +void show_ping_res_line(t_waitlist *cur, t_settings *set, uint16_t seq, t_stats *stats, uint8_t ttl) { double diff; diff = timediff(&cur->time) * 1000; update_stats(stats, diff); - printf("%d bytes from %s: icmp_seq=%d ttl=??? time=%.3f ms\n", 64, set->current_ip, seq, diff); + printf("%d bytes from %s: icmp_seq=%d ttl=%u time=%.3f ms\n", 64, set->current_ip, seq, ttl, diff); } diff --git a/srcs/waitlist_utils.c b/srcs/waitlist_utils.c index 034d327..8fcb3b5 100644 --- a/srcs/waitlist_utils.c +++ b/srcs/waitlist_utils.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/01 17:38:58 by tomoron #+# #+# */ -/* Updated: 2025/05/02 01:06:21 by tomoron ### ########.fr */ +/* Updated: 2025/05/22 15:25:38 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,7 +38,7 @@ void waitlist_free(t_waitlist *lst) } } -void waitlist_remove(t_waitlist **lst, uint16_t seq, t_settings *set, t_stats *stats) +void waitlist_remove(t_waitlist **lst, uint16_t seq, t_settings *set, t_stats *stats, uint8_t ttl) { t_waitlist *prev; t_waitlist *cur; @@ -57,7 +57,7 @@ void waitlist_remove(t_waitlist **lst, uint16_t seq, t_settings *set, t_stats *s *lst = cur->next; else prev->next = cur->next; - show_ping_res_line(cur, set, seq, stats); + show_ping_res_line(cur, set, seq, stats, ttl); free(cur); }