86 lines
2.4 KiB
C
86 lines
2.4 KiB
C
|
|
|
|
#include "icmp_error.h"
|
|
#include "interval.h"
|
|
#include "setting.h"
|
|
#include "statistics.h"
|
|
#include <arpa/inet.h>
|
|
#include <bits/types/struct_timeval.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/ip.h>
|
|
#include <netinet/ip_icmp.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
void print_err(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
|
|
dprintf(2, "ft_ping: ");
|
|
va_start(args, format);
|
|
vdprintf(2, format, args);
|
|
va_end(args);
|
|
write(2, "\n", 1);
|
|
}
|
|
|
|
void print_header(const struct setting *settings)
|
|
{
|
|
printf("PING %s (%s): %zu data bytes",
|
|
settings->dest.hostname,
|
|
settings->dest.ipstr,
|
|
settings->payload_size
|
|
);
|
|
if (settings->verbose)
|
|
{
|
|
unsigned short pid = getpid();
|
|
unsigned short s_pid = htons(getpid());
|
|
printf(", id 0x%02x%02x = %d", s_pid & 0xFF, (s_pid>>8) & 0xFF, pid);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void print_statistics(struct statistics const *stats, struct setting const *settings)
|
|
{
|
|
printf("--- %s ping statistics ---\n", settings->dest.hostname);
|
|
printf("%zu packets transmitted, %zu packets received, %.3f%% packet loss\n",
|
|
stats->packets_sent,
|
|
stats->packets_received,
|
|
((double) stats->packets_sent - stats->packets_received) * 100 / stats->packets_sent
|
|
);
|
|
}
|
|
|
|
static const char *get_message_description(const uint8_t type, const uint8_t code)
|
|
{
|
|
switch(type)
|
|
{
|
|
case 0:
|
|
return "icmp_seq=%d ttl=%d time=%.3f ms";
|
|
case ICMP_DEST_UNREACH:
|
|
return (net_icmp_unreach_messages[code]);
|
|
case ICMP_REDIRECT:
|
|
return (net_icmp_redirect_messages[code]);
|
|
case ICMP_TIME_EXCEEDED:
|
|
return (net_icmp_time_messages[code]);
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
void print_recv(const struct setting *settings, const char *packet, const struct timeval *start, const struct timeval *stop, struct sockaddr_in const *sender)
|
|
{
|
|
const struct iphdr *ip_hdr = (const struct iphdr *) packet;
|
|
const struct icmphdr *icmp_hdr = (const struct icmphdr *) packet + sizeof(struct iphdr);
|
|
|
|
char *ipstr = inet_ntoa(sender->sin_addr);
|
|
printf("%ld bozo", ntohs(ip_hdr->tot_len) - sizeof(struct iphdr));
|
|
printf(" bytes from %s: ", ipstr);
|
|
printf(get_message_description(icmp_hdr->type, icmp_hdr->code),
|
|
htons(icmp_hdr->un.echo.sequence),
|
|
settings->ttl,
|
|
get_interval(start, stop)
|
|
);
|
|
printf("\n");
|
|
}
|
|
|