stddev
This commit is contained in:
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Project Meta Settings
|
# Project Meta Settings
|
||||||
NAME = ft_ping
|
NAME = ft_ping
|
||||||
RELEASE_TYPE = Release
|
RELEASE_TYPE = Debug
|
||||||
CURRENT_DIR = ${CURDIR}
|
CURRENT_DIR = ${CURDIR}
|
||||||
|
|
||||||
# Project Build Output Settings
|
# Project Build Output Settings
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <netinet/ip_icmp.h>
|
#include <netinet/ip_icmp.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
92
srcs/main.c
92
srcs/main.c
@ -1,5 +1,21 @@
|
|||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠉⠀⢻⣿⣿⣿⣿⣿⣿⡿⠁⠀⠙⢿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠈⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠿⠛⠛⠛⠛⠿⣿⠀⠀⠀⠀⢀⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⣀⣤⡀⠀⠀⠀⠀⣀⡀⠀⠀⠀⢀⠀⢸⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣴⣿⣿⠇⠀⠀⢠⣾⣿⣿⣆⠀⠀⠀⠀⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢡⣿⣿⣿⠀⠀⢀⣿⣿⣿⣿⣿⠀⠀⠀⢸⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢸⣿⡿⠃⠀⠀⢸⣿⣿⣿⣿⠏⠀⠀⠀⡘⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠈⠀⠈⠭⠀⠈⠛⠿⠛⠋⠀⠀⠀⠀⠠⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡑⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠈⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠈⢃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿
|
||||||
|
// ⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿
|
||||||
|
|
||||||
const char* argp_program_version = "ft_ping 1.0";
|
const char* argp_program_version = "ft_ping 1.0";
|
||||||
const char* argp_program_bug_address = "<jrathelo@student.42nice.fr>";
|
const char* argp_program_bug_address = "<jrathelo@student.42nice.fr>";
|
||||||
static char doc[] = "Send ICMP ECHO_REQUEST packets to network hosts.\vMandatory or optional arguments to long options "
|
static char doc[] = "Send ICMP ECHO_REQUEST packets to network hosts.\vMandatory or optional arguments to long options "
|
||||||
@ -54,10 +70,6 @@ struct timespec sendt;
|
|||||||
unsigned long xmit = 0;
|
unsigned long xmit = 0;
|
||||||
unsigned long recvd = 0;
|
unsigned long recvd = 0;
|
||||||
|
|
||||||
double min = 0;
|
|
||||||
double max = 0;
|
|
||||||
double avg = 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;
|
||||||
unsigned int sum = 0;
|
unsigned int sum = 0;
|
||||||
@ -88,7 +100,7 @@ void send_ping() {
|
|||||||
struct timeval tmp_tv;
|
struct timeval tmp_tv;
|
||||||
gettimeofday(&tmp_tv, NULL);
|
gettimeofday(&tmp_tv, NULL);
|
||||||
|
|
||||||
memcpy(packet.msg, &tmp_tv, sizeof(tmp_tv));
|
memcpy(packet.msg, &tmp_tv, sizeof(struct timeval));
|
||||||
for (long unsigned i = 0; i < sizeof(packet.msg) - sizeof(tmp_tv); ++i) {
|
for (long unsigned i = 0; i < sizeof(packet.msg) - sizeof(tmp_tv); ++i) {
|
||||||
packet.msg[sizeof(tmp_tv) + i] = (char)i;
|
packet.msg[sizeof(tmp_tv) + i] = (char)i;
|
||||||
}
|
}
|
||||||
@ -108,18 +120,36 @@ void sig_handler(int sig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double nabs(double a) { return (a < 0) ? -a : a; }
|
||||||
|
|
||||||
|
double nsqrt(double a, double prec) {
|
||||||
|
double b;
|
||||||
|
double c;
|
||||||
|
|
||||||
|
if (a < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (a < prec) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
c = a / 2;
|
||||||
|
do {
|
||||||
|
b = c;
|
||||||
|
c = (b + a / b) / 2;
|
||||||
|
} while (nabs(c - b) > prec);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
struct arguments arguments;
|
struct arguments arguments;
|
||||||
int timeout = 3000;
|
int timeout = 3000;
|
||||||
struct timespec recvt;
|
struct timespec recvt;
|
||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
float min;
|
double min = INT32_MAX;
|
||||||
float max;
|
double max = 0;
|
||||||
float avg;
|
double avg = 0;
|
||||||
|
double stddev = 0;
|
||||||
min = INT32_MAX;
|
|
||||||
max = 0;
|
|
||||||
avg = 0;
|
|
||||||
|
|
||||||
arguments.verbose = 0;
|
arguments.verbose = 0;
|
||||||
arguments.ttl = 64;
|
arguments.ttl = 64;
|
||||||
@ -151,20 +181,22 @@ int main(int argc, char** argv) {
|
|||||||
fds[0].fd = sock;
|
fds[0].fd = sock;
|
||||||
fds[0].events = POLLIN;
|
fds[0].events = POLLIN;
|
||||||
|
|
||||||
struct sigaction sig_handle;
|
struct sigaction sig_handle = {0};
|
||||||
|
|
||||||
sig_handle.sa_handler = sig_handler;
|
sig_handle.sa_handler = sig_handler;
|
||||||
|
|
||||||
sigaction(SIGINT, &sig_handle, 0);
|
sigaction(SIGINT, &sig_handle, 0);
|
||||||
sigaction(SIGALRM, &sig_handle, 0);
|
sigaction(SIGALRM, &sig_handle, 0);
|
||||||
|
|
||||||
|
printf("PING %s (%s): %ld data bytes\n", arguments.args[0], arguments.args[0], 64 - sizeof(struct icmphdr));
|
||||||
|
|
||||||
send_ping();
|
send_ping();
|
||||||
|
|
||||||
while (!stop) {
|
while (!stop) {
|
||||||
int ret = poll(fds, 1, timeout);
|
int ret = poll(fds, 1, timeout);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (fds[0].revents & POLLIN) {
|
if (fds[0].revents & POLLIN) {
|
||||||
char buf[100];
|
char buf[100] = {0};
|
||||||
|
|
||||||
long int bytes_received = recvfrom(sock, buf, 100, 0, NULL, NULL);
|
long int bytes_received = recvfrom(sock, buf, 100, 0, NULL, NULL);
|
||||||
|
|
||||||
@ -173,34 +205,56 @@ int main(int argc, char** argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
pause();
|
||||||
|
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;
|
||||||
struct icmphdr* icmp_reply = (struct icmphdr*)(buf + (ip_header->ip_hl << 2));
|
struct icmphdr* icmp_reply = (struct icmphdr*)(buf + (ip_header->ip_hl << 2));
|
||||||
|
|
||||||
|
int old_checksum = icmp_reply->checksum;
|
||||||
|
icmp_reply->checksum = 0;
|
||||||
|
|
||||||
|
if (old_checksum != calc_checksum(icmp_reply, bytes_received - (ip_header->ip_hl << 2))) {
|
||||||
|
dprintf(STDERR_FILENO, "checksum mismatch from %s\n", arguments.args[0]);
|
||||||
|
pause();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
icmp_reply->checksum = old_checksum;
|
||||||
|
|
||||||
float tmp =
|
float tmp =
|
||||||
((recvt.tv_sec * 1000 + recvt.tv_nsec / 1000000) - (sendt.tv_sec * 1000 + sendt.tv_nsec / 1000000));
|
((recvt.tv_sec * 1000 + recvt.tv_nsec / 1000000) - (sendt.tv_sec * 1000 + sendt.tv_nsec / 1000000));
|
||||||
tmp += ((float)((recvt.tv_nsec - sendt.tv_nsec) % 1000000) / 1000000.0);
|
tmp += ((float)((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, arguments.args[0],
|
printf("%zd bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms \n", bytes_received - sizeof(struct ip),
|
||||||
icmp_reply->un.echo.sequence, ip_header->ip_ttl, tmp);
|
arguments.args[0], icmp_reply->un.echo.sequence + 1, 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));
|
||||||
avg += tmp;
|
avg += tmp;
|
||||||
|
stddev += tmp * tmp;
|
||||||
recvd++;
|
recvd++;
|
||||||
}
|
}
|
||||||
} 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 {
|
|
||||||
perror("Poll failed");
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// perror("Poll failed");
|
||||||
|
// }
|
||||||
|
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
|
fflush(stdout);
|
||||||
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
||||||
printf("%zu packets transmitted, %zu packets received, %zu%% packet loss\n", xmit, recvd,
|
printf("%zu packets transmitted, %zu packets received, %zu%% packet loss\n", xmit, recvd,
|
||||||
(xmit - recvd) / xmit * 100);
|
(xmit - recvd) / xmit * 100);
|
||||||
printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%%.3f ms\n", min, max, avg / recvd);
|
avg /= recvd;
|
||||||
|
stddev = stddev / recvd - 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