add: implement ttl
This commit is contained in:
88
src/main.c
88
src/main.c
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
|
|
||||||
void signal_handler(int code)
|
static void signal_handler(int code)
|
||||||
{
|
{
|
||||||
(void) code;
|
(void) code;
|
||||||
loop = false;
|
loop = false;
|
||||||
@ -76,7 +76,6 @@ static int get_setting(char * const *av, struct setting *setting)
|
|||||||
{NULL, "v", OPTION, false},
|
{NULL, "v", OPTION, false},
|
||||||
{NULL, "f", OPTION, false},
|
{NULL, "f", OPTION, false},
|
||||||
{NULL, "n", OPTION, false},
|
{NULL, "n", OPTION, false},
|
||||||
{NULL, "W",ARGUMENT, "0"},
|
|
||||||
{"ttl", NULL, ARGUMENT, "116"},
|
{"ttl", NULL, ARGUMENT, "116"},
|
||||||
{NULL, "s", ARGUMENT, "56"},
|
{NULL, "s", ARGUMENT, "56"},
|
||||||
{NULL, NULL, 0, NULL},
|
{NULL, NULL, 0, NULL},
|
||||||
@ -90,12 +89,54 @@ static int get_setting(char * const *av, struct setting *setting)
|
|||||||
setting->verbose = parameters[1].value;
|
setting->verbose = parameters[1].value;
|
||||||
setting->flood = parameters[2].value;
|
setting->flood = parameters[2].value;
|
||||||
setting->numeric_only = parameters[3].value;
|
setting->numeric_only = parameters[3].value;
|
||||||
if (parsing_number(parameters[4].value, 0, 2147483647, &setting->timeout))
|
size_t ttl;
|
||||||
return 1;
|
if (parsing_number(parameters[4].value, 0, 255, &ttl))
|
||||||
if (parsing_number(parameters[5].value, 0, 255, &setting->ttl))
|
|
||||||
return 2;
|
return 2;
|
||||||
if (parsing_number(parameters[6].value, 0, 2147483647, &setting->payload_size))
|
if (parsing_number(parameters[5].value, 0, 2147483647, &setting->payload_size))
|
||||||
return 3;
|
return 3;
|
||||||
|
setting->ttl = ttl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_socket(struct setting const *setting)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||||
|
|
||||||
|
if (sockfd == -1)
|
||||||
|
{
|
||||||
|
print_err("open socket failed, maybe try in root (:");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = setsockopt(sockfd, IPPROTO_IP, IP_TTL, &setting->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)
|
||||||
|
{
|
||||||
|
print_err("Failed to setsockopt(): recv timeout");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_destination(struct hostenv *host)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,22 +153,12 @@ int main(int ac, char **av)
|
|||||||
|
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if (dns_lookup(&settings.dest))
|
if (set_destination(&settings.dest))
|
||||||
return 5;
|
return 1;
|
||||||
|
|
||||||
settings.dest.ip.sin_family = AF_INET;
|
int sockfd = create_socket(&settings);
|
||||||
settings.dest.ip.sin_port = htons(0);
|
if (sockfd == -1)
|
||||||
inet_pton(AF_INET, settings.dest.ipstr, &settings.dest.ip.sin_addr);
|
|
||||||
|
|
||||||
dns_reverse_lookup(&settings.dest);
|
|
||||||
|
|
||||||
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
|
||||||
|
|
||||||
if (sockfd == -1)
|
|
||||||
{
|
|
||||||
print_err("open socket failed, maybe try in root (:");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
char *packet = packet_create(settings.payload_size);
|
char *packet = packet_create(settings.payload_size);
|
||||||
if (packet == NULL)
|
if (packet == NULL)
|
||||||
@ -166,9 +197,12 @@ int main(int ac, char **av)
|
|||||||
|
|
||||||
stats.packets_sent++;
|
stats.packets_sent++;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (recvfrom(sockfd, buffer, packet_size, 0, (struct sockaddr *) &sender, &len) < 0)
|
buffer[0] = 0;
|
||||||
|
ret = recvfrom(sockfd, buffer, packet_size, 0, (struct sockaddr *) &sender, &len) < 0;
|
||||||
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
print_err("error: receive packet failed.");
|
print_err("error: receive packet failed.");
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
@ -178,13 +212,13 @@ int main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
gettimeofday(&stop, NULL);
|
gettimeofday(&stop, NULL);
|
||||||
}
|
}
|
||||||
while (len == packet_size && packet_check(buffer, packet_size) == 0 && packet_compare(packet, buffer, packet_size) == 0);
|
while (!(ret == 1 && buffer[0] == '\0') || (len == packet_size && packet_check(buffer, packet_size) == 0 && packet_compare(packet, buffer, packet_size) == 0));
|
||||||
|
|
||||||
|
if (*buffer != 0)
|
||||||
|
{
|
||||||
stats.packets_received++;
|
stats.packets_received++;
|
||||||
|
print_recv(&settings, (struct icmphdr *)buffer, &start, &stop);
|
||||||
struct icmphdr *hdr = (struct icmphdr *) packet;
|
}
|
||||||
|
|
||||||
print_ping(&settings, hdr, &start, &stop);
|
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ void print_statistics(struct statistics const *stats, struct setting const *sett
|
|||||||
void print_recv(const struct setting *settings, const struct icmphdr *header, const struct timeval *start, const struct timeval *stop)
|
void print_recv(const struct setting *settings, const struct icmphdr *header, const struct timeval *start, const struct timeval *stop)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("%zu bytes from %s: icmp_seq=%d ttl=%zu time=%.3f ms\n",
|
printf("%zu bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms\n",
|
||||||
settings->payload_size + sizeof(struct icmphdr),
|
settings->payload_size + sizeof(struct icmphdr),
|
||||||
settings->dest.ipstr,
|
settings->dest.ipstr,
|
||||||
htons(header->un.echo.sequence),
|
htons(header->un.echo.sequence),
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ struct setting
|
|||||||
bool flood;
|
bool flood;
|
||||||
bool numeric_only;
|
bool numeric_only;
|
||||||
size_t timeout;
|
size_t timeout;
|
||||||
size_t ttl;
|
uint8_t ttl;
|
||||||
size_t payload_size;
|
size_t payload_size;
|
||||||
struct hostenv dest;
|
struct hostenv dest;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user