mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:57:44 +00:00
Ping: Add TTL config option and value to output
This change adds the TTL value of the inbound packet to the output of the userland ping program, bringing it more in line with other common ping utilities. It also adds the (optional) -t option to configure the TTL of the outgoing packet if desired.
This commit is contained in:
parent
16fcbe555e
commit
4ed7456486
1 changed files with 13 additions and 1 deletions
|
@ -33,6 +33,7 @@ static int max_ms;
|
|||
static DeprecatedString host;
|
||||
static int payload_size = -1;
|
||||
static bool quiet = false;
|
||||
static Optional<size_t> ttl;
|
||||
static timespec interval_timespec { .tv_sec = 1, .tv_nsec = 0 };
|
||||
// variable part of header can be 0 to 40 bytes
|
||||
// https://datatracker.ietf.org/doc/html/rfc791#section-3.1
|
||||
|
@ -90,6 +91,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
});
|
||||
args_parser.add_option(payload_size, "Amount of bytes to send as payload in the ECHO_REQUEST packets.", "size", 's', "size");
|
||||
args_parser.add_option(quiet, "Quiet mode. Only display summary when finished.", "quiet", 'q');
|
||||
args_parser.add_option(ttl, "Set the TTL (time-to-live) value on the ICMP packets.", nullptr, 't', "ttl");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
if (count.has_value() && (count.value() < 1 || count.value() > UINT32_MAX)) {
|
||||
|
@ -97,6 +99,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (ttl.has_value() && (ttl.value() < 1 || ttl.value() > 255)) {
|
||||
warnln("invalid TTL argument: '{}': out of range: 1 <= value <= 255", ttl.value());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (payload_size < 0) {
|
||||
// Use the default.
|
||||
payload_size = 32 - sizeof(struct icmphdr);
|
||||
|
@ -112,6 +119,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
};
|
||||
|
||||
TRY(Core::System::setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)));
|
||||
if (ttl.has_value()) {
|
||||
TRY(Core::System::setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl.value(), sizeof(ttl.value())));
|
||||
}
|
||||
|
||||
auto* hostent = gethostbyname(host.characters());
|
||||
if (!hostent) {
|
||||
|
@ -170,6 +180,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
auto& pong_packet = pong_packet_result.value();
|
||||
socklen_t peer_address_size = sizeof(peer_address);
|
||||
auto result = Core::System::recvfrom(fd, pong_packet.data(), pong_packet.size(), 0, (struct sockaddr*)&peer_address, &peer_address_size);
|
||||
uint8_t const pong_ttl = pong_packet[8];
|
||||
if (result.is_error()) {
|
||||
if (result.error().code() == EAGAIN) {
|
||||
if (!quiet)
|
||||
|
@ -220,11 +231,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
char addr_buf[INET_ADDRSTRLEN];
|
||||
if (!quiet)
|
||||
outln("Pong from {}: id={}, seq={}{}, time={}ms, size={}",
|
||||
outln("Pong from {}: id={}, seq={}{}, ttl={}, time={}ms, size={}",
|
||||
inet_ntop(AF_INET, &peer_address.sin_addr, addr_buf, sizeof(addr_buf)),
|
||||
ntohs(pong_hdr->un.echo.id),
|
||||
ntohs(pong_hdr->un.echo.sequence),
|
||||
pong_hdr->un.echo.sequence != ping_hdr->un.echo.sequence ? "(!)" : "",
|
||||
pong_ttl,
|
||||
ms, result.value());
|
||||
|
||||
// If this was a response to an earlier packet, we still need to wait for the current one.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue