From c90606706babfef1554873ba8cb0a092d815e2bf Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Mon, 13 Nov 2017 15:33:42 +0100 Subject: [PATCH] stuff --- ping/includes/ping.h | 21 ++++++++ ping/srcs/ping.c | 112 +++++++++++++++++++++---------------------- 2 files changed, 75 insertions(+), 58 deletions(-) diff --git a/ping/includes/ping.h b/ping/includes/ping.h index 590698e2..9b3cfb06 100644 --- a/ping/includes/ping.h +++ b/ping/includes/ping.h @@ -27,6 +27,27 @@ # define PACKETSIZE 64 +typedef struct s_ping t_ping; + +struct s_ping +{ + pid_t pid; + t_rs rs; + int pkt_sent; + int pkt_recv; + int sock; + struct addrinfo *sa; + union + { + char ip4[INET_ADDRSTRLEN]; + char ip6[INET6_ADDRSTRLEN]; + } ip; +#define ip4 ip.ip4 +#define ip6 ip.ip6 +}; + +extern t_ping g_ping; + struct s_packet { struct icmp hdr; diff --git a/ping/srcs/ping.c b/ping/srcs/ping.c index c3a45e2d..6babb3be 100644 --- a/ping/srcs/ping.c +++ b/ping/srcs/ping.c @@ -15,86 +15,78 @@ #define TIME_END 1 #define TIME_TRIPTIME 2 -int g_pid = -1; -int g_pkt_rec = 0; -char g_domain[256]; -struct s_stats g_rs; +t_ping g_ping = +{ + .pid = -1, + .pkt_sent = -1, + .pkt_recv = 0, +}; -void display(void *buf, int bytes, struct sockaddr_in *addr) +void display(void *buf, int bytes, struct sockaddr_in *addr) { struct ip *ip; struct icmp *icmp; struct s_packet *pkt; int hlen; double triptime; + char strbuf[INET_ADDRSTRLEN]; ip = buf; (void)bytes; hlen = ip->ip_hl << 2; pkt = (struct s_packet*)(buf + hlen); icmp = &pkt->hdr; - if (icmp->icmp_id != g_pid) + if (icmp->icmp_id != g_ping.pid) return ; triptime = time_milli() - *(double*)&pkt->msg; - rs_push(triptime); - g_pkt_rec++; + rs_push(&g_ping.rs, triptime); + g_ping.pkt_recv++; printf("%d bytes from %s: icmp_seq=%d ttl=%i time=%.3f ms\n", ip->ip_len, - inet_ntop(AF_INET, &(addr->sin_addr), g_domain, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &(addr->sin_addr), strbuf, INET_ADDRSTRLEN), icmp->icmp_seq, ip->ip_ttl, triptime); } -void ping(struct sockaddr_in *addr) +void ping(int signo) { - int sd; - int cnt; struct s_packet pkt; double epoch; - if ((sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) - return (perror("sender socket")); - if (setsockopt(sd, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0) - perror("set TTL option"); - cnt = 0; - while (1) - { - bzero(&pkt, sizeof(pkt)); - pkt.hdr.icmp_type = ICMP_ECHO; - pkt.hdr.icmp_id = g_pid; - pkt.hdr.icmp_seq = cnt++; - epoch = time_milli(); - ft_memcpy(pkt.msg, (void*)&epoch, sizeof(epoch)); - pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt)); - if (sendto(sd, &pkt, sizeof(pkt), 0, - (struct sockaddr*)addr, sizeof(*addr)) <= 0) - return (perror("sendto")); - sleep(1); - } + (void)signo; + bzero(&pkt, sizeof(pkt)); + pkt.hdr.icmp_type = ICMP_ECHO; + pkt.hdr.icmp_id = g_ping.pid; + pkt.hdr.icmp_seq = ++g_ping.pkt_sent; + epoch = time_milli(); + ft_memcpy(pkt.msg, (void*)&epoch, sizeof(epoch)); + pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt)); + sendto(g_ping.sock, &pkt, sizeof(pkt), 0, g_ping.sa->ai_addr, + sizeof(struct sockaddr)); } -void stats_recap(int signo) +void stats_recap(int signo) { double loss; (void)signo; - rs_calcmore(); - loss = FT_PCT(g_pkt_rec, g_rs.count); - printf("\n--- %s ping statistics ---", g_domain); + rs_final(&g_ping.rs); + loss = FT_PCT(g_ping.pkt_recv, g_ping.pkt_sent); + printf("\n--- %s ping statistics ---", g_ping.ip4); printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss", - g_rs.count, g_pkt_rec, loss); + g_ping.rs.count, g_ping.pkt_recv, loss); printf("\nround-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms", - g_rs.min, g_rs.avg, g_rs.max, g_rs.stdev); + g_ping.rs.min, g_ping.rs.avg, g_ping.rs.max, g_ping.rs.stdev); + freeaddrinfo(g_ping.sa); exit(0); } -struct addrinfo *resolve_host(char *hostname) +int resolve_host(char *hostname, t_ping *ping) { struct addrinfo *result; struct addrinfo hints; - struct sockaddr_in *addr; memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; + hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags |= AI_CANONNAME; if (getaddrinfo(hostname, NULL, &hints, &result) != 0) @@ -102,35 +94,39 @@ struct addrinfo *resolve_host(char *hostname) perror("getaddrinfo"); exit(1); } - addr = (struct sockaddr_in*)result->ai_addr; - inet_ntop(AF_INET, &(addr->sin_addr), g_domain, INET_ADDRSTRLEN); - if (result->ai_canonname) - ft_strcpy(g_domain, result->ai_canonname); - return (result); + ping->sa = result; + inet_ntop(AF_INET, &(((struct sockaddr_in*)ping->sa->ai_addr)->sin_addr), ping->ip4, INET_ADDRSTRLEN); + return (0); } -int main(int ac, char **av) +int main(int ac, char **av) { - struct addrinfo *result; - if (ac != 2) { ft_usage("%s \n", av[0]); exit(1); } - g_pid = getpid(); - result = resolve_host(av[1]); - if (result->ai_canonname) + resolve_host(av[1], &g_ping); + if (g_ping.sa->ai_canonname) printf("PING %s (%s): %i data bytes\n", - result->ai_canonname, g_domain, PACKETSIZE); + g_ping.sa->ai_canonname, g_ping.ip4, PACKETSIZE); else - printf("PING %s: %i data bytes\n", g_domain, PACKETSIZE); - if (fork() == 0) + printf("PING %s: %i data bytes\n", g_ping.ip4, PACKETSIZE); + if ((g_ping.sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { - signal(SIGINT, stats_recap); - rs_clear(); - listener(PF_INET, SOCK_RAW, IPPROTO_ICMP, &display); + ft_dprintf(2, "socket(2) error\n"); + exit(1); } - ping((struct sockaddr_in*)result->ai_addr); + if (setsockopt(g_ping.sock, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0) + { + ft_dprintf(2, "setsockopt(2) error\n"); + exit(1); + } + g_ping.pid = getpid(); + rs_init(&g_ping.rs); + signal(SIGINT, stats_recap); + signal(SIGALRM, ping); + alarm(1); + listener(PF_INET, SOCK_RAW, IPPROTO_ICMP, &display); return (0); }