1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-08 05:31:31 +00:00

Added Zhao changes which cause packet-trace to print tcp ops, slight changes to new os detection, and update fingerfix.pl for recent os detection changes

This commit is contained in:
fyodor
2006-08-20 18:17:03 +00:00
parent cd233fca26
commit 1da53c8366
4 changed files with 212 additions and 48 deletions

View File

@@ -2,7 +2,7 @@
4.20ALPHA5 4.20ALPHA5
o Worked with Zhao to improve the new OS detection system with o Worked with Zhao to improve the new OS detection system with
better algorithms and bug fixes. better algorithms, some probe changes, and some bug fixes.
o Nmap now uses the (relatively) new libpcap pcap_get_selectable_fd o Nmap now uses the (relatively) new libpcap pcap_get_selectable_fd
API on systems which support it. This means that we no longer need API on systems which support it. This means that we no longer need

View File

@@ -2,7 +2,7 @@
.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" It was generated using the DocBook XSL Stylesheets (version 1.69.1).
.\" Instead of manually editing it, you probably should edit the DocBook XML .\" Instead of manually editing it, you probably should edit the DocBook XML
.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .\" source for it and then use the DocBook XSL Stylesheets to regenerate it.
.TH "NMAP" "1" "08/16/2006" "" "Nmap Reference Guide" .TH "NMAP" "1" "08/19/2006" "" "Nmap Reference Guide"
.\" disable hyphenation .\" disable hyphenation
.nh .nh
.\" disable justification (adjust text to left margin only) .\" disable justification (adjust text to left margin only)

View File

@@ -301,7 +301,7 @@ public:
private: private:
/* Ports of the targets used in os fingerprinting. */ /* Ports of the targets used in os fingerprinting. */
unsigned long openTCPPort, closedTCPPort, closedUDPPort; int openTCPPort, closedTCPPort, closedUDPPort;
/* Probe list used in tests. At first, probes are linked in /* Probe list used in tests. At first, probes are linked in
* probesToSend; when a probe is sent, it will be removed from * probesToSend; when a probe is sent, it will be removed from
@@ -567,9 +567,9 @@ HostOsScanStats::HostOsScanStats(Target * t) {
target = t; target = t;
FP = NULL; FP = NULL;
openTCPPort = (unsigned int)-1; openTCPPort = -1;
closedTCPPort = (unsigned int)-1; closedTCPPort = -1;
closedUDPPort = (unsigned int)-1; closedUDPPort = -1;
num_probes_sent = 0; num_probes_sent = 0;
sendDelayMs = MAX(o.scan_delay, OS_PROBE_DELAY); sendDelayMs = MAX(o.scan_delay, OS_PROBE_DELAY);
@@ -631,7 +631,7 @@ void HostOsScanStats::initScanStats() {
int i; int i;
/* Lets find an open port to use if we don't already have one */ /* Lets find an open port to use if we don't already have one */
openTCPPort = (unsigned long) -1; openTCPPort = -1;
/* target->FPR->osscan_opentcpport = -1; /* target->FPR->osscan_opentcpport = -1;
target->FPR->osscan_closedtcpport = -1; target->FPR->osscan_closedtcpport = -1;
target->FPR->osscan_closedudpport = -1; */ target->FPR->osscan_closedudpport = -1; */
@@ -694,8 +694,8 @@ void HostOsScanStats::initScanStats() {
closedUDPPort = (get_random_uint() % 14781) + 30000; closedUDPPort = (get_random_uint() % 14781) + 30000;
} }
if (o.verbose && openTCPPort != (unsigned long) -1) if (o.verbose && openTCPPort != -1)
log_write(LOG_STDOUT, "OSScan against host %s: assuming TCP port %lu is open, %lu is closed, UDP port %lu is closed and none is firewalled\n", log_write(LOG_STDOUT, "OSScan against host %s: assuming TCP port %d is open, %d is closed, UDP port %d is closed and none is firewalled\n",
target->targetipstr(), openTCPPort, closedTCPPort, closedUDPPort); target->targetipstr(), openTCPPort, closedTCPPort, closedUDPPort);
FP = NULL; FP = NULL;
@@ -933,7 +933,7 @@ void HostOsScan::reInitScanSystem() {
void HostOsScan::buildSeqProbeList(HostOsScanStats *hss) { void HostOsScan::buildSeqProbeList(HostOsScanStats *hss) {
assert(hss); assert(hss);
int i; int i;
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
if(hss->FP_TSeq) return; if(hss->FP_TSeq) return;
for(i=0; i<NUM_SEQ_SAMPLES; i++) for(i=0; i<NUM_SEQ_SAMPLES; i++)
@@ -989,7 +989,7 @@ void HostOsScan::buildTUIProbeList(HostOsScanStats *hss) {
hss->addNewProbe(OFP_TUDP, 0); hss->addNewProbe(OFP_TUDP, 0);
} }
if(hss->openTCPPort != (unsigned long)-1) { if(hss->openTCPPort != -1) {
/* tops/twin probes. We send the probe again if we didn't get a /* tops/twin probes. We send the probe again if we didn't get a
response by the corresponding seq probe. response by the corresponding seq probe.
*/ */
@@ -1254,7 +1254,7 @@ void HostOsScan::sendTSeqProbe(HostOsScanStats *hss, int probeNo) {
assert(hss); assert(hss);
assert(probeNo >= 0 && probeNo < NUM_SEQ_SAMPLES); assert(probeNo >= 0 && probeNo < NUM_SEQ_SAMPLES);
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
tcpPortBase + probeNo, hss->openTCPPort, tcpPortBase + probeNo, hss->openTCPPort,
@@ -1269,21 +1269,24 @@ void HostOsScan::sendTOpsProbe(HostOsScanStats *hss, int probeNo) {
assert(hss); assert(hss);
assert(probeNo>=0 && probeNo< NUM_SEQ_SAMPLES); assert(probeNo>=0 && probeNo< NUM_SEQ_SAMPLES);
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
tcpPortBase + NUM_SEQ_SAMPLES + probeNo, hss->openTCPPort, tcpSeqBase, tcpPortBase + NUM_SEQ_SAMPLES + probeNo,
tcpAck, 0, TH_SYN, prbWindowSz[probeNo], 0, prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0); hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN,
prbWindowSz[probeNo], 0, prbOpts[probeNo].val,
prbOpts[probeNo].len, NULL, 0);
} }
void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) { void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) {
assert(hss); assert(hss);
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort, tcpSeqBase, 0, 8, tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort,
TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6], 63477, prbOpts[6].val, prbOpts[6].len, NULL, 0); tcpSeqBase, 0, 8, TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6],
63477, prbOpts[6].val, prbOpts[6].len, NULL, 0);
} }
void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) { void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
@@ -1294,51 +1297,51 @@ void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
switch(probeNo) { switch(probeNo) {
case 0: /* T1 */ case 0: /* T1 */
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
port_base, hss->openTCPPort, tcpSeqBase, tcpAck, 0, port_base, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
TH_SYN, prbWindowSz[0], 0, prbOpts[0].val, TH_SYN, prbWindowSz[0], 0, prbOpts[0].val,
prbOpts[0].len, NULL, 0); prbOpts[0].len, NULL, 0);
break; break;
case 1: /* T2 */ case 1: /* T2 */
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true,
port_base + 1, hss->openTCPPort, tcpSeqBase, tcpAck, 0, port_base + 1, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
0, prbWindowSz[7], 0, prbOpts[7].val, prbOpts[7].len, NULL, 0); 0, prbWindowSz[7], 0, prbOpts[7].val, prbOpts[7].len, NULL, 0);
break; break;
case 2: /* T3 */ case 2: /* T3 */
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
port_base + 2, hss->openTCPPort, tcpSeqBase, tcpAck, 0, port_base + 2, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0, TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0,
prbOpts[8].val, prbOpts[8].len, NULL, 0); prbOpts[8].val, prbOpts[8].len, NULL, 0);
break; break;
case 3: /* T4 */ case 3: /* T4 */
if(hss->openTCPPort == (unsigned long)-1) return; if(hss->openTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true,
port_base + 3, hss->openTCPPort, tcpSeqBase, tcpAck, 0, port_base + 3, hss->openTCPPort, tcpSeqBase, tcpAck, 0,
TH_ACK, prbWindowSz[9], 0, prbOpts[9].val, TH_ACK, prbWindowSz[9], 0, prbOpts[9].val,
prbOpts[9].len, NULL, 0); prbOpts[9].len, NULL, 0);
break; break;
case 4: /* T5 */ case 4: /* T5 */
if(hss->closedTCPPort == (unsigned long)-1) return; if(hss->closedTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
port_base + 4, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, port_base + 4, hss->closedTCPPort, tcpSeqBase, tcpAck,
TH_SYN, prbWindowSz[10], 0, prbOpts[10].val, 0, TH_SYN, prbWindowSz[10], 0, prbOpts[10].val,
prbOpts[10].len, NULL, 0); prbOpts[10].len, NULL, 0);
break; break;
case 5: /* T6 */ case 5: /* T6 */
if(hss->closedTCPPort == (unsigned long)-1) return; if(hss->closedTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true,
port_base + 5, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, port_base + 5, hss->closedTCPPort, tcpSeqBase, tcpAck,
TH_ACK, prbWindowSz[11], 0, prbOpts[11].val, 0, TH_ACK, prbWindowSz[11], 0, prbOpts[11].val,
prbOpts[11].len, NULL, 0); prbOpts[11].len, NULL, 0);
break; break;
case 6: /* T7 */ case 6: /* T7 */
if(hss->closedTCPPort == (unsigned long)-1) return; if(hss->closedTCPPort == -1) return;
send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false,
port_base + 6, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, port_base + 6, hss->closedTCPPort, tcpSeqBase, tcpAck,
TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0, 0, TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0,
prbOpts[12].val, prbOpts[12].len, NULL, 0); prbOpts[12].val, prbOpts[12].len, NULL, 0);
break; break;
} }
@@ -1360,7 +1363,7 @@ void HostOsScan::sendTIcmpProbe(HostOsScanStats *hss, int probeNo) {
void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) { void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) {
assert(hss); assert(hss);
if(hss->closedUDPPort == (unsigned long)-1) return; if(hss->closedUDPPort == -1) return;
send_closedudp_probe_2(hss->upi, rawsd, ethptr, hss->target->v4hostip(), send_closedudp_probe_2(hss->upi, rawsd, ethptr, hss->target->v4hostip(),
this->udpttl, udpPortBase + probeNo, this->udpttl, udpPortBase + probeNo,
hss->closedUDPPort); hss->closedUDPPort);
@@ -1511,7 +1514,10 @@ void HostOsScan::makeFP(HostOsScanStats *hss) {
makeTWinFP(hss); makeTWinFP(hss);
for(i=3; i < NUM_FPTESTS; i++) { for(i=3; i < NUM_FPTESTS; i++) {
if (!hss->FPtests[i] && ((hss->openTCPPort != (unsigned long) -1) || i > 7)) { if (!hss->FPtests[i] &&
((i>=3 && i<=7 && hss->openTCPPort != -1) ||
(i>=8 && i<=10 && hss->target->FPR->osscan_closedtcpport != -1) ||
i>=11)) {
/* We create a Resp (response) attribute with value of N (no) because /* We create a Resp (response) attribute with value of N (no) because
it is important here to note whether responses were or were not it is important here to note whether responses were or were not
received */ received */
@@ -1976,7 +1982,7 @@ bool HostOsScan::processTSeqResp(HostOsScanStats *hss, struct ip *ip, int replyN
if ((tcp->th_flags & TH_RST)) { if ((tcp->th_flags & TH_RST)) {
if (hss->si.responses == 0) { if (hss->si.responses == 0) {
fprintf(stderr, "WARNING: RST from %s port %lu -- is this port really open?\n", fprintf(stderr, "WARNING: RST from %s port %d -- is this port really open?\n",
hss->target->targetipstr(), hss->openTCPPort); hss->target->targetipstr(), hss->openTCPPort);
} }
return false; return false;
@@ -2476,7 +2482,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, struct ip *ip) {
checksum = *checksumptr; checksum = *checksumptr;
if (checksum == 0) if (checksum == 0)
strcpy(AVs[current_testno].value, "0"); strcpy(AVs[current_testno].value, "Z");
else { else {
*checksumptr = 0; *checksumptr = 0;
if (in_cksum((unsigned short *)ip2, 20) == checksum) { if (in_cksum((unsigned short *)ip2, 20) == checksum) {

184
tcpip.cc
View File

@@ -262,6 +262,142 @@ void PacketTrace::traceArp(pdirection pdir, const u8 *frame, u32 len,
return; return;
} }
/* Get an ASCII information about a tcp option which is pointed by
optp, with a length of len. The result is stored in the result
buffer. The result may look like "<mss 1452,sackOK,timestamp
45848914 0,nop,wscale 7>" */
static void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize) {
assert(optp);
assert(result);
char *p, ch;
u8 *q;
int opcode;
u16 tmpshort;
u32 tmpword1, tmpword2;
p = result; *p = '\0';
q = optp;
ch = '<';
while(len > 0 && bufsize > 2) {
snprintf(p, bufsize, "%c", ch);
bufsize--;
p++;
opcode=*q++;
if (!opcode) { /* End of List */
snprintf(p, bufsize, "eol");
bufsize -= strlen(p);
p += strlen(p);
len--;
} else if (opcode == 1) { /* No Op */
snprintf(p, bufsize, "nop");
bufsize -= strlen(p);
p += strlen(p);
len--;
} else if (opcode == 2) { /* MSS */
if(len<4)
break; /* MSS has 4 bytes */
q++;
memcpy(&tmpshort, q, 2);
snprintf(p, bufsize, "mss %u", ntohs(tmpshort));
bufsize -= strlen(p);
p += strlen(p);
q += 2;
len -= 4;
} else if (opcode == 3) { /* Window Scale */
if(len<3)
break; /* Window Scale option has 3 bytes */
q++;
snprintf(p, bufsize, "wsacle %u", *q);
bufsize -= strlen(p);
p += strlen(p);
q++;
len -= 3;
} else if (opcode == 4) { /* SACK permitted */
if(len<2)
break; /* SACK permitted option has 2 bytes */
snprintf(p, bufsize, "sackOK");
bufsize -= strlen(p);
p += strlen(p);
q++;
len -= 2;
} else if (opcode == 5) { /* SACK */
int sackoptlen = *q;
if(len < sackoptlen)
break;
q++;
if((sackoptlen-2) % 8 != 0) {
snprintf(p, bufsize, "malformed sack");
bufsize -= strlen(p);
p += strlen(p);
} else {
snprintf(p, bufsize, "sack %d ", (sackoptlen-2)/8);
bufsize -= strlen(p);
p += strlen(p);
for(int i = 0; i < sackoptlen - 2; i += 8) {
memcpy(&tmpword1, q + i, 4);
memcpy(&tmpword2, q + i + 4, 4);
snprintf(p, bufsize, "{%u:%u}", tmpword1, tmpword2);
bufsize -= strlen(p);
p += strlen(p);
}
}
q += sackoptlen-2;
len -= sackoptlen;
} else if (opcode == 8) { /* Timestamp */
if(len<10)
break; /* Timestamp option has 10 bytes */
q++;
memcpy(&tmpword1, q, 4);
memcpy(&tmpword2, q+4, 4);
snprintf(p, bufsize, "timestamp %u %u", ntohl(tmpword1), ntohl(tmpword2));
bufsize -= strlen(p);
p += strlen(p);
q += 8;
len -= 10;
}
ch = ',';
}
if(len > 0) {
*result = '\0';
return;
}
snprintf(p, bufsize, ">");
}
/* Returns a buffer of ASCII information about a packet that may look /* Returns a buffer of ASCII information about a packet that may look
like "TCP 127.0.0.1:50923 > 127.0.0.1:3 S ttl=61 id=39516 iplen=40 like "TCP 127.0.0.1:50923 > 127.0.0.1:3 S ttl=61 id=39516 iplen=40
seq=625950769" or "ICMP PING (0/1) ttl=61 id=39516 iplen=40". seq=625950769" or "ICMP PING (0/1) ttl=61 id=39516 iplen=40".
@@ -269,7 +405,7 @@ void PacketTrace::traceArp(pdirection pdir, const u8 *frame, u32 len,
within (say) printf(). And certainly don't try to free() it! The within (say) printf(). And certainly don't try to free() it! The
returned buffer is NUL-terminated */ returned buffer is NUL-terminated */
static const char *ippackethdrinfo(const u8 *packet, u32 len) { static const char *ippackethdrinfo(const u8 *packet, u32 len) {
static char protoinfo[256]; static char protoinfo[512];
struct ip *ip = (struct ip *) packet; struct ip *ip = (struct ip *) packet;
struct tcphdr *tcp; struct tcphdr *tcp;
udphdr_bsd *udp; udphdr_bsd *udp;
@@ -279,7 +415,6 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
struct in_addr saddr, daddr; struct in_addr saddr, daddr;
int frag_off = 0, more_fragments = 0; int frag_off = 0, more_fragments = 0;
char fragnfo[64] = ""; char fragnfo[64] = "";
char tflags[10];
if (ip->ip_v != 4) if (ip->ip_v != 4)
return "BOGUS! IP Version in packet is not 4"; return "BOGUS! IP Version in packet is not 4";
@@ -303,12 +438,15 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
ip->ip_ttl, ntohs(ip->ip_id), ntohs(ip->ip_len), fragnfo); ip->ip_ttl, ntohs(ip->ip_id), ntohs(ip->ip_len), fragnfo);
if (ip->ip_p == IPPROTO_TCP) { if (ip->ip_p == IPPROTO_TCP) {
char tflags[10];
char tcpinfo[64] = ""; char tcpinfo[64] = "";
char buf[32]; char buf[32];
char tcpoptinfo[256] = "";
tcp = (struct tcphdr *) (packet + ip->ip_hl * 4); tcp = (struct tcphdr *) (packet + ip->ip_hl * 4);
if (frag_off > 8 || len < (u32) ip->ip_hl * 4 + 8) if (frag_off > 8 || len < (u32) ip->ip_hl * 4 + 8)
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? ?? %s (incomplete)", srchost, dsthost, ipinfo); snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? ?? %s (incomplete)", srchost, dsthost, ipinfo);
else if (frag_off == 8 && len >= (u32) ip->ip_hl * 4 + 8) {// we can get TCP flags and ACKn else if (frag_off == 8) {// at least we can get TCP flags and ACKn
tcp = (struct tcphdr *)((u8 *) tcp - frag_off); // ugly? tcp = (struct tcphdr *)((u8 *) tcp - frag_off); // ugly?
p = tflags; p = tflags;
/* These are basically in tcpdump order */ /* These are basically in tcpdump order */
@@ -326,17 +464,25 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
if (tcp->th_flags & TH_CWR) *p++ = 'C'; /* rfc 2481/3168 */ if (tcp->th_flags & TH_CWR) *p++ = 'C'; /* rfc 2481/3168 */
*p++ = '\0'; *p++ = '\0';
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? %s %s %s", if((u32) tcp->th_off * 4 > sizeof(struct tcphdr)) {
srchost, dsthost, tflags, ipinfo, tcpinfo); // tcp options
} else if (len < (u32) ip->ip_hl * 4 + 16) { // we can get ports an seq if(len < (u32) ip->ip_hl * 4 + (u32) tcp->th_off * 4 - frag_off) {
snprintf(tcpoptinfo, sizeof(tcpoptinfo), "option incomplete");
} else {
tcppacketoptinfo((u8*) tcp + sizeof(struct tcphdr),
tcp->th_off*4 - sizeof(struct tcphdr),
tcpoptinfo, sizeof(tcpoptinfo));
}
}
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:?? > %s:?? %s %s %s %s",
srchost, dsthost, tflags, ipinfo, tcpinfo, tcpoptinfo);
} else if (len < (u32) ip->ip_hl * 4 + 16) { // we can get ports and seq
snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu (incomplete)", (unsigned long) ntohl(tcp->th_seq)); snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu (incomplete)", (unsigned long) ntohl(tcp->th_seq));
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:%d > %s:%d ?? %s %s", snprintf(protoinfo, sizeof(protoinfo), "TCP %s:%d > %s:%d ?? %s %s",
srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport), ipinfo, tcpinfo); srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport), ipinfo, tcpinfo);
} else if (len < (u32) ip->ip_hl * 4 + 16 && !frag_off) { // we can't get TCP flags } else { // at least first 16 bytes of TCP header are there
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:%d > %s:%d ?? %s %s (incomplete)",
srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport),
ipinfo, tcpinfo);
} else { // at least first 16 bytes of TCP header are there (everything we need)
snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu win=%hi", snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu win=%hi",
(unsigned long) ntohl(tcp->th_seq), (unsigned long) ntohl(tcp->th_seq),
@@ -358,9 +504,21 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) {
if (tcp->th_flags & TH_CWR) *p++ = 'C'; /* rfc 2481/3168 */ if (tcp->th_flags & TH_CWR) *p++ = 'C'; /* rfc 2481/3168 */
*p++ = '\0'; *p++ = '\0';
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:%d > %s:%d %s %s %s", if((u32) tcp->th_off * 4 > sizeof(struct tcphdr)) {
// tcp options
if(len < (u32) ip->ip_hl * 4 + (u32) tcp->th_off * 4) {
snprintf(tcpoptinfo, sizeof(tcpoptinfo), "option incomplete");
} else {
tcppacketoptinfo((u8*) tcp + sizeof(struct tcphdr),
tcp->th_off*4 - sizeof(struct tcphdr),
tcpoptinfo, sizeof(tcpoptinfo));
}
}
snprintf(protoinfo, sizeof(protoinfo), "TCP %s:%d > %s:%d %s %s %s %s",
srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport), srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport),
tflags, ipinfo, tcpinfo); tflags, ipinfo, tcpinfo, tcpoptinfo);
} }
} else if (ip->ip_p == IPPROTO_UDP && frag_off) { } else if (ip->ip_p == IPPROTO_UDP && frag_off) {
snprintf(protoinfo, sizeof(protoinfo), "UDP %s:?? > %s:?? fragment %s (incomplete)", srchost, dsthost, ipinfo); snprintf(protoinfo, sizeof(protoinfo), "UDP %s:?? > %s:?? fragment %s (incomplete)", srchost, dsthost, ipinfo);