「🏗️」 wip: don't understand whats going on
This commit is contained in:
@ -15,6 +15,7 @@ extern int tx_count;
|
|||||||
extern int rx_count;
|
extern int rx_count;
|
||||||
extern char *address;
|
extern char *address;
|
||||||
extern double *times;
|
extern double *times;
|
||||||
|
extern int sock;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
@ -34,14 +35,15 @@ typedef struct {
|
|||||||
#define DEFAULT_COUNT -1
|
#define DEFAULT_COUNT -1
|
||||||
#define DEFAULT_LINGER 10
|
#define DEFAULT_LINGER 10
|
||||||
|
|
||||||
int send_ping(int socket, struct sockaddr_in *dest, args_t *args);
|
int send_ping(int socket, struct sockaddr_in *dest, options_t opt);
|
||||||
int init_socket(args_t *args);
|
int init_socket(options_t opt);
|
||||||
void init_packet(char *buf, int seq, uint32_t size);
|
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 send_icmp(int socket, char *buf, struct sockaddr_in *addr, uint32_t size);
|
||||||
int receive_icmp(int socket, char *buf, uint32_t size,
|
int receive_icmp(int socket, char *buf, uint32_t size,
|
||||||
struct sockaddr_in *addr);
|
struct sockaddr_in *addr);
|
||||||
void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq,
|
void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq,
|
||||||
struct timeval *tv_start, struct timeval *tv_end);
|
struct timeval *tv_start, struct timeval *tv_end);
|
||||||
|
int ping(args_t *args);
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
unsigned short get_checksum(unsigned short *addr, int count);
|
unsigned short get_checksum(unsigned short *addr, int count);
|
||||||
|
@ -28,3 +28,5 @@ double get_stddev_rtt(void);
|
|||||||
bool check_for_timeout(struct timeval start, options_t opt);
|
bool check_for_timeout(struct timeval start, options_t opt);
|
||||||
|
|
||||||
void print_stats(void);
|
void print_stats(void);
|
||||||
|
|
||||||
|
bool check_for_count(options_t opt);
|
||||||
|
@ -34,7 +34,7 @@ int handle_options(args_t *args) {
|
|||||||
print_help();
|
print_help();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
return send_ping(args);
|
return ping(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ int init_socket(options_t opt) {
|
|||||||
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
fprintf(stderr,
|
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);
|
exec_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ void init_packet(char *buf, int seq, uint32_t size) {
|
|||||||
|
|
||||||
packet->icmp_type = ICMP_ECHO;
|
packet->icmp_type = ICMP_ECHO;
|
||||||
packet->icmp_code = 0;
|
packet->icmp_code = 0;
|
||||||
packet->icmp_id = getpid() & 0xFFFF;
|
packet->icmp_id = (getpid() & 0xffff);
|
||||||
packet->icmp_seq = seq;
|
packet->icmp_seq = seq;
|
||||||
|
|
||||||
memset(buf + sizeof(struct icmphdr), 0x42, size - sizeof(struct icmphdr));
|
memset(buf + sizeof(struct icmphdr), 0x42, size - sizeof(struct icmphdr));
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#include <utils.h>
|
|
||||||
#include <opt_parse.h>
|
#include <opt_parse.h>
|
||||||
#include <ping.h>
|
#include <ping.h>
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip_icmp.h>
|
#include <netinet/ip_icmp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ int send_icmp(int socket, char *buf, struct sockaddr_in *addr, uint32_t size) {
|
|||||||
(struct sockaddr *)addr, sizeof(*addr));
|
(struct sockaddr *)addr, sizeof(*addr));
|
||||||
|
|
||||||
if (bytes_send < 0) {
|
if (bytes_send < 0) {
|
||||||
fprintf(stderr, "sendto failed can't send packet");
|
fprintf(stderr, "sendto failed can't send packet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return bytes_send;
|
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);
|
struct icmp *icmp = (struct icmp *)(buf + len);
|
||||||
|
|
||||||
if (icmp->icmp_type == ICMP_ECHOREPLY &&
|
if (icmp->icmp_type == ICMP_ECHOREPLY &&
|
||||||
icmp->icmp_type == (getpid() & 0xFFFF)) {
|
icmp->icmp_id == (getpid() & 0xffff)) {
|
||||||
|
|
||||||
rx_count++;
|
rx_count++;
|
||||||
|
|
||||||
double rtt = (tv_end->tv_sec - tv_start->tv_sec) / 1000.0 +
|
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);
|
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);
|
inet_ntoa(addr->sin_addr), icmp->icmp_seq, ip->ip_ttl, rtt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "help.h"
|
#include "help.h"
|
||||||
#include <cerrno>
|
|
||||||
#include <opt_parse.h>
|
#include <opt_parse.h>
|
||||||
#include <ping.h>
|
#include <ping.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -17,9 +17,15 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
char *address = NULL;
|
||||||
|
int sock = -1;
|
||||||
|
|
||||||
void sigint(int sig) {
|
void sigint(int sig) {
|
||||||
(void)sig;
|
(void)sig;
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
print_stats();
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,8 +43,7 @@ options_t init_opt(args_t *args) {
|
|||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_ping(int socket, struct sockaddr_in *dest, args_t *args) {
|
int send_ping(int socket, struct sockaddr_in *dest, options_t opt) {
|
||||||
options_t opt = init_opt(args);
|
|
||||||
struct timeval loop_start, loop_end;
|
struct timeval loop_start, loop_end;
|
||||||
struct timeval pkt_start, pkt_end;
|
struct timeval pkt_start, pkt_end;
|
||||||
struct sockaddr_in addr;
|
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);
|
init_packet(sendbuf, tx_count++, opt.size);
|
||||||
gettimeofday(&pkt_start, NULL);
|
gettimeofday(&pkt_start, NULL);
|
||||||
bytes = send_icmp(socket, sendbuf, &addr, opt.size);
|
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);
|
bytes = receive_icmp(socket, recvbuf, sizeof(recvbuf), &addr);
|
||||||
gettimeofday(&pkt_end, NULL);
|
gettimeofday(&pkt_end, NULL);
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
printf("Request timeout for icmp_seq=%d\n", tx_count - 1);
|
printf("Request timeout for icmp_seq=%d\n", tx_count - 1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "recv failed");
|
fprintf(stderr, "recv failed\n");
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
process_icmp(recvbuf, bytes, &addr, tx_count - 1, &pkt_end,
|
process_icmp(recvbuf, bytes, &addr, tx_count - 1, &pkt_end,
|
||||||
&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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ping(args_t *args) {
|
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++) {
|
for (int i = 0; args->hosts[i] != NULL; i++) {
|
||||||
|
address = args->hosts[i];
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, args->hosts[i], &addr) <= 0) {
|
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;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
int socket = init_socket(args);
|
sock = init_socket(opt);
|
||||||
if (socket < 0) {
|
if (sock < 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("PING %s (%s): %d data bytes\n", args->hosts[i], args->hosts[i],
|
printf("PING %s (%s): %d data bytes\n", address, address, opt.size);
|
||||||
args->opts[SIZE]);
|
|
||||||
|
|
||||||
ret = send_ping(socket, &addr, args);
|
ret = send_ping(sock, &addr, opt);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
23
src/utils.c
23
src/utils.c
@ -1,8 +1,8 @@
|
|||||||
#include <ping.h>
|
#include <ping.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
void append_time(double time) {
|
void append_time(double time) {
|
||||||
@ -39,6 +39,9 @@ double get_avg_rtt(void) {
|
|||||||
avg += times[i];
|
avg += times[i];
|
||||||
}
|
}
|
||||||
avg = avg / rx_count;
|
avg = avg / rx_count;
|
||||||
|
if (avg < 0) {
|
||||||
|
avg = 0;
|
||||||
|
}
|
||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,10 +61,18 @@ bool check_for_timeout(struct timeval start, options_t opt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_stats(void) {
|
void print_stats(void) {
|
||||||
printf("--- %s ping statistics ---", address);
|
printf("--- %s ping statistics ---\n", address);
|
||||||
printf("%d packets transmitted, %d packets received, %f%% packet loss",
|
printf("%d packets transmitted, %d packets received, %.0f%% packet loss\n",
|
||||||
tx_count, rx_count, (tx_count - rx_count / 2.0) * 100);
|
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(),
|
printf("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f\n",
|
||||||
get_avg_rtt(), get_max_rtt(), get_stddev_rtt());
|
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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user