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
This commit is contained in:
Crist J. Clark 2006-05-11 06:30:18 +00:00
parent b776843c9e
commit a719d3b931
2 changed files with 21 additions and 9 deletions

View File

@ -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

View File

@ -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