From 297aabd6d98b8a98d335289f4267f1134d1def38 Mon Sep 17 00:00:00 2001 From: cjc Date: Thu, 11 May 2006 06:30:18 +0000 Subject: Option for setting a fixed destination port. This is useful for tracing to a host behind a firewall where only specific services are allowed. For example, to trace the hops to an HTTP server behind a firewall, $ traceroute -e -P tcp -p 80 www-firewalled.example.com MFC after: 1 week --- contrib/traceroute/traceroute.8 | 7 ++++++- contrib/traceroute/traceroute.c | 23 +++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'contrib/traceroute') diff --git a/contrib/traceroute/traceroute.8 b/contrib/traceroute/traceroute.8 index 0955e23..cfd9959 100644 --- a/contrib/traceroute/traceroute.8 +++ b/contrib/traceroute/traceroute.8 @@ -24,7 +24,7 @@ traceroute \- print the route packets take to network host .na .B traceroute [ -.B \-dFISdnrvx +.B \-deFISdnrvx ] [ .B \-f .I first_ttl @@ -98,6 +98,11 @@ name. .PP Other options are: .TP +.B \-e +Firewall evasion mode. +Use fixed destination ports for UDP and TCP probes. +The destination port does NOT increment with each packet sent. +.TP .B \-f Set the initial time-to-live used in the first outgoing probe packet. .TP diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c index 7215ca0..e6182f4 100644 --- a/contrib/traceroute/traceroute.c +++ b/contrib/traceroute/traceroute.c @@ -353,6 +353,7 @@ int doipcksum = 0; /* don't calculate ip checksums by default */ int doipcksum = 1; /* calculate ip checksums by default */ #endif int optlen; /* length of ip options */ +int fixedPort = 0; /* Use fixed destination port for TCP and UDP */ extern int optind; extern int opterr; @@ -521,13 +522,17 @@ main(int argc, char **argv) prog = argv[0]; opterr = 0; - while ((op = getopt(argc, argv, "dFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF) + while ((op = getopt(argc, argv, "edFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF) switch (op) { case 'd': options |= SO_DEBUG; break; + case 'e': + fixedPort = 1; + break; + case 'f': case 'M': /* FreeBSD compat. */ first_ttl = str2val(optarg, "first ttl", 1, 255); @@ -1289,8 +1294,8 @@ udp_prep(struct outdata *outdata) { struct udphdr *const outudp = (struct udphdr *) outp; - outudp->uh_sport = htons(ident); - outudp->uh_dport = htons(port + outdata->seq); + outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0)); + outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq)); outudp->uh_ulen = htons((u_short)protlen); outudp->uh_sum = 0; if (doipcksum) { @@ -1306,8 +1311,8 @@ udp_check(const u_char *data, int seq) { struct udphdr *const udp = (struct udphdr *) data; - return (ntohs(udp->uh_sport) == ident - && ntohs(udp->uh_dport) == port + seq); + return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) && + ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq)); } void @@ -1316,8 +1321,9 @@ tcp_prep(struct outdata *outdata) struct tcphdr *const tcp = (struct tcphdr *) outp; tcp->th_sport = htons(ident); - tcp->th_dport = htons(port + outdata->seq); - tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport; + tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq)); + tcp->th_seq = (tcp->th_sport << 16) | (tcp->th_dport + + (fixedPort ? outdata->seq : 0)); tcp->th_ack = 0; tcp->th_off = 5; tcp->th_flags = TH_SYN; @@ -1335,7 +1341,8 @@ tcp_check(const u_char *data, int seq) struct tcphdr *const tcp = (struct tcphdr *) data; return (ntohs(tcp->th_sport) == ident - && ntohs(tcp->th_dport) == port + seq); + && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq)) + && tcp->th_seq == (ident << 16) | (port + seq); } void -- cgit v1.1