4#include "Stroika/Frameworks/StroikaPreComp.h"
8#include "Stroika/Foundation/Characters/String2Int.h"
10#include "Stroika/Foundation/Containers/Collection.h"
12#include "Stroika/Foundation/Execution/CommandLine.h"
16#include "Stroika/Frameworks/NetworkMonitor/Traceroute.h"
23using namespace Stroika::Foundation::IO::Network::InternetProtocol;
24using namespace Stroika::Foundation::Time;
25using namespace Stroika::Frameworks;
26using namespace Stroika::Frameworks::NetworkMonitor;
31int main (
int argc,
const char* argv[])
40 MajorOp majorOp = MajorOp::eTraceroute;
41 unsigned int maxHops = Ping::Options::kDefaultMaxHops;
42 unsigned int sampleCount = 3;
43 static const Duration kInterSampleTime_{
"PT.1S"};
44 size_t packetSize = Ping::Options::kDefaultPayloadSize +
sizeof (ICMP::V4::PacketHeader);
48 .fLongName =
"packetSize"sv, .fSupportsArgument =
true, .fHelpArgName =
"N", .fHelpOptionText =
"Number of bytes to send in each test packet"sv};
50 .fLongName =
"maxHops"sv, .fSupportsArgument =
true, .fHelpArgName =
"N", .fHelpOptionText =
"Max number of hops to get to the target address"sv};
52 .fLongName =
"sampleCount"sv,
53 .fSupportsArgument =
true,
54 .fHelpArgName =
"N"sv,
55 .fHelpOptionText =
"(default 3) - if sampleCount is 1, exception details shown, otherwise just summary of number of exceptions"sv};
58 using namespace Execution::StandardCommandLineOptions;
60 const initializer_list<Execution::CommandLine::Option> kAllOptions_{kHelp, kPingO_, kTraceRtO_, kPacketSizeO_,
61 kMaxHopsO_, kSampleCntO_, kTargetAddress_};
63 auto usage = [&] (
const optional<String>& extraArg = {}) {
65 cerr << *extraArg << endl;
67 cerr << Execution::CommandLine::GenerateUsage (
"traceroute"sv, kAllOptions_);
71 using namespace Execution::StandardCommandLineOptions;
73 if (cmdLine.Has (kPingO_)) {
74 majorOp = MajorOp::ePing;
76 if (cmdLine.Has (kTraceRtO_)) {
77 majorOp = MajorOp::eTraceroute;
79 if (
auto o = cmdLine.GetArgument (kPacketSizeO_)) {
80 packetSize = Characters::String2Int<unsigned int> (*o);
82 if (
auto o = cmdLine.GetArgument (kMaxHopsO_)) {
83 maxHops = Characters::String2Int<unsigned int> (*o);
85 if (
auto o = cmdLine.GetArgument (kSampleCntO_)) {
86 sampleCount = Characters::String2Int<unsigned int> (*o);
88 if (cmdLine.Has (kHelp)) {
92 targetAddress = cmdLine.GetArgument (kTargetAddress_).value_or (
String{});
95 cmdLine.Validate (kAllOptions_);
97 if (addrList.
empty ()) {
103 case MajorOp::ePing: {
104 Ping::Options options{};
105 options.fPacketPayloadSize = Ping::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize -
sizeof (ICMP::V4::PacketHeader));
106 options.fMaxHops = maxHops;
108 NetworkMonitor::Ping::SampleResults t =
109 NetworkMonitor::Ping::Sample (addr, Ping::SampleOptions{kInterSampleTime_, sampleCount}, options);
110 cout <<
"Ping to " << addr.
ToString () <<
": " << Characters::ToString (t) << endl;
112 case MajorOp::eTraceroute: {
113 Traceroute::Options options{};
114 options.fPacketPayloadSize = Traceroute::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize -
sizeof (ICMP::V4::PacketHeader));
115 options.fMaxHops = maxHops;
117 cout <<
"Tracing Route to " << targetAddress <<
" [" << Characters::ToString (addr) <<
"] over a maximum of " << maxHops
122 cout <<
"Hop\tTime\t\tAddress" << endl;
123 unsigned int hopIdx{1};
124 auto perHopCallback = [&] (Traceroute::Hop h) {
126 if (h.fAddress.empty ()) {
130 if (
auto rdnsName =
DNS::kThe.QuietReverseLookup (h.fAddress)) {
131 return *rdnsName +
" ["_k + addrStr +
"]"_k;
137 String timeStr = h.fTime.empty () ?
"timeout\t"_k : h.fTime.PrettyPrint ();
138 cout << hopIdx++ <<
"\t" << timeStr <<
"\t" << hopName << endl;
142 Traceroute::Run (addr, perHopCallback, options);
147 cerr <<
"Exception - " << Characters::ToString (current_exception ()) <<
" - terminating..." << endl;
#define Stroika_Foundation_Debug_OptionalizeTraceArgs(...)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Exception<> is a replacement (subclass) for any std c++ exception class (e.g. the default 'std::excep...
nonvirtual Sequence< InternetAddress > GetHostAddresses(const String &hostNameOrAddress) const
simple wrapper on GetHostEntry - looking up the hostname/ip address and returning the list of associa...
nonvirtual String ToString() const
Duration is a chrono::duration<double> (=.
nonvirtual T Nth(ptrdiff_t n) const
Find the Nth element of the Iterable<>
nonvirtual bool empty() const
Returns true iff size() == 0.