/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* icmp.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 22:49:22 by tomoron #+# #+# */ /* Updated: 2025/05/22 22:19:36 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "includes/ft_ping.h" static void set_packet_data(uint8_t *packet_data) { int i; i = 0; while(i < PACKET_DATA_LENGTH) { packet_data[i] = i; i++; } } uint16_t calc_checksum(void *ptr, size_t len) { uint32_t res; uint16_t *data; data = ptr; res = 0; while (len > 1) { res += *data; data++; len -= 2; } if (len) res += *(uint8_t *)data; while (res >> 16) { res = (res & 0xFFFF) + (res >> 16); } return(~res); } t_icmp_echo prepare_icmp_echo(uint16_t sequence, uint16_t identifier) { t_icmp_echo packet; packet.type = 8; packet.code = 0; packet.identifier = htons(identifier); packet.sequence = htons(sequence); set_packet_data(packet.data); gettimeofday(&packet.time, 0); packet.checksum = 0; packet.checksum = calc_checksum(&packet, sizeof(t_icmp_echo)); return(packet); } t_waitlist *send_icmp(t_settings *set, struct addrinfo *host, uint16_t *seq, struct timeval *last, t_stats *stats) { t_icmp_echo packet; t_waitlist *ret; size_t len; if(timediff(last) < set->interval) return (0); packet = prepare_icmp_echo(*seq, set->id); len = sendto(set->socket, &packet, sizeof(t_icmp_echo), 0, host->ai_addr, host->ai_addrlen); if(len == (size_t)-1) { perror(set->name); set->err = 1; g_stop = 1; } gettimeofday(last, 0); ret = malloc(sizeof(t_waitlist)); if(!ret) return(0); ret->time = *last; ret->seq = *seq; ret->next = 0; stats->sent++; gettimeofday(&set->last_send_time, 0); (*seq)++; return(ret); } void receive_icmp(t_settings *set, struct addrinfo *info, t_waitlist **wl, t_stats *stats) { size_t len; t_icmp_ip_reply res; uint16_t checksum; 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(len == (size_t)-1 ) return; if(res.icmp.type != 0 && res.icmp.identifier != set->id) return ; checksum = res.icmp.checksum; res.icmp.checksum = 0; if(calc_checksum(&res.icmp, sizeof(t_icmp_echo)) != checksum) return ; res.icmp.sequence = htons(res.icmp.sequence); waitlist_remove(wl, res.icmp.sequence, set, stats, res.header.ttl); }