diff --git a/src/main.c b/src/main.c index a3205bd..684f5b7 100644 --- a/src/main.c +++ b/src/main.c @@ -77,15 +77,17 @@ static int preload(struct setting const *settings, int sockfd, char const *packe return 0; } -static int check_reply(struct sockaddr_in const *me, struct sockaddr_in const *sender, char *sent, char *received, size_t sent_size, size_t recv_size) +static int check_reply(struct sockaddr_in const *me, struct sockaddr_in const *sender, struct icmphdr *sent_hdr, struct icmphdr *recv_hdr, size_t sent_size, ssize_t recv_size) { - if (sent_size != recv_size) - return 0; - if (((struct icmphdr *)sent)->type != 0) - return 0; - if (check_packet_conformity(sent, received, sent_size)) + if (recv_size < (ssize_t) sizeof(struct icmphdr)) return 1; - return memcmp(sender, me, sizeof(struct sockaddr_in)); + if (memcmp(sender, me, sizeof(struct sockaddr_in))) + return 1; + if (recv_hdr->type == 8) + return 1; + if ((size_t) recv_size != sent_size) + return 1; + return check_packet_conformity((char *)sent_hdr, (char *)recv_hdr, recv_size); } int main(int ac, char **av) @@ -135,10 +137,9 @@ int main(int ac, char **av) if (preload(&settings, sockfd, packet, packet_size)) goto error3; + struct timeval stop, start; while (loop) { - struct timeval stop, start; - gettimeofday(&start, NULL); if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings.dest.ip, sizeof(settings.dest.ip)) == -1) { @@ -147,27 +148,28 @@ int main(int ac, char **av) } stats.packets_sent++; - ssize_t ret = 0; - do + while (loop) { - ret = recvfrom(sockfd, buffer, recv_packet_size, 0, (struct sockaddr *) &sender, &len); + ssize_t recv_size = recvfrom(sockfd, buffer, recv_packet_size, 0, (struct sockaddr *) &sender, &len); + gettimeofday(&stop, NULL); - } - while (ret >= 0 && check_reply(&settings.dest.ip, &sender, packet, buffer + sizeof(struct iphdr), packet_size, ret)); - - if (ret >= (ssize_t) (sizeof(struct icmphdr) + sizeof(struct iphdr))) - { - if (((struct icmphdr *) (buffer + sizeof(struct iphdr)))->type == 0) + + struct icmphdr *recv_hdr = (struct icmphdr *) (buffer + sizeof(struct iphdr)); + recv_size -= sizeof(struct iphdr); + + if (check_reply(&settings.dest.ip, &sender, (struct icmphdr *) packet, recv_hdr, packet_size, recv_size)) + continue; + + if (recv_hdr->type == 0) stats.packets_received++; print_recv(&settings, buffer, &start, &stop, &sender); - } - - double interval = get_interval(&start, &stop); - if (interval < 1000) - usleep((1000 - interval) * 1e3); - + double interval = get_interval(&start, &stop); + if (interval < 1000) + usleep((1000 - interval) * 1e3); + break; + } if (packet_update(packet, settings.payload_size)) - goto error3; + goto error3; } free(packet);