diff --git a/ping/Makefile b/ping/Makefile index 9503eed4..61823b4c 100644 --- a/ping/Makefile +++ b/ping/Makefile @@ -49,6 +49,8 @@ $(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(CLIENT_OBJ) $(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS) \ -lm @printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n" + @sudo setcap cap_net_raw+ep $@ + @printf "\r\033[38;5;117m✓ SETCAP $@ \033[0m\033[K\n" $(LIBFT_LIB): @make -C $(LIBFT_DIR) diff --git a/ping/includes/ping.h b/ping/includes/ping.h index 9b3cfb06..3835cf7e 100644 --- a/ping/includes/ping.h +++ b/ping/includes/ping.h @@ -25,12 +25,11 @@ # include # include -# define PACKETSIZE 64 - typedef struct s_ping t_ping; struct s_ping { + size_t pkt_size; pid_t pid; t_rs rs; int pkt_sent; @@ -48,10 +47,4 @@ struct s_ping extern t_ping g_ping; -struct s_packet -{ - struct icmp hdr; - char msg[PACKETSIZE - sizeof(struct icmp)]; -}; - #endif diff --git a/ping/srcs/ping.c b/ping/srcs/ping.c index b767e991..ab7527b1 100644 --- a/ping/srcs/ping.c +++ b/ping/srcs/ping.c @@ -11,12 +11,11 @@ /* ************************************************************************** */ #include "ping.h" -#define TIME_START 0 #define TIME_END 1 -#define TIME_TRIPTIME 2 t_ping g_ping = { .pid = -1, + .pkt_size = 56, .pkt_sent = -1, .pkt_recv = 0, }; @@ -36,16 +35,26 @@ int resolve_host(char *node, t_ping *ping) exit(1); } ping->sa = result; - inet_ntop(AF_INET, &(((struct sockaddr_in*)ping->sa->ai_addr)->sin_addr), ping->ip4, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(((struct sockaddr_in*)ping->sa->ai_addr)->sin_addr), + ping->ip4, INET_ADDRSTRLEN); return (0); } +void display_time_exceeded(struct sockaddr *addr, struct icmp *icmp) +{ + char ipbuf[INET_ADDRSTRLEN]; + + bzero(ipbuf, INET_ADDRSTRLEN); + getnameinfo(addr, sizeof(struct sockaddr_in), ipbuf, INET_ADDRSTRLEN, + NULL, 0, NI_NUMERICHOST); + printf("From %s icmp_seq=%d Time to live exceeded\n", + ipbuf, icmp->icmp_id); +} void display(void *buf, int bytes, struct sockaddr *addr) { struct ip *ip; struct icmp *icmp; - struct s_packet *pkt; int hlen; double triptime; char hbuf[NI_MAXHOST]; @@ -54,39 +63,48 @@ void display(void *buf, int bytes, struct sockaddr *addr) ip = buf; (void)bytes; hlen = ip->ip_hl << 2; - pkt = (struct s_packet*)(buf + hlen); - icmp = &pkt->hdr; - if (icmp->icmp_id != g_ping.pid) + icmp = (struct icmp*)(buf + hlen); + if (icmp->icmp_type == ICMP_TIME_EXCEEDED) + return (display_time_exceeded(addr, icmp)); + else if (icmp->icmp_id != g_ping.pid) + { + dprintf(2, "id = %i\n", icmp->icmp_id); return ; - triptime = time_milli() - *(double*)&pkt->msg; + } + triptime = time_milli() - *(double*)(icmp + 1); rs_push(&g_ping.rs, triptime); g_ping.pkt_recv++; bzero(hbuf, NI_MAXHOST); bzero(ipbuf, INET_ADDRSTRLEN); - getnameinfo(addr, sizeof(struct sockaddr_in), ipbuf, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); + getnameinfo(addr, sizeof(struct sockaddr_in), ipbuf, INET_ADDRSTRLEN, + NULL, 0, NI_NUMERICHOST); if (getnameinfo(addr, sizeof(struct sockaddr_in), hbuf, NI_MAXHOST, NULL, 0, 0) == 0) - printf("%d bytes from %s (%s): icmp_seq=%d ttl=%i time=%.1f ms\n", - hlen, hbuf, ipbuf, icmp->icmp_seq, ip->ip_ttl, triptime); + printf("%zu bytes from %s (%s): icmp_seq=%d ttl=%i time=%.1f ms\n", + bytes - hlen - sizeof(struct icmphdr), hbuf, ipbuf, icmp->icmp_seq, ip->ip_ttl, triptime); else - printf("%d bytes from %s: icmp_seq=%d ttl=%i time=%.1f ms\n", - hlen, ipbuf, icmp->icmp_seq, ip->ip_ttl, triptime); + printf("%zu bytes from %s: icmp_seq=%d ttl=%i time=%.1f ms\n", + bytes - hlen - sizeof(struct icmphdr), ipbuf, icmp->icmp_seq, ip->ip_ttl, triptime); } void ping(int signo) { - struct s_packet pkt; + char pkt[g_ping.pkt_size + sizeof(struct icmp)]; + double *msg; + struct icmp *hdr; double epoch; (void)signo; + hdr = (struct icmp*)&pkt; 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; + hdr->icmp_type = ICMP_ECHO; + hdr->icmp_id = g_ping.pid; + hdr->icmp_seq = ++g_ping.pkt_sent; + msg = (double*)(pkt + sizeof(struct icmp)); epoch = time_milli(); - ft_memcpy(pkt.msg, (void*)&epoch, sizeof(double)); - pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt)); + ft_memcpy(msg, (void*)&epoch, sizeof(double)); + hdr->icmp_cksum = cksum(&pkt, sizeof(pkt)); sendto(g_ping.sock, &pkt, sizeof(pkt), 0, g_ping.sa->ai_addr, sizeof(struct sockaddr)); alarm(1); @@ -99,10 +117,10 @@ void stats_recap(int signo) (void)signo; 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--- %s ping statistics ---", g_ping.sa->ai_canonname); printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss", - g_ping.rs.count, g_ping.pkt_recv, loss); - printf("\nround-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms", + g_ping.pkt_sent, g_ping.pkt_recv, loss); + printf("\nrtt min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n", g_ping.rs.min, g_ping.rs.avg, g_ping.rs.max, g_ping.rs.stdev); freeaddrinfo(g_ping.sa); exit(0); @@ -117,18 +135,20 @@ int main(int ac, char **av) } resolve_host(av[1], &g_ping); if (g_ping.sa->ai_canonname) - printf("PING %s (%s): %i data bytes\n", - g_ping.sa->ai_canonname, g_ping.ip4, PACKETSIZE); + printf("PING %s (%s): %zu(%zu) data bytes\n", + g_ping.sa->ai_canonname, g_ping.ip4, + g_ping.pkt_size, g_ping.pkt_size + sizeof(struct icmp)); else - printf("PING %s: %i data bytes\n", g_ping.ip4, PACKETSIZE); + printf("PING %s: %zu(%zu) data bytes\n", g_ping.ip4, + g_ping.pkt_size, g_ping.pkt_size + sizeof(struct icmp)); if ((g_ping.sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { - ft_dprintf(2, "socket(2) error\n"); + perror("socket"); exit(1); } - if (setsockopt(g_ping.sock, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0) + if (setsockopt(g_ping.sock, 0, IP_TTL, (int[]){255}, sizeof(int)) != 0) { - ft_dprintf(2, "setsockopt(2) error\n"); + perror("setsockopt"); exit(1); } g_ping.pid = getpid();