diff --git a/includes/ping.h b/includes/ping.h index 9125063..57f619c 100644 --- a/includes/ping.h +++ b/includes/ping.h @@ -15,6 +15,7 @@ extern int tx_count; extern int rx_count; extern char *address; extern double *times; +extern int sock; typedef struct { bool verbose; @@ -34,14 +35,15 @@ typedef struct { #define DEFAULT_COUNT -1 #define DEFAULT_LINGER 10 -int send_ping(int socket, struct sockaddr_in *dest, args_t *args); -int init_socket(args_t *args); +int send_ping(int socket, struct sockaddr_in *dest, options_t opt); +int init_socket(options_t opt); void init_packet(char *buf, int seq, uint32_t size); int send_icmp(int socket, char *buf, struct sockaddr_in *addr, uint32_t size); int receive_icmp(int socket, char *buf, uint32_t size, struct sockaddr_in *addr); void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq, struct timeval *tv_start, struct timeval *tv_end); +int ping(args_t *args); // Internal unsigned short get_checksum(unsigned short *addr, int count); diff --git a/includes/utils.h b/includes/utils.h index 0361136..210489f 100644 --- a/includes/utils.h +++ b/includes/utils.h @@ -28,3 +28,5 @@ double get_stddev_rtt(void); bool check_for_timeout(struct timeval start, options_t opt); void print_stats(void); + +bool check_for_count(options_t opt); diff --git a/src/main.c b/src/main.c index c1e4fb3..212bd44 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,7 @@ int handle_options(args_t *args) { print_help(); return EXIT_SUCCESS; } else { - return send_ping(args); + return ping(args); } } diff --git a/src/ping/init_ping.c b/src/ping/init_ping.c index d40c378..9d8b97d 100644 --- a/src/ping/init_ping.c +++ b/src/ping/init_ping.c @@ -17,7 +17,7 @@ int init_socket(options_t opt) { int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sock < 0) { fprintf(stderr, - "%s: can't create socket maybe try in root next time :D", + "%s: can't create socket maybe try in root next time :D\n", exec_name); return -1; } @@ -56,7 +56,7 @@ void init_packet(char *buf, int seq, uint32_t size) { packet->icmp_type = ICMP_ECHO; packet->icmp_code = 0; - packet->icmp_id = getpid() & 0xFFFF; + packet->icmp_id = (getpid() & 0xffff); packet->icmp_seq = seq; memset(buf + sizeof(struct icmphdr), 0x42, size - sizeof(struct icmphdr)); diff --git a/src/ping/send_icmp.c b/src/ping/send_icmp.c index ae7b59f..b488c80 100644 --- a/src/ping/send_icmp.c +++ b/src/ping/send_icmp.c @@ -1,15 +1,15 @@ -#include #include #include +#include #include -#include #include #include #include #include #include #include +#include #include #include @@ -18,7 +18,7 @@ int send_icmp(int socket, char *buf, struct sockaddr_in *addr, uint32_t size) { (struct sockaddr *)addr, sizeof(*addr)); if (bytes_send < 0) { - fprintf(stderr, "sendto failed can't send packet"); + fprintf(stderr, "sendto failed can't send packet\n"); return -1; } return bytes_send; @@ -40,7 +40,8 @@ void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq, struct icmp *icmp = (struct icmp *)(buf + len); if (icmp->icmp_type == ICMP_ECHOREPLY && - icmp->icmp_type == (getpid() & 0xFFFF)) { + icmp->icmp_id == (getpid() & 0xffff)) { + rx_count++; double rtt = (tv_end->tv_sec - tv_start->tv_sec) / 1000.0 + @@ -48,7 +49,7 @@ void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq, append_time(rtt); - printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f", bytes - len, + printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f\n", bytes - len, inet_ntoa(addr->sin_addr), icmp->icmp_seq, ip->ip_ttl, rtt); } } diff --git a/src/ping/send_ping.c b/src/ping/send_ping.c index eb65294..d59a376 100644 --- a/src/ping/send_ping.c +++ b/src/ping/send_ping.c @@ -1,7 +1,7 @@ #include "help.h" -#include #include #include +#include #include #include @@ -17,9 +17,15 @@ #include #include +char *address = NULL; +int sock = -1; + void sigint(int sig) { (void)sig; + close(sock); + print_stats(); + exit(EXIT_SUCCESS); } @@ -37,8 +43,7 @@ options_t init_opt(args_t *args) { return opt; } -int send_ping(int socket, struct sockaddr_in *dest, args_t *args) { - options_t opt = init_opt(args); +int send_ping(int socket, struct sockaddr_in *dest, options_t opt) { struct timeval loop_start, loop_end; struct timeval pkt_start, pkt_end; struct sockaddr_in addr; @@ -52,42 +57,50 @@ int send_ping(int socket, struct sockaddr_in *dest, args_t *args) { init_packet(sendbuf, tx_count++, opt.size); gettimeofday(&pkt_start, NULL); bytes = send_icmp(socket, sendbuf, &addr, opt.size); - sleep(1); - if (check_for_timeout(loop_start, opt)) { - print_stats(); - return EXIT_SUCCESS; - } bytes = receive_icmp(socket, recvbuf, sizeof(recvbuf), &addr); gettimeofday(&pkt_end, NULL); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("Request timeout for icmp_seq=%d\n", tx_count - 1); } else { - fprintf(stderr, "recv failed"); + fprintf(stderr, "recv failed\n"); } } else process_icmp(recvbuf, bytes, &addr, tx_count - 1, &pkt_end, &pkt_end); + if (check_for_count(opt)) { + print_stats(); + return EXIT_SUCCESS; + } + sleep(opt.interval); + if (check_for_timeout(loop_start, opt)) { + print_stats(); + return EXIT_SUCCESS; + } } return EXIT_SUCCESS; } int ping(args_t *args) { - int ret; + int ret; + options_t opt = init_opt(args); + signal(SIGINT, &sigint); for (int i = 0; args->hosts[i] != NULL; i++) { + address = args->hosts[i]; struct sockaddr_in addr; + if (inet_pton(AF_INET, args->hosts[i], &addr) <= 0) { - fprintf(stderr, "Bar address: %s\n", args->hosts[i]); + fprintf(stderr, "Bad address: %s\n", args->hosts[i]); return EXIT_FAILURE; } - int socket = init_socket(args); - if (socket < 0) { + sock = init_socket(opt); + if (sock < 0) { + break; } - printf("PING %s (%s): %d data bytes\n", args->hosts[i], args->hosts[i], - args->opts[SIZE]); + printf("PING %s (%s): %d data bytes\n", address, address, opt.size); - ret = send_ping(socket, &addr, args); + ret = send_ping(sock, &addr, opt); } return ret; } diff --git a/src/utils.c b/src/utils.c index bb1c2d7..fc927b3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,8 +1,8 @@ #include -#include #include #include +#include #include void append_time(double time) { @@ -39,6 +39,9 @@ double get_avg_rtt(void) { avg += times[i]; } avg = avg / rx_count; + if (avg < 0) { + avg = 0; + } return avg; } @@ -58,10 +61,18 @@ bool check_for_timeout(struct timeval start, options_t opt) { return false; } -void print_stats(void) { - printf("--- %s ping statistics ---", address); - printf("%d packets transmitted, %d packets received, %f%% packet loss", +void print_stats(void) { + printf("--- %s ping statistics ---\n", address); + printf("%d packets transmitted, %d packets received, %.0f%% packet loss\n", tx_count, rx_count, (tx_count - rx_count / 2.0) * 100); - printf("round-trip min/avg/max/stddev = %f/%f/%f/%f", get_min_rtt(), - get_avg_rtt(), get_max_rtt(), get_stddev_rtt()); + printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f\n", + get_min_rtt(), get_avg_rtt(), get_max_rtt(), get_stddev_rtt()); +} + +bool check_for_count(options_t opt) { + if (opt.count == -1) + return false; + if (tx_count > opt.count) + return true; + return false; }