#include "help.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char *address = NULL; int sock = -1; void sigint(int sig) { (void)sig; close(sock); print_stats(); exit(EXIT_SUCCESS); } options_t init_opt(args_t *args) { options_t opt; verbose = args->opts[VERBOSE] != false ? true : DEFAULT_VERBOSE; opt.count = args->arg[COUNT] != -1 ? args->arg[COUNT] : DEFAULT_COUNT; opt.size = args->arg[SIZE] != -1 ? args->arg[SIZE] : DEFAULT_SIZE; opt.timeout = args->arg[TIMEOUT] != -1 ? args->arg[TIMEOUT] : DEFAULT_TIMEOUT; opt.interval = args->arg[INTERVAL] != -1 ? args->arg[INTERVAL] : DEFAULT_INTERVAL; opt.linger = args->arg[LINGER] != -1 ? args->arg[LINGER] : DEFAULT_LINGER; return opt; } 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 = *dest; int bytes; char sendbuf[opt.size]; char recvbuf[opt.size + sizeof(struct ip)]; gettimeofday(&loop_start, 0); while (727) { int seq = tx_count; init_packet(sendbuf, seq, opt.size); gettimeofday(&pkt_start, NULL); bytes = send_icmp(socket, sendbuf, &addr, opt.size); tx_count++; bytes = receive_icmp(socket, recvbuf, sizeof(recvbuf), &addr); gettimeofday(&pkt_end, NULL); if (bytes <= 0) { if (verbose) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("Request timeout for icmp_seq=%d\n", seq); } else { fprintf(stderr, "recv failed: %s\n", strerror(errno)); } } } else process_icmp(recvbuf, bytes, &addr, seq, &pkt_start, &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; 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; struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = IPPROTO_ICMP; int status = getaddrinfo(address, NULL, &hints, &res); if (status != 0) { fprintf(stderr, "Bad address: %s\n", address); ret = EXIT_FAILURE; continue; } memcpy(&addr, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sock = init_socket(opt); if (sock < 0) { break; } printf("PING %s (%s): %d data bytes\n", address, address, opt.size); ret = send_ping(sock, &addr, opt); } return ret; }