ditched libc icmphdr for a struct in ft_ping

This commit is contained in:
2024-09-14 03:08:40 +02:00
parent 71be209ee6
commit 995a4acdf7
2 changed files with 40 additions and 24 deletions

View File

@@ -15,6 +15,15 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
struct icmp_header
{
uint8_t type;
uint8_t code;
uint16_t checksum;
uint16_t id;
uint16_t seq;
};
struct t_socket struct t_socket
{ {
struct sockaddr_in dst, src; struct sockaddr_in dst, src;

55
main.c
View File

@@ -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 data[2048];
unsigned char data2[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(data, 0, sizeof(data));
memset(data2, 0, sizeof(data2)); memset(data2, 0, sizeof(data2));
sock.fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock.fd < 0) if (sock < 0)
{ {
fprintf(stderr, "ERROR : socket() failed\n"); fprintf(stderr, "ERROR : socket() failed\n");
return (0); 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"); fprintf(stderr, "ERROR : getsockname() failed\n");
return (0); return (0);
} }
sock.dst.sin_family = AF_INET; dst.sin_family = AF_INET;
memset(icmp_header, 0, sizeof(icmp_header)); memset(icmp_hdr, 0, sizeof(icmp_hdr));
icmp_header->type = ICMP_ECHO; icmp_hdr->type = ICMP_ECHO;
icmp_header->code = 0; icmp_hdr->code = 0;
icmp_header->checksum = 0; icmp_hdr->checksum = 0;
icmp_header->un.echo.id = getpid(); icmp_hdr->id = getpid();
icmp_header->un.echo.sequence = *seq++; icmp_hdr->seq = *seq++;
icmp_header->checksum = calculate_checksum((uint16_t *)icmp_header, sizeof(icmp_header)); icmp_hdr->checksum = calculate_checksum((uint16_t *)icmp_hdr, sizeof(icmp_hdr));
if (sendto(sock.fd, data, sizeof(data), 0, (struct sockaddr *)&sock.dst, sizeof(sock.dst)) == -1) if (sendto(sock, data, sizeof(data), 0, (struct sockaddr *)&dst, sizeof(dst)) == -1)
{ {
fprintf(stderr, "ERROR : sendto() failed\n"); fprintf(stderr, "ERROR : sendto() failed\n");
return (0); 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"); fprintf(stderr, "ERROR : recvfrom() failed\n");
return (0); return (0);
} }
struct icmphdr *icmp_recv_header = (struct icmphdr *)(data2 + 20); struct icmp_header *icmp_recv_hdr = (struct icmp_header *)(data2 + 20);
if (icmp_recv_header->type != ICMP_ECHOREPLY || icmp_recv_header->code != 0) 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"); fprintf(stderr, "ERROR : invalid packet received (code)\n");
return (0); 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"); fprintf(stderr, "ERROR : invalid packet received (id is not matching)\n");
return (0); 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"); fprintf(stderr, "ERROR : invalid packet received (sequence is not matching)\n");
return (0); return (0);
} }
printf("success"); printf("success");
close(sock.fd); close(sock);
return (1); return (1);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct t_socket sock; int sock;
struct sockaddr_in src, dst;
int seq = 1; int seq = 1;
sock.src.sin_family = AF_INET; src.sin_family = AF_INET;
if (argc != 2 || argv[1] == NULL || argv[1][0] == 0) if (argc != 2 || argv[1] == NULL || argv[1][0] == 0)
{ {
fprintf(stderr, "ERROR : usage : ping {-v?} [ADRESS]\n"); fprintf(stderr, "ERROR : usage : ping {-v?} [ADRESS]\n");
return (0); 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]); fprintf(stderr, "ERROR : %s is an invalid adress\n", argv[1]);
return (0); return (0);
} }
return (ft_ping(sock, &seq)); return (ft_ping(sock, &seq, src, dst));
} }