add: error message
This commit is contained in:
126
src/main.c
126
src/main.c
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user