From 995a4acdf7d1d370d5e04d17131023e88671dd35 Mon Sep 17 00:00:00 2001 From: Namonay Date: Sat, 14 Sep 2024 03:08:40 +0200 Subject: [PATCH] ditched libc icmphdr for a struct in ft_ping --- ft_ping.h | 9 +++++++++ main.c | 55 +++++++++++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/ft_ping.h b/ft_ping.h index 716663a..aaac178 100644 --- a/ft_ping.h +++ b/ft_ping.h @@ -15,6 +15,15 @@ #include #include +struct icmp_header +{ + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t id; + uint16_t seq; +}; + struct t_socket { struct sockaddr_in dst, src; diff --git a/main.c b/main.c index 491c204..744c5e7 100644 --- a/main.c +++ b/main.c @@ -19,78 +19,85 @@ uint16_t calculate_checksum(uint16_t *data, int len) } -int ft_ping(struct t_socket sock, int *seq) +int ft_ping(int sock, int *seq, struct sockaddr_in src, struct sockaddr_in dst) { unsigned char data[2048]; unsigned char data2[2048]; - struct icmphdr *icmp_header = (struct icmphdr *)data; + int len; + struct icmp_header *icmp_hdr = (struct icmp_header *)data; memset(data, 0, sizeof(data)); memset(data2, 0, sizeof(data2)); - sock.fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (sock.fd < 0) + sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sock < 0) { fprintf(stderr, "ERROR : socket() failed\n"); return (0); } - if (getsockname(sock.fd, (struct sockaddr *)&sock.src, &sock.len) < 0) + if (getsockname(sock, (struct sockaddr *)&src, &len) < 0) { fprintf(stderr, "ERROR : getsockname() failed\n"); return (0); } - sock.dst.sin_family = AF_INET; - memset(icmp_header, 0, sizeof(icmp_header)); - icmp_header->type = ICMP_ECHO; - icmp_header->code = 0; - icmp_header->checksum = 0; - icmp_header->un.echo.id = getpid(); - icmp_header->un.echo.sequence = *seq++; - icmp_header->checksum = calculate_checksum((uint16_t *)icmp_header, sizeof(icmp_header)); - if (sendto(sock.fd, data, sizeof(data), 0, (struct sockaddr *)&sock.dst, sizeof(sock.dst)) == -1) + dst.sin_family = AF_INET; + memset(icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr->type = ICMP_ECHO; + icmp_hdr->code = 0; + icmp_hdr->checksum = 0; + icmp_hdr->id = getpid(); + icmp_hdr->seq = *seq++; + icmp_hdr->checksum = calculate_checksum((uint16_t *)icmp_hdr, sizeof(icmp_hdr)); + if (sendto(sock, data, sizeof(data), 0, (struct sockaddr *)&dst, sizeof(dst)) == -1) { fprintf(stderr, "ERROR : sendto() failed\n"); return (0); } - if (recvfrom(sock.fd, data2, sizeof(data2), 0, (struct sockaddr *)&sock.src, &sock.len) == -1) + if (recvfrom(sock, data2, sizeof(data2), 0, (struct sockaddr *)&src, &len) == -1) { fprintf(stderr, "ERROR : recvfrom() failed\n"); return (0); } - struct icmphdr *icmp_recv_header = (struct icmphdr *)(data2 + 20); - if (icmp_recv_header->type != ICMP_ECHOREPLY || icmp_recv_header->code != 0) + struct icmp_header *icmp_recv_hdr = (struct icmp_header *)(data2 + 20); + for (int i = 0; data[i]; i++) + printf("%c", data[i]); + for (int i = 0; data2[i]; i++) + printf("%c", data2[i]); + if (icmp_recv_hdr->type != ICMP_ECHOREPLY || icmp_recv_hdr->code != 0) { + printf("%d %d\n", icmp_recv_hdr->type, icmp_recv_hdr->code); fprintf(stderr, "ERROR : invalid packet received (code)\n"); return (0); } - if (icmp_recv_header->un.echo.id != icmp_header->un.echo.id) + if (icmp_recv_hdr->id != icmp_hdr->id) { fprintf(stderr, "ERROR : invalid packet received (id is not matching)\n"); return (0); } - if (icmp_recv_header->un.echo.sequence != icmp_header->un.echo.sequence) + if (icmp_recv_hdr->seq != icmp_hdr->seq) { fprintf(stderr, "ERROR : invalid packet received (sequence is not matching)\n"); return (0); } printf("success"); - close(sock.fd); + close(sock); return (1); } int main(int argc, char **argv) { - struct t_socket sock; + int sock; + struct sockaddr_in src, dst; int seq = 1; - sock.src.sin_family = AF_INET; + src.sin_family = AF_INET; if (argc != 2 || argv[1] == NULL || argv[1][0] == 0) { fprintf(stderr, "ERROR : usage : ping {-v?} [ADRESS]\n"); return (0); } - if (gethostbyname(argv[1]) == NULL && inet_aton(argv[1], (struct in_addr *)&sock.dst.sin_addr.s_addr) == 0) + if (gethostbyname(argv[1]) == NULL && inet_aton(argv[1], (struct in_addr *)&dst.sin_addr.s_addr) == 0) { fprintf(stderr, "ERROR : %s is an invalid adress\n", argv[1]); return (0); } - return (ft_ping(sock, &seq)); + return (ft_ping(sock, &seq, src, dst)); } \ No newline at end of file