Skip to content

Commit

Permalink
Add --interface command line option
Browse files Browse the repository at this point in the history
Passing --interface will force the packets through the specified
interface instead of the default one.

Signed-off-by: Andrea Barberio <[email protected]>
  • Loading branch information
insomniacslk committed Apr 5, 2020
1 parent 2079431 commit 33c99a1
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 26 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
*.dylib
build
go/dublintraceroute/cmd/dublin-traceroute/dublin-traceroute
go/dublintraceroute/cmd/routest/routest
.travis/trace.json
integ/trace.json
18 changes: 13 additions & 5 deletions include/dublintraceroute/dublin_traceroute.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DublinTraceroute {
const bool broken_nat_,
use_srcport_for_path_generation_,
no_dns_;
std::string interface_;
std::mutex mutex_tracerouting,
mutex_sniffed_packets;
IPv4Address my_address;
Expand All @@ -67,6 +68,7 @@ class DublinTraceroute {
static const bool default_broken_nat = false;
static const bool default_use_srcport_for_path_generation = false;
static const bool default_no_dns = false;
static const std::string default_interface;
DublinTraceroute(
const std::string &dst,
const uint16_t srcport = default_srcport,
Expand All @@ -77,7 +79,8 @@ class DublinTraceroute {
const uint16_t delay = default_delay,
const bool broken_nat = default_broken_nat,
const bool use_srcport_for_path_generation = default_use_srcport_for_path_generation,
const bool no_dns = default_no_dns
const bool no_dns = default_no_dns,
const std::string interface = default_interface
):
srcport_(srcport),
dstport_(dstport),
Expand All @@ -88,7 +91,8 @@ class DublinTraceroute {
delay_(delay),
broken_nat_(broken_nat),
use_srcport_for_path_generation_(use_srcport_for_path_generation),
no_dns_(no_dns)
no_dns_(no_dns),
interface_(interface)
{ validate_arguments(); }
DublinTraceroute(
const char *dst,
Expand All @@ -100,7 +104,8 @@ class DublinTraceroute {
const uint16_t delay = default_delay,
const bool broken_nat = default_broken_nat,
const bool use_srcport_for_path_generation = default_use_srcport_for_path_generation,
const bool no_dns = default_no_dns
const bool no_dns = default_no_dns,
const std::string interface = default_interface
):
srcport_(srcport),
dstport_(dstport),
Expand All @@ -111,7 +116,8 @@ class DublinTraceroute {
delay_(delay),
broken_nat_(broken_nat),
use_srcport_for_path_generation_(use_srcport_for_path_generation),
no_dns_(no_dns)
no_dns_(no_dns),
interface_(interface)
{ validate_arguments(); }
~DublinTraceroute() { std::lock_guard<std::mutex> lock(mutex_tracerouting); };
DublinTraceroute(const DublinTraceroute& source):
Expand All @@ -124,7 +130,8 @@ class DublinTraceroute {
delay_(source.delay_),
broken_nat_(source.broken_nat_),
use_srcport_for_path_generation_(source.use_srcport_for_path_generation_),
no_dns_(source.no_dns_)
no_dns_(source.no_dns_),
interface_(source.interface_)
{ validate_arguments(); }

inline const uint16_t srcport() const { return srcport_; }
Expand All @@ -135,6 +142,7 @@ class DublinTraceroute {
inline const uint16_t delay() const { return delay_; }
inline const bool broken_nat() const { return broken_nat_; }
inline const bool no_dns() const { return no_dns_; }
inline const std::string interface() const { return interface_; }
inline const bool use_srcport_for_path_generation() const { return use_srcport_for_path_generation_; }
inline const std::string &dst() const { return dst_; }
inline const IPv4Address &target() const { return target_; }
Expand Down
4 changes: 4 additions & 0 deletions include/dublintraceroute/udpv4probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class UDPv4Probe {
uint16_t local_port_;
uint16_t remote_port_;
uint8_t ttl_;
std::string interface_;
IP *packet = nullptr;

public:
Expand All @@ -33,17 +34,20 @@ class UDPv4Probe {
const uint16_t local_port() const { return local_port_; };
const uint16_t remote_port() const { return remote_port_; };
const uint8_t ttl() const { return ttl_; };
const std::string interface() const { return interface_; };

UDPv4Probe(
IPv4Address remote_addr,
uint16_t remote_port,
uint16_t local_port,
uint8_t ttl,
std::string interface = "",
IPv4Address local_addr = 0):
remote_addr_(remote_addr),
remote_port_(remote_port),
local_port_(local_port),
ttl_(ttl),
interface_(interface),
local_addr_(local_addr) { };
~UDPv4Probe();
IP* forge();
Expand Down
6 changes: 4 additions & 2 deletions src/dublin_traceroute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ extern int errno;

#define SNIFFER_TIMEOUT_MS 2000

// this is not necessary in C++17 and can be assigned in the header file.
const std::string DublinTraceroute::default_interface = "";

Tins::Timestamp extract_timestamp_from_msg(struct msghdr &msg) {
int level, type;
Expand Down Expand Up @@ -218,10 +220,10 @@ std::shared_ptr<TracerouteResults> DublinTraceroute::traceroute() {

UDPv4Probe *probe = NULL;
if(use_srcport_for_path_generation()){
probe = new UDPv4Probe(target(), dstport(), iterated_port, ttl);
probe = new UDPv4Probe(target(), dstport(), iterated_port, ttl, interface());
}
else{
probe = new UDPv4Probe(target(), iterated_port, srcport(), ttl);
probe = new UDPv4Probe(target(), iterated_port, srcport(), ttl, interface());
//UDPv4Probe probe(target(), dport, srcport(), ttl);
}
IP *packet;
Expand Down
43 changes: 28 additions & 15 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const struct option longopts[] = {
{"broken-nat", no_argument, NULL, 'b'},
{"use-srcport", no_argument, NULL, 'i'},
{"no-dns", no_argument, NULL, 'N'},
{"interface", required_argument, NULL, 'I'},
{"output-file", required_argument, NULL, 'o'},
{NULL, 0, NULL, 0},
};
Expand All @@ -51,23 +52,25 @@ R"(Written by Andrea Barberio - https://insomniac.slackware.it
[--broken-nat]
[--use-srcport]
[--no-dns]
[--interface=ifname]
[--output-file=file_name]
[--help]
[--version]
Options:
-h --help this help
-v --version print the version of Dublin Traceroute
-s SRC_PORT --sport=SRC_PORT the source port to send packets from (default: )" << DublinTraceroute::default_srcport << R"()
-d DST_PORT --dport=DST_PORT the base destination port to send packets to (default: )" << DublinTraceroute::default_dstport << R"()
-n NPATHS --npaths=NPATHS the number of paths to probe (default: )" << static_cast<int>(DublinTraceroute::default_npaths) << R"()
-t MIN_TTL --min-ttl=MIN_TTL the minimum TTL to probe (default: )" << static_cast<int>(DublinTraceroute::default_min_ttl) << R"()
-T MAX_TTL --max-ttl=MAX_TTL the maximum TTL to probe. Must be greater or equal than the minimum TTL (default: )" << static_cast<int>(DublinTraceroute::default_max_ttl) << R"()
-D DELAY --delay=DELAY the inter-packet delay in milliseconds (default: )" << DublinTraceroute::default_delay << R"()
-b --broken-nat the network has a broken NAT configuration (e.g. no payload fixup). Try this if you see fewer hops than expected
-i --use-srcport generate paths using source port instead of destination port
-N --no-dns do not attempt to do reverse DNS lookup of the hops
-o --output-file the output file name (default: )" << DEFAULT_OUTPUT_FILE << R"()
-h, --help this help
-v, --version print the version of Dublin Traceroute
-s, --sport=SRC_PORT the source port to send packets from (default: )" << DublinTraceroute::default_srcport << R"()
-d, --dport=DST_PORT the base destination port to send packets to (default: )" << DublinTraceroute::default_dstport << R"()
-n, --npaths=NPATHS the number of paths to probe (default: )" << static_cast<int>(DublinTraceroute::default_npaths) << R"()
-t, --min-ttl=MIN_TTL the minimum TTL to probe (default: )" << static_cast<int>(DublinTraceroute::default_min_ttl) << R"()
-T, --max-ttl=MAX_TTL the maximum TTL to probe. Must be greater or equal than the minimum TTL (default: )" << static_cast<int>(DublinTraceroute::default_max_ttl) << R"()
-D, --delay=DELAY the inter-packet delay in milliseconds (default: )" << DublinTraceroute::default_delay << R"()
-b, --broken-nat the network has a broken NAT configuration (e.g. no payload fixup). Try this if you see fewer hops than expected
-i, --use-srcport generate paths using source port instead of destination port
-N, --no-dns do not attempt to do reverse DNS lookup of the hops
-I, --interface=INTERFACE force packets through the specified interface. If not specified, the default interface for the target will be used
-o, --output-file=OUTFILE the output file name (default: )" << DEFAULT_OUTPUT_FILE << R"()
See documentation at https://dublin-traceroute.net
Expand All @@ -89,6 +92,7 @@ main(int argc, char **argv) {
bool broken_nat = DublinTraceroute::default_broken_nat;
bool use_srcport_for_path_generation = DublinTraceroute::default_use_srcport_for_path_generation;
bool no_dns = DublinTraceroute::default_no_dns;
std::string interface = DublinTraceroute::default_interface;
std::string output_file = DEFAULT_OUTPUT_FILE;

if (geteuid() == 0) {
Expand Down Expand Up @@ -143,6 +147,9 @@ main(int argc, char **argv) {
case 'N':
no_dns = true;
break;
case 'I':
interface = optarg;
break;
case 'o':
output_file.assign(optarg);
break;
Expand Down Expand Up @@ -215,18 +222,24 @@ main(int argc, char **argv) {
delay,
broken_nat,
use_srcport_for_path_generation,
no_dns
no_dns,
interface
);

std::cout << "Traceroute from 0.0.0.0:" << Dublin.srcport();
if(use_srcport_for_path_generation == 1){
if (use_srcport_for_path_generation == 1){
std::cout << "~" << (Dublin.srcport() + npaths - 1);
}

std::cout << " to " << Dublin.dst() << ":" << Dublin.dstport();
if(use_srcport_for_path_generation == 0){
if (use_srcport_for_path_generation == 0){
std::cout << "~" << (Dublin.dstport() + npaths - 1);
}
if (interface != "") {
std::cout << " through interface " << interface;
} else {
std::cout << " through default interface";
}

std::cout << " (probing " << npaths << " path" << (npaths == 1 ? "" : "s")
<< ", min TTL is " << min_ttl
Expand Down
7 changes: 5 additions & 2 deletions src/udpv4probe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,15 @@ IP* UDPv4Probe::forge() {
}

IP &UDPv4Probe::send() {
NetworkInterface iface = NetworkInterface::default_interface();
std::string ifname = NetworkInterface::default_interface().name();
if (interface_ != "") {
ifname = interface_;
}
PacketSender sender;
if (packet == nullptr) {
packet = forge();
}
sender.send(*packet, iface.name());
sender.send(*packet, ifname);
return *packet;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/src/udpv4.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class UDPv4Test: public ::testing::Test {
};

TEST_F(UDPv4Test, TestUDPv4Constructor) {
UDPv4Probe p = UDPv4Probe(IPv4Address("8.8.8.8"), 33434, 12345, 64, IPv4Address("127.0.0.2"));
UDPv4Probe p = UDPv4Probe(IPv4Address("8.8.8.8"), 33434, 12345, 64, "", IPv4Address("127.0.0.2"));
ASSERT_EQ(p.local_port(), 12345);
ASSERT_EQ(p.remote_port(), 33434);
ASSERT_EQ(p.ttl(), 64);
Expand All @@ -30,7 +30,7 @@ TEST_F(UDPv4Test, TestUDPv4ConstructorDefaultLocalAddr) {
}

TEST_F(UDPv4Test, TestUDPv4PacketForging) {
UDPv4Probe p = UDPv4Probe(IPv4Address("127.0.0.3"), 33434, 12345, 64, IPv4Address("127.0.0.2"));
UDPv4Probe p = UDPv4Probe(IPv4Address("127.0.0.3"), 33434, 12345, 64, "", IPv4Address("127.0.0.2"));
IP* ip = p.forge();
ASSERT_EQ(ip->tos(), 0);
ASSERT_EQ(ip->id(), 60794);
Expand Down

0 comments on commit 33c99a1

Please sign in to comment.