add: error message

This commit is contained in:
2025-11-20 10:37:16 -06:00
parent 214abd7ddd
commit c6289081e7
7 changed files with 200 additions and 97 deletions

View File

@@ -69,7 +69,7 @@ value_error:
return 2;
}
static int get_setting(char * const *av, struct setting *setting)
static int get_setting(char * const *av, struct setting *settings)
{
struct param parameters[] = {
{NULL, "?", OPTION, false},
@@ -83,25 +83,26 @@ static int get_setting(char * const *av, struct setting *setting)
char *hostname = parsing(av, parameters);
if (hostname == NULL)
return 1;
setting->dest.hostname = hostname;
settings->dest.hostname = hostname;
setting->help = parameters[0].value;
setting->verbose = parameters[1].value;
setting->numeric_only = parameters[2].value;
settings->help = parameters[0].value;
settings->verbose = parameters[1].value;
settings->numeric_only = parameters[2].value;
size_t ttl;
if (parsing_number(parameters[3].value, 0, 255, &ttl))
return 2;
setting->ttl = ttl;
if (parsing_number(parameters[4].value, 0, 2147483647, &setting->payload_size))
settings->ttl = ttl;
if (parsing_number(parameters[4].value, 0, 2147483647, &settings->payload_size))
return 3;
if (parsing_number(parameters[5].value, 0, 2147483647, &setting->preload))
if (parsing_number(parameters[5].value, 0, 2147483647, &settings->preload))
return 4;
return 0;
}
static int create_socket(struct setting const *setting)
static int create_socket(struct setting const *settings)
{
int ret;
(void)settings;
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
@@ -111,13 +112,13 @@ static int create_socket(struct setting const *setting)
return -1;
}
ret = setsockopt(sockfd, IPPROTO_IP, IP_TTL, &setting->ttl, sizeof(uint8_t));
ret = setsockopt(sockfd, IPPROTO_IP, IP_TTL, &settings->ttl, sizeof(uint8_t));
if (ret != 0)
{
print_err("Failed to setsockopt(): ttl");
return -1;
}
struct timeval tv = {1, 0};
ret = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
if (ret != 0)
@@ -129,18 +130,25 @@ static int create_socket(struct setting const *setting)
return sockfd;
}
static int set_destination(struct hostenv *host)
static int preload(struct setting const *settings, int sockfd, char const *packet, size_t packet_size)
{
if (dns_lookup(host))
return 1;
host->ip.sin_family = AF_INET;
host->ip.sin_port = htons(0);
inet_pton(AF_INET, host->ipstr, &host->ip.sin_addr);
for (size_t i = 0; i < settings->preload; i++)
{
if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings->dest.ip, sizeof(settings->dest.ip)) == -1)
return 1;
}
return 0;
}
int check_reply(struct sockaddr_in const *me, struct sockaddr_in const *sender, char *sent, char *received, size_t packet_size)
{
if (((struct icmphdr *)sent)->type != 0)
return 0;
if (check_packet_conformity(sent, received, packet_size))
return 1;
return memcmp(sender, me, sizeof(struct sockaddr_in));
}
int main(int ac, char **av)
{
(void) ac;
@@ -148,51 +156,40 @@ int main(int ac, char **av)
struct setting settings;
if (get_setting(av + 1, &settings))
return 1;
goto error0;
size_t packet_size = sizeof(struct icmphdr) + settings.payload_size;
size_t recv_packet_size = packet_size + sizeof(struct iphdr);
signal(SIGINT, signal_handler);
if (set_destination(&settings.dest))
return 1;
if (dns_lookup(&settings.dest))
goto error0;
int sockfd = create_socket(&settings);
if (sockfd == -1)
return 1;
goto error0;
char *packet = packet_create(settings.payload_size);
if (packet == NULL)
{
close(sockfd);
return 2;
}
goto error1;
char *buffer;
buffer = malloc(packet_size * sizeof(char));
buffer = malloc((recv_packet_size) * sizeof(char));
if (buffer == NULL)
{
print_err("error: allocation failed.");
free(packet);
close(sockfd);
return 10;
goto error2;
}
struct sockaddr_in sender;
socklen_t len = sizeof(sender);
bzero(&stats, sizeof(struct statistics));
print_header(&settings);
for (size_t i = 0; i < settings.payload_size; i++)
{
if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings.dest.ip, sizeof(settings.dest.ip)) == -1)
{
print_err("error: send packet failed.");
free(packet);
close(sockfd);
return 2;
}
}
if (preload(&settings, sockfd, packet, packet_size))
goto error3;
while (loop) {
@@ -202,47 +199,48 @@ int main(int ac, char **av)
if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings.dest.ip, sizeof(settings.dest.ip)) == -1)
{
print_err("error: send packet failed.");
free(packet);
close(sockfd);
return 2;
goto error2;
}
stats.packets_sent++;
int ret = 0;
ssize_t ret = 0;
do
{
ret = recvfrom(sockfd, buffer, packet_size, 0, (struct sockaddr *) &sender, &len) < 0;
if (ret == -1)
ret = recvfrom(sockfd, buffer, recv_packet_size, 0, (struct sockaddr *) &sender, &len);
if (ret < 0)
{
print_err("error: receive packet failed.");
close(sockfd);
free(buffer);
free(packet);
return 3;
goto error3;
}
gettimeofday(&stop, NULL);
}
while ((ret > 1) && (len != packet_size && packet_check(buffer, packet_size) && packet_compare(packet, buffer, packet_size)));
while (((size_t) ret != recv_packet_size) || (check_reply(&settings.dest.ip, &sender, packet, buffer + sizeof(struct iphdr), packet_size)));
if (ret > 1)
{
if (((struct icmphdr *) buffer + sizeof(struct iphdr))->type == 0)
stats.packets_received++;
print_recv(&settings, (struct icmphdr *)buffer, &start, &stop);
}
print_recv(&settings, (struct icmphdr*) (buffer + sizeof(struct iphdr)), &start, &stop, &sender);
sleep(1);
if (packet_update(packet, settings.payload_size))
{
close(sockfd);
free(buffer);
free(packet);
}
goto error3;
}
free(packet);
free(buffer);
close(sockfd);
print_statistics(&stats, &settings);
return 0;
error3:
free(buffer);
error2:
free(packet);
error1:
close(sockfd);
error0:
return 1;
}