diff --git a/NmapOutputTable.cc b/NmapOutputTable.cc index 9bdb7aa16..498fe264f 100644 --- a/NmapOutputTable.cc +++ b/NmapOutputTable.cc @@ -241,13 +241,32 @@ int NmapOutputTable::printableSize() { } +/* True if every column in nrow is empty */ +bool NmapOutputTable::emptyRow(unsigned int nrow) { + NmapOutputTableCell *cell; + unsigned int col; + bool isEmpty = true; + + assert(nrow < numRows); + + for(col = 0 ; col < numColumns; col++) { + cell = getCellAddy(nrow, col); + if(cell->strlength > 0) { + isEmpty = false; + break; + } + } + return isEmpty; +} + // This function sticks the entire table into a character buffer. // Note that the buffer is likely to be reused if you call the // function again, and it will also be invalidated if you free the // table. If size is not NULL, it will be filled with the size of - // the ASCII table in bytes (not including the terminating NUL) - -char *NmapOutputTable::printableTable(int *size) { + // the ASCII table in bytes (not including the terminating NUL) + // If trim is true, excess empty rows are not returned + // +char *NmapOutputTable::internalPrintableTable(int *size, bool trim) { unsigned int col, row; int maxsz = printableSize(); char *p; @@ -265,6 +284,12 @@ char *NmapOutputTable::printableTable(int *size) { for(row = 0; row < numRows; row++) { validthisrow = 0; + /* If this was called by printableTrimmedTable + * (trim == true) we can ignore everything after an + * empty row */ + if(trim && emptyRow(row)) + break; + cell = getCellAddy(row, 0); if(cell->fullrow && cell->strlength > 0) { memcpy(p, cell->str, cell->strlength); @@ -291,3 +316,11 @@ char *NmapOutputTable::printableTable(int *size) { if (size) *size = p - tableout; return tableout; } + +char *NmapOutputTable::printableTable(int *size) { + return internalPrintableTable(size, false); +} + +char *NmapOutputTable::printableTrimmedTable(int *size) { + return internalPrintableTable(size, true); +} diff --git a/NmapOutputTable.h b/NmapOutputTable.h index 37d09fa67..ef62f9f00 100644 --- a/NmapOutputTable.h +++ b/NmapOutputTable.h @@ -148,8 +148,13 @@ class NmapOutputTable { // the ASCII table in bytes (not including the terminating NUL) char *printableTable(int *size); + // same as printableTable() but with excess empty rows removed + char *printableTrimmedTable(int *size); + private: + char *internalPrintableTable(int *size, bool trim); + bool emptyRow(unsigned int nrow); // The table, squished into 1D. Access a member via getCellAddy struct NmapOutputTableCell *table; struct NmapOutputTableCell *getCellAddy(unsigned int row, unsigned int col) { diff --git a/traceroute.cc b/traceroute.cc index 6752b1012..b929381ab 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -945,7 +945,6 @@ Traceroute::outputTarget (Target * t) { char row_count = 0; char timebuf[16]; u8 consol_count = 0; - u16 size; if ((TraceGroups.find (t->v4host ().s_addr)) == TraceGroups.end ()) return; @@ -959,20 +958,16 @@ Traceroute::outputTarget (Target * t) { /* clean up and consolidate traces */ tg->consolidateHops (); /* calculate length of table, post-consolidation */ - size = tg->tableSize (); this->outputXMLTrace(tg); /* table headers */ - Tbl = new NmapOutputTable (size, 3); + Tbl = new NmapOutputTable (tg->hopDistance+1, 3); Tbl->addItem (row_count, HOP_COL, false, "HOP", 3); Tbl->addItem (row_count, RTT_COL, false, "RTT", 3); Tbl->addItem (row_count, HOST_COL, false, "ADDRESS", 7); for (ttl_count = 1; ttl_count <= tg->hopDistance; ttl_count++) { - if (row_count >= size-1) - break; - /* consolidate hops based on the reference trace (commonPath) */ if(commonPath[ttl_count] && ttl_count <= tg->consolidation_start) { /* do not consolidate in debug mode */ @@ -1061,7 +1056,7 @@ Traceroute::outputTarget (Target * t) { log_write(LOG_PLAIN, "\nTRACEROUTE (using proto %d/%s)\n", tg->proto, proto?proto->p_name:"unknown"); else log_write(LOG_PLAIN, "\nTRACEROUTE (using port %d/%s)\n", tg->dport, proto2ascii(tg->proto)); - log_write (LOG_PLAIN, "%s", Tbl->printableTable(NULL)); + log_write (LOG_PLAIN, "%s", Tbl->printableTrimmedTable(NULL)); if(G_TTL(tg->getState())) log_write(LOG_PLAIN, "! maximum TTL reached (50)\n"); @@ -1226,39 +1221,6 @@ TraceGroup::retransmissions (vector < TraceProbe * >&retrans) { } } -/* nmap's traceroute output can be consolidated, timeouts - * and hops from the common path are collapsed to save space. - * This function calculates the number lines the trace will - * occupy after all consolidation. If debug mode is active - * no consolidation will be applied */ -u8 TraceGroup::tableSize () { - map < u16, TraceProbe * >::iterator it; - TraceProbe *last_probe = NULL; - u8 pathCount = 255; - u8 size = this->size (); - - /* count timeouts and common path elements */ - for (it = TraceProbes.begin (); it != TraceProbes.end (); ++it) { - pathCount = MIN (pathCount, it->second->ttl); - if(last_probe && last_probe->timing.consolidated && it->second->timing.consolidated) - size--; - last_probe = it->second; - } - - /* reached max ttl */ - if(G_TTL(getState())) - return size; - - /* no consolidation in debug mode */ - if(o.debugging) - return size + pathCount; - /* trace has been consolidated based on commonpath */ - if(pathCount > 1) - return size-(consolidation_start-pathCount); - /* no common path elements have been used */ - return size; -} - /* Remove uneeded probes and mark timed out probes for consolidation */ void TraceGroup::consolidateHops () { map < u16, TraceProbe * >::size_type ttl_count; diff --git a/traceroute.h b/traceroute.h index df8d0170f..be685b184 100644 --- a/traceroute.h +++ b/traceroute.h @@ -270,9 +270,6 @@ class TraceGroup { /* consolidate timeouts, remove common paths elements * and performs general upkeep on a finished trace */ void consolidateHops (); - /* the number of table rows a trace will use - * when printed. */ - u8 tableSize (); /* the next ttl to send, if the destination has replied * the ttl is decremented, if it hasn't it is incremented */ void nextTTL () { if (gotReply) ttl--; else { ttl++; hopDistance++;}}