fixed ctrl+c not working instantly, fixed accidental double capture of icmp echo req on 0.0.0.0, fixed some error messages showing when not needed
This commit is contained in:
@ -17,6 +17,8 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
struct arguments {
|
struct arguments {
|
||||||
char* args[1];
|
char* args[1];
|
||||||
|
41
srcs/main.c
41
srcs/main.c
@ -67,9 +67,9 @@ static struct sockaddr_in destination = {0};
|
|||||||
|
|
||||||
struct timespec sendt;
|
struct timespec sendt;
|
||||||
|
|
||||||
unsigned long xmit = 0;
|
volatile unsigned long xmit = 0;
|
||||||
unsigned long recvd = 0;
|
volatile unsigned long recvd = 0;
|
||||||
unsigned long rept = 0;
|
volatile unsigned long rept = 0;
|
||||||
|
|
||||||
uint16_t calc_checksum(void* b, size_t len) {
|
uint16_t calc_checksum(void* b, size_t len) {
|
||||||
unsigned short* buf = b;
|
unsigned short* buf = b;
|
||||||
@ -182,9 +182,9 @@ int main(int argc, char** argv) {
|
|||||||
inet_ntop(res->ai_family, &destination.sin_addr, ip_str, INET_ADDRSTRLEN);
|
inet_ntop(res->ai_family, &destination.sin_addr, ip_str, INET_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct protoent *proto = getprotobyname("icmp");
|
struct protoent* proto = getprotobyname("icmp");
|
||||||
if (!proto) {
|
if (!proto) {
|
||||||
dprintf (STDERR_FILENO, "%s: unknown protocol icmp.\n", argv[0]);
|
dprintf(STDERR_FILENO, "%s: unknown protocol icmp.\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,22 +238,30 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
if ((size_t)bytes_received < sizeof(struct ip) + sizeof(struct icmphdr) + 8) {
|
if ((size_t)bytes_received < sizeof(struct ip) + sizeof(struct icmphdr) + 8) {
|
||||||
dprintf(STDERR_FILENO, "packet too short (%ld bytes) from %s\n", bytes_received, arguments.args[0]);
|
dprintf(STDERR_FILENO, "packet too short (%ld bytes) from %s\n", bytes_received, arguments.args[0]);
|
||||||
pause();
|
if (!stop)
|
||||||
|
pause();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &recvt);
|
clock_gettime(CLOCK_MONOTONIC, &recvt);
|
||||||
|
|
||||||
struct ip* ip_header = (struct ip*)buf;
|
struct ip* ip_header = (struct ip*)buf;
|
||||||
|
|
||||||
|
char strip[INET_ADDRSTRLEN] = {0};
|
||||||
|
inet_ntop(AF_INET, &(ip_header->ip_src.s_addr), strip, INET_ADDRSTRLEN);
|
||||||
struct icmphdr* icmp_reply = (struct icmphdr*)(buf + (ip_header->ip_hl << 2));
|
struct icmphdr* icmp_reply = (struct icmphdr*)(buf + (ip_header->ip_hl << 2));
|
||||||
|
if (icmp_reply->type == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int old_checksum = icmp_reply->checksum;
|
int old_checksum = icmp_reply->checksum;
|
||||||
icmp_reply->checksum = 0;
|
icmp_reply->checksum = 0;
|
||||||
|
|
||||||
if (old_checksum != calc_checksum(icmp_reply, bytes_received - (ip_header->ip_hl << 2))) {
|
if (old_checksum != calc_checksum(icmp_reply, bytes_received - (ip_header->ip_hl << 2))) {
|
||||||
dprintf(STDERR_FILENO, "checksum mismatch from %s\n", ip_str);
|
dprintf(STDERR_FILENO, "checksum mismatch from %s\n", strip);
|
||||||
rept++;
|
rept++;
|
||||||
pause();
|
if (!stop)
|
||||||
|
pause();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +272,7 @@ int main(int argc, char** argv) {
|
|||||||
tmp += ((double)((recvt.tv_nsec - sendt.tv_nsec) % 1000000) / 1000000.0);
|
tmp += ((double)((recvt.tv_nsec - sendt.tv_nsec) % 1000000) / 1000000.0);
|
||||||
|
|
||||||
printf("%zd bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms \n", bytes_received - sizeof(struct ip),
|
printf("%zd bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms \n", bytes_received - sizeof(struct ip),
|
||||||
ip_str, icmp_reply->un.echo.sequence, ip_header->ip_ttl, tmp);
|
strip, icmp_reply->un.echo.sequence, ip_header->ip_ttl, tmp);
|
||||||
|
|
||||||
min = (((min) < (tmp)) ? (min) : (tmp));
|
min = (((min) < (tmp)) ? (min) : (tmp));
|
||||||
max = (((max) > (tmp)) ? (max) : (tmp));
|
max = (((max) > (tmp)) ? (max) : (tmp));
|
||||||
@ -279,10 +287,13 @@ int main(int argc, char** argv) {
|
|||||||
} else if (ret == 0) {
|
} else if (ret == 0) {
|
||||||
printf("No reply received within the timeout period\n");
|
printf("No reply received within the timeout period\n");
|
||||||
} else {
|
} else {
|
||||||
perror("Poll failed");
|
if (errno != EINTR) {
|
||||||
|
perror("Poll failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pause();
|
if (!stop)
|
||||||
|
pause();
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
||||||
@ -298,8 +309,10 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
double total = recvd + rept;
|
double total = recvd + rept;
|
||||||
avg /= total;
|
if (total > 0) {
|
||||||
stddev = stddev / total - avg * avg;
|
avg /= total;
|
||||||
printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n", min, max, avg, nsqrt(stddev, 0.0005));
|
stddev = stddev / total - avg * avg;
|
||||||
|
printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n", min, max, avg, nsqrt(stddev, 0.0005));
|
||||||
|
}
|
||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
Reference in New Issue
Block a user