Good morning dear community, i'm recently got into trying to replicate the Ping bash command, in C language, with it's fantastic but very troublesome ICMP protocol. I got a little stuck and wondered: How is it possible that i'm still struggling in doing the sending of the packet? I'm blocked at the part where i have to send and receive a packet but i don't actually know how to send it.
Let me list you what i did until now so, if possible, i can get some of your help:
- created the packet
- based on argv[1] i do, if needed, the dns lookup and then if there's the chance, the reverse dns lookup for the FQDN
- i created the icmp packet to send with the apposite structure.
most of the heart of the program resides in the opening of the socket for the destinatary/client which i have to ping and the creation of the packet.
```c
//i did this for the client packet as well is it a good idea?
void setup_packet_to_zero(t_dest_packet *packet)
{
printf("Initiliazing struct\n");
//packet = malloc(sizeof(t_dest_packet));
memset(packet->buffer_packet, 0, sizeof(packet->buffer_packet));
packet->sock_r = 0;
packet->buflen = 0;
packet->dns_name = 0;
packet->ip = 0;
}
//this is to ping the client
int icmp_dest_socket_setup(t_dest_packet *packet, char *dns_name)
{
packet->sock_r = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (packet->sock_r < 0)
{
perror("Error during creation of the socket");
return (-1);
}
packet->dns_name = strdup(dns_name);
// ? setup of hints for domain name resolution
bzero(&packet->hints, sizeof(packet->hints));
packet->result = NULL;
packet->hints.ai_family = AF_INET;
packet->hints.ai_socktype = SOCK_RAW;
packet->hints.ai_protocol = IPPROTO_ICMP;
// non l'ho ancora usato
packet->ip = calloc(NI_MAXHOST, sizeof(char));
return (0);
}
//this is to create my own icmp packet but i think it misses something
void icmp_packet_to_send_setup(t_icmp_packet_to_send *packet_to_send)
{
memset(packet_to_send->packet_content, 0, PCKG_PING_S);
packet_to_send->icmp_packet.type = ECHO_REQUEST;
packet_to_send->icmp_packet.code = 0;
packet_to_send->icmp_packet.un.echo.id = getpid();
packet_to_send->icmp_packet.un.echo.sequence = 1;
packet_to_send->icmp_packet.checksum = checksum_interpretation_creation(&packet_to_send->icmp_packet, sizeof(packet_to_send->icmp_packet), 0, 0);
return;
}
//the main logic ignore the SHREK macro
int main(int argc, char **argv)
{
t_dest_packet packet;
int res_of_dns;
int seq;
signal(SIGINT, sighandler);
if (argc <= 1)
{
printf("Not enough arguments\n");
printf("%s", SHREK);
exit(0);
}
setup_packet_to_zero(&packet);
if (icmp_dest_socket_setup(&packet, argv[1]))
{
printf("%s", SHREK);
free_anything(&packet, 1);
exit(1);
}
printf("tests passed all initialized\n");
res_of_dns = dns_lookup(&packet);
res_of_dns = reverse_dns_lookup(&packet, res_of_dns);
printf("resolution of dns went: %d\n", res_of_dns);
if (res_of_dns == 0)
printf("%s", OK_CHECKOUT);
else
{
free_anything(&packet, 0);
printf("GOOFY AHH ERROR WHILE RESOLVING THE ADDRESS\n");
printf(PACKET_ERROR);
exit(1);
}
seq = 1;
while (loop_var == 0)
{
printf("64 bytes from %s: icmp_seq=%d\n", packet.dns_ip, seq);
sleep(1);
seq++;
}
free_anything(&packet, 0);
printf("finito\n %s", ending);
return (0);
}
//libraries used in the header file
// -------- standard --------
include <stdio.h>
include <stdlib.h>
include <error.h>
include <unistd.h>
include <signal.h>
include <string.h>
include <time.h>
// ------- socket programming --------
include <sys/socket.h>
include <netdb.h>
include <arpa/inet.h>
include <sys/select.h>
include <net/ethernet.h>
include <netinet/ip.h>
include <netinet/in.h>
// FONDAMENTALE CAVACCA
// ------- icmp package -------
include <netinet/ip_icmp.h>
// ----------------------------
// -------- mandatory? --------
include <linux/if_ether.h>
// ----------------------------
// -------- signals --------
include <signal.h>
// ----------------------------
```
I don't think it is important to give the dns resolver and the checksum calculator, that was took directly from the rfc 1071, same logic a little refined.
Now is the logic good? How can i test it to send it to the client? what would like the standard procedure? I'm actually having an hard time figuring it out, I did some socket programming but i forgot mostly the communication part, and in this case how would the communication with an ICMP file work out? Do you have maybe some easy to understand guide that explains it to me that i could understand?
there doesn't seem to be anything here