/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_ping.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/26 19:54:25 by tomoron #+# #+# */ /* Updated: 2025/04/30 01:57:10 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "includes/ft_ping.h" struct addrinfo *resolve_ip(char *host) { struct addrinfo hints, *result; int s; struct addrinfo *ret; memset(&hints, 0, sizeof(hints)); ret = 0; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; s = getaddrinfo(host, NULL, &hints, &result); if (s != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); return(ret); } ret = result; if(!ret) return(ret); ret->ai_next = 0; result = result->ai_next; freeaddrinfo(result); return(ret); } double timediff(struct timeval *from) { struct timeval now; float diff; gettimeofday(&now, 0); diff = ((double)now.tv_sec - from->tv_sec); diff += (((double)now.tv_usec / 1000000) - ((double)from->tv_usec / 1000000)); return(diff); } t_waitlist *send_icmp(t_settings *set, struct addrinfo *host, int seq, struct timeval *last) { t_icmp_echo packet; t_waitlist *ret; if(timediff(last) < set->interval) return (0); printf("send packet\n"); packet = prepare_icmp_echo(seq, set->id); sendto(set->socket, &packet, sizeof(t_icmp_echo), 0, host->ai_addr, host->ai_addrlen); gettimeofday(last, 0); ret = malloc(sizeof(t_waitlist)); if(!ret) return(0); ret->time = *last; ret->seq = seq; ret->next = 0; return(ret); } void waitlist_add(t_waitlist **waitlist, t_waitlist *elem) { t_waitlist *cur; cur = *waitlist; while(cur && cur->next) cur = cur->next; if(cur) cur->next = elem; else *waitlist = elem; } void whitelist_free(t_waitlist *lst) { t_waitlist *tmp; while(lst) { tmp = lst->next; free(lst); lst = tmp; } } void receive_icmp(t_settings *set, struct addrinfo *info, t_waitlist **wl) { size_t len; t_icmp_echo packet; t_waitlist *tmp; len = recvfrom(set->socket, &packet, sizeof(t_icmp_echo), 0, info->ai_addr, &info->ai_addrlen); if(len == -1 || !len) return; tmp = *wl; while(tmp && tmp->seq != packet.sequence) tmp = tmp->next; if(tmp) { free(tmp); } (void)len; } int ping_host(t_settings *set, char *host) { uint16_t seq; struct addrinfo *info; struct timeval last_sent; t_waitlist *wl; t_waitlist *tmp; seq = 0; info = resolve_ip(host); if(!info) return(0); last_sent.tv_sec = 0; last_sent.tv_usec = 0; wl = 0; while(seq < set->count || set->count == -1) { tmp = send_icmp(set, info, seq, &last_sent); if(tmp) waitlist_add(&wl, tmp); usleep(1000); receive_icmp(set, info, &wl); } while(wl) receive_icmp(set, info, &wl); freeaddrinfo(info); whitelist_free(wl); return(1); } void send_pings(t_settings *set) { t_host_list *cur; cur = set->hosts; while(cur) { if(!ping_host(set, cur->host)) return; cur = cur->next; } }