add: error message
This commit is contained in:
@ -24,9 +24,13 @@ int dns_lookup(struct hostenv *host)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct addrinfo *first = responses;
|
struct addrinfo *first = responses;
|
||||||
struct in_addr *addr = &(((struct sockaddr_in *) first->ai_addr)->sin_addr);
|
|
||||||
|
|
||||||
inet_ntop(first->ai_family, addr, host->ipstr, sizeof(char) * INET_ADDRSTRLEN);
|
host->ip.sin_addr.s_addr = ((struct sockaddr_in *) first->ai_addr)->sin_addr.s_addr;
|
||||||
|
host->ip.sin_port = ((struct sockaddr_in *) first->ai_addr)->sin_port;
|
||||||
|
memcpy(host->ip.sin_zero, ((struct sockaddr_in *) first->ai_addr)->sin_zero, sizeof(host->ip.sin_zero));
|
||||||
|
host->ip.sin_family = ((struct sockaddr_in *) first->ai_addr)->sin_family;
|
||||||
|
|
||||||
|
inet_ntop(first->ai_family, &host->ip.sin_addr, host->ipstr, sizeof(char) * INET_ADDRSTRLEN);
|
||||||
|
|
||||||
freeaddrinfo(responses);
|
freeaddrinfo(responses);
|
||||||
|
|
||||||
|
|||||||
87
src/icmp_error.h
Normal file
87
src/icmp_error.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICMP_ECHOREPLY = 0, /* Echo Reply */
|
||||||
|
ICMP_DEST_UNREACH = 3, /* Destination Unreachable */
|
||||||
|
ICMP_SOURCE_QUENCH = 4, /* Source Quench */
|
||||||
|
ICMP_REDIRECT = 5, /* Redirect (change route) */
|
||||||
|
ICMP_ECHO = 8, /* Echo Request */
|
||||||
|
ICMP_TIME_EXCEEDED = 11, /* Time Exceeded */
|
||||||
|
ICMP_PARAMETERPROB = 12, /* Parameter Problem */
|
||||||
|
ICMP_TIMESTAMP = 13, /* Timestamp Request */
|
||||||
|
ICMP_TIMESTAMPREPLY = 14, /* Timestamp Reply */
|
||||||
|
ICMP_INFO_REQUEST = 15, /* Information Request */
|
||||||
|
ICMP_INFO_REPLY = 16, /* Information Reply */
|
||||||
|
ICMP_ADDRESS = 17, /* Address Mask Request */
|
||||||
|
ICMP_ADDRESSREPLY = 18 /* Address Mask Reply */
|
||||||
|
} net_icmp_types;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICMP_NET_UNREACH = 0, /* Network Unreachable */
|
||||||
|
ICMP_HOST_UNREACH = 1, /* Host Unreachable */
|
||||||
|
ICMP_PROT_UNREACH = 2, /* Protocol Unreachable */
|
||||||
|
ICMP_PORT_UNREACH = 3, /* Port Unreachable */
|
||||||
|
ICMP_FRAG_NEEDED = 4, /* Fragmentation Needed/DF set */
|
||||||
|
ICMP_SR_FAILED = 5, /* Source Route failed */
|
||||||
|
ICMP_NET_UNKNOWN = 6,
|
||||||
|
ICMP_HOST_UNKNOWN = 7,
|
||||||
|
ICMP_HOST_ISOLATED = 8,
|
||||||
|
ICMP_NET_ANO = 9,
|
||||||
|
ICMP_HOST_ANO = 10,
|
||||||
|
ICMP_NET_UNR_TOS = 11,
|
||||||
|
ICMP_HOST_UNR_TOS = 12,
|
||||||
|
ICMP_PKT_FILTERED = 13, /* Packet filtered */
|
||||||
|
ICMP_PREC_VIOLATION = 14, /* Precedence violation */
|
||||||
|
ICMP_PREC_CUTOFF = 15 /* Precedence cut off */
|
||||||
|
} net_icmp_unreach_codes; /* Codes for UNREACH*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICMP_REDIR_NET = 0,
|
||||||
|
ICMP_REDIR_HOST = 1,
|
||||||
|
ICMP_REDIR_NETTOS = 2,
|
||||||
|
ICMP_REDIR_HOSTTOS = 3
|
||||||
|
} net_icmp_redirect_code; /* Codes for REDIRECT*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICMP_EXC_TTL = 0,
|
||||||
|
ICMP_EXC_FRAGTIME = 1
|
||||||
|
} net_icmp_time_code; /* Codes for TIME_EXCEEDED. */
|
||||||
|
|
||||||
|
static const char *net_icmp_unreach_messages[] =
|
||||||
|
{
|
||||||
|
[ICMP_NET_UNREACH] = "Network Unreachable",
|
||||||
|
[ICMP_HOST_UNREACH] = "Host Unreachable",
|
||||||
|
[ICMP_PROT_UNREACH] = "Protocol Unreachable",
|
||||||
|
[ICMP_PORT_UNREACH] = "Port Unreachable",
|
||||||
|
[ICMP_FRAG_NEEDED] = "Fragmentation Needed/DF set",
|
||||||
|
[ICMP_SR_FAILED] = "Source Route failed",
|
||||||
|
[ICMP_NET_UNKNOWN] = "Network Unknown",
|
||||||
|
[ICMP_HOST_UNKNOWN] = "Host Unknown",
|
||||||
|
[ICMP_HOST_ISOLATED] = "Host Isolated",
|
||||||
|
[ICMP_NET_ANO] = "Network Administratively Prohibited",
|
||||||
|
[ICMP_HOST_ANO] = "Host Administratively Prohibited",
|
||||||
|
[ICMP_NET_UNR_TOS] = "Network Unreachable for TOS",
|
||||||
|
[ICMP_HOST_UNR_TOS] = "Host Unreachable for TOS",
|
||||||
|
[ICMP_PKT_FILTERED] = "Packet filtered",
|
||||||
|
[ICMP_PREC_VIOLATION] = "Precedence violation",
|
||||||
|
[ICMP_PREC_CUTOFF] = "Precedence cut off"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *net_icmp_redirect_messages[] =
|
||||||
|
{
|
||||||
|
[ICMP_REDIR_NET] = "Redirect for Network",
|
||||||
|
[ICMP_REDIR_HOST] = "Redirect for Host",
|
||||||
|
[ICMP_REDIR_NETTOS] = "Redirect for Network with TOS",
|
||||||
|
[ICMP_REDIR_HOSTTOS] = "Redirect for Host with TOS"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *net_icmp_time_messages[] =
|
||||||
|
{
|
||||||
|
[ICMP_EXC_TTL] = "Time-to-live exceeded",
|
||||||
|
[ICMP_EXC_FRAGTIME] = "Fragment Reassembly Timeout"
|
||||||
|
};
|
||||||
120
src/main.c
120
src/main.c
@ -69,7 +69,7 @@ value_error:
|
|||||||
return 2;
|
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[] = {
|
struct param parameters[] = {
|
||||||
{NULL, "?", OPTION, false},
|
{NULL, "?", OPTION, false},
|
||||||
@ -83,25 +83,26 @@ static int get_setting(char * const *av, struct setting *setting)
|
|||||||
char *hostname = parsing(av, parameters);
|
char *hostname = parsing(av, parameters);
|
||||||
if (hostname == NULL)
|
if (hostname == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
setting->dest.hostname = hostname;
|
settings->dest.hostname = hostname;
|
||||||
|
|
||||||
setting->help = parameters[0].value;
|
settings->help = parameters[0].value;
|
||||||
setting->verbose = parameters[1].value;
|
settings->verbose = parameters[1].value;
|
||||||
setting->numeric_only = parameters[2].value;
|
settings->numeric_only = parameters[2].value;
|
||||||
size_t ttl;
|
size_t ttl;
|
||||||
if (parsing_number(parameters[3].value, 0, 255, &ttl))
|
if (parsing_number(parameters[3].value, 0, 255, &ttl))
|
||||||
return 2;
|
return 2;
|
||||||
setting->ttl = ttl;
|
settings->ttl = ttl;
|
||||||
if (parsing_number(parameters[4].value, 0, 2147483647, &setting->payload_size))
|
if (parsing_number(parameters[4].value, 0, 2147483647, &settings->payload_size))
|
||||||
return 3;
|
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 4;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_socket(struct setting const *setting)
|
static int create_socket(struct setting const *settings)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
(void)settings;
|
||||||
|
|
||||||
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ static int create_socket(struct setting const *setting)
|
|||||||
return -1;
|
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)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
print_err("Failed to setsockopt(): ttl");
|
print_err("Failed to setsockopt(): ttl");
|
||||||
@ -129,18 +130,25 @@ static int create_socket(struct setting const *setting)
|
|||||||
return sockfd;
|
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))
|
for (size_t i = 0; i < settings->preload; i++)
|
||||||
return 1;
|
{
|
||||||
|
if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings->dest.ip, sizeof(settings->dest.ip)) == -1)
|
||||||
host->ip.sin_family = AF_INET;
|
return 1;
|
||||||
host->ip.sin_port = htons(0);
|
}
|
||||||
inet_pton(AF_INET, host->ipstr, &host->ip.sin_addr);
|
|
||||||
|
|
||||||
return 0;
|
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)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
(void) ac;
|
(void) ac;
|
||||||
@ -148,51 +156,40 @@ int main(int ac, char **av)
|
|||||||
struct setting settings;
|
struct setting settings;
|
||||||
|
|
||||||
if (get_setting(av + 1, &settings))
|
if (get_setting(av + 1, &settings))
|
||||||
return 1;
|
goto error0;
|
||||||
|
|
||||||
size_t packet_size = sizeof(struct icmphdr) + settings.payload_size;
|
size_t packet_size = sizeof(struct icmphdr) + settings.payload_size;
|
||||||
|
size_t recv_packet_size = packet_size + sizeof(struct iphdr);
|
||||||
|
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if (set_destination(&settings.dest))
|
if (dns_lookup(&settings.dest))
|
||||||
return 1;
|
goto error0;
|
||||||
|
|
||||||
int sockfd = create_socket(&settings);
|
int sockfd = create_socket(&settings);
|
||||||
if (sockfd == -1)
|
if (sockfd == -1)
|
||||||
return 1;
|
goto error0;
|
||||||
|
|
||||||
char *packet = packet_create(settings.payload_size);
|
char *packet = packet_create(settings.payload_size);
|
||||||
if (packet == NULL)
|
if (packet == NULL)
|
||||||
{
|
goto error1;
|
||||||
close(sockfd);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *buffer;
|
char *buffer;
|
||||||
buffer = malloc(packet_size * sizeof(char));
|
buffer = malloc((recv_packet_size) * sizeof(char));
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
print_err("error: allocation failed.");
|
print_err("error: allocation failed.");
|
||||||
free(packet);
|
goto error2;
|
||||||
close(sockfd);
|
|
||||||
return 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in sender;
|
struct sockaddr_in sender;
|
||||||
socklen_t len = sizeof(sender);
|
socklen_t len = sizeof(sender);
|
||||||
|
|
||||||
bzero(&stats, sizeof(struct statistics));
|
bzero(&stats, sizeof(struct statistics));
|
||||||
print_header(&settings);
|
print_header(&settings);
|
||||||
|
|
||||||
for (size_t i = 0; i < settings.payload_size; i++)
|
if (preload(&settings, sockfd, packet, packet_size))
|
||||||
{
|
goto error3;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (loop) {
|
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)
|
if (sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) &settings.dest.ip, sizeof(settings.dest.ip)) == -1)
|
||||||
{
|
{
|
||||||
print_err("error: send packet failed.");
|
print_err("error: send packet failed.");
|
||||||
free(packet);
|
goto error2;
|
||||||
close(sockfd);
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.packets_sent++;
|
stats.packets_sent++;
|
||||||
|
|
||||||
int ret = 0;
|
ssize_t ret = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = recvfrom(sockfd, buffer, packet_size, 0, (struct sockaddr *) &sender, &len) < 0;
|
ret = recvfrom(sockfd, buffer, recv_packet_size, 0, (struct sockaddr *) &sender, &len);
|
||||||
if (ret == -1)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
print_err("error: receive packet failed.");
|
print_err("error: receive packet failed.");
|
||||||
close(sockfd);
|
goto error3;
|
||||||
free(buffer);
|
|
||||||
free(packet);
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
gettimeofday(&stop, NULL);
|
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++;
|
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);
|
sleep(1);
|
||||||
|
|
||||||
if (packet_update(packet, settings.payload_size))
|
if (packet_update(packet, settings.payload_size))
|
||||||
{
|
goto error3;
|
||||||
close(sockfd);
|
|
||||||
free(buffer);
|
|
||||||
free(packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(packet);
|
free(packet);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
close(sockfd);
|
||||||
|
|
||||||
print_statistics(&stats, &settings);
|
print_statistics(&stats, &settings);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error3:
|
||||||
|
free(buffer);
|
||||||
|
error2:
|
||||||
|
free(packet);
|
||||||
|
error1:
|
||||||
|
close(sockfd);
|
||||||
|
error0:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
40
src/packet.c
40
src/packet.c
@ -2,6 +2,8 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netinet/ip_icmp.h>
|
#include <netinet/ip_icmp.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -26,8 +28,8 @@ static int fill_with_random(char *str, size_t nb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short checksum(void *b, int len) {
|
static unsigned short checksum(void const *b, int len) {
|
||||||
unsigned short *buf = b;
|
unsigned short const *buf = b;
|
||||||
unsigned int sum = 0;
|
unsigned int sum = 0;
|
||||||
unsigned short result;
|
unsigned short result;
|
||||||
|
|
||||||
@ -41,12 +43,20 @@ static unsigned short checksum(void *b, int len) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int packet_compare(const char *sent, const char *received, size_t packet_size)
|
int check_packet_conformity(char const *sent, char const *received, size_t packet_size)
|
||||||
{
|
{
|
||||||
const struct icmphdr *sent_hdr = (const struct icmphdr*) sent;
|
struct icmphdr const *sent_hdr = (struct icmphdr const *) sent;
|
||||||
const struct icmphdr *received_hdr = (const struct icmphdr*) received;
|
struct icmphdr *received_hdr = (struct icmphdr *) received;
|
||||||
|
|
||||||
if (received_hdr->un.echo.sequence == sent_hdr->un.echo.sequence)
|
if (received_hdr->un.echo.sequence != sent_hdr->un.echo.sequence)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
const uint16_t checksum_bak = received_hdr->checksum;
|
||||||
|
received_hdr->checksum = 0;
|
||||||
|
const uint16_t tmp = checksum(received, packet_size);
|
||||||
|
received_hdr->checksum = checksum_bak;
|
||||||
|
|
||||||
|
if (checksum_bak != tmp)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
const char *sent_payload = sent + sizeof(struct icmphdr);
|
const char *sent_payload = sent + sizeof(struct icmphdr);
|
||||||
@ -55,25 +65,9 @@ int packet_compare(const char *sent, const char *received, size_t packet_size)
|
|||||||
return memcmp(sent_payload, received_payload, packet_size - sizeof(struct icmphdr));
|
return memcmp(sent_payload, received_payload, packet_size - sizeof(struct icmphdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int packet_check(char *packet, size_t packet_size)
|
|
||||||
{
|
|
||||||
struct icmphdr *hdr = (struct icmphdr *) packet;
|
|
||||||
|
|
||||||
if (hdr->type != 0 || hdr->code != 8)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
const uint16_t checksum_bak = hdr->checksum;
|
|
||||||
hdr->checksum = 0;
|
|
||||||
int tmp = checksum(packet, packet_size);
|
|
||||||
hdr->checksum = checksum_bak;
|
|
||||||
|
|
||||||
return tmp - checksum_bak;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int packet_update(char *packet, size_t payload_size)
|
int packet_update(char *packet, size_t payload_size)
|
||||||
{
|
{
|
||||||
static size_t sequence = 1;
|
static uint16_t sequence = 0;
|
||||||
size_t hdr_size = sizeof(struct icmphdr);
|
size_t hdr_size = sizeof(struct icmphdr);
|
||||||
size_t packet_size = hdr_size + payload_size;
|
size_t packet_size = hdr_size + payload_size;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
int packet_compare(const char *sent, const char *received, size_t packet_size);
|
int check_packet_conformity(char *sent, char *received, size_t packet_size);
|
||||||
int packet_check(char *packet, size_t packet_size);
|
|
||||||
int packet_update(char *packet, size_t payload_size);
|
int packet_update(char *packet, size_t payload_size);
|
||||||
void *packet_create(size_t payload_size);
|
void *packet_create(size_t payload_size);
|
||||||
29
src/print.c
29
src/print.c
@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "icmp_error.h"
|
||||||
#include "interval.h"
|
#include "interval.h"
|
||||||
#include "setting.h"
|
#include "setting.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <bits/types/struct_timeval.h>
|
#include <bits/types/struct_timeval.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
@ -47,16 +49,35 @@ void print_statistics(struct statistics const *stats, struct setting const *sett
|
|||||||
stats->packets_received,
|
stats->packets_received,
|
||||||
(double) stats->packets_received * 100 / (double) stats->packets_sent
|
(double) stats->packets_received * 100 / (double) stats->packets_sent
|
||||||
);
|
);
|
||||||
|
// TODO fix packet lost calcul
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_recv(const struct setting *settings, const struct icmphdr *header, const struct timeval *start, const struct timeval *stop)
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
printf("%zu bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms\n",
|
void print_recv(const struct setting *settings, const struct icmphdr *header, const struct timeval *start, const struct timeval *stop, struct sockaddr_in const *sender)
|
||||||
settings->payload_size + sizeof(struct icmphdr),
|
{
|
||||||
settings->dest.ipstr,
|
char *ipstr = inet_ntoa(sender->sin_addr);
|
||||||
|
printf("%zu", settings->payload_size + sizeof(struct icmphdr) + ((header->type == 0) ? 0 : sizeof(struct iphdr)));
|
||||||
|
printf(" bytes from %s: ", ipstr);
|
||||||
|
printf(get_message_description(header->type, header->code),
|
||||||
htons(header->un.echo.sequence),
|
htons(header->un.echo.sequence),
|
||||||
settings->ttl,
|
settings->ttl,
|
||||||
get_interval(start, stop)
|
get_interval(start, stop)
|
||||||
);
|
);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,4 +9,4 @@ void print_err(const char *format, ...);
|
|||||||
|
|
||||||
void print_header(struct setting const *settings);
|
void print_header(struct setting const *settings);
|
||||||
void print_statistics(struct statistics const *stats, struct setting const *settings);
|
void print_statistics(struct statistics const *stats, struct setting const *settings);
|
||||||
void print_recv(struct setting const *settings, struct icmphdr const *header, struct timeval const *start, struct timeval const *stop);
|
void print_recv(const struct setting *settings, const struct icmphdr *header, const struct timeval *start, const struct timeval *stop, struct sockaddr_in const *sender);
|
||||||
Reference in New Issue
Block a user