1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-26 01:19:03 +00:00

Avoid up to 2 portlist lookups when setting port state in ultrascan

This commit is contained in:
dmiller
2024-02-26 23:10:51 +00:00
parent e75a253d72
commit c5f3665c4f
3 changed files with 47 additions and 51 deletions

View File

@@ -1859,57 +1859,52 @@ static bool ultrascan_port_pspec_update(UltraScanInfo *USI,
portno = pspec->pd.sctp.dport;
} else assert(0);
if (hss->target->ports.portIsDefault(portno, proto)) {
oldstate = PORT_TESTING;
hss->ports_finished++;
} else {
oldstate = hss->target->ports.getPortState(portno, proto);
}
// Set new port state, pending checks for valid state transitions
hss->target->ports.setPortState(portno, proto, newstate, &oldstate);
/* printf("TCP port %hu has changed from state %s to %s!\n", portno, statenum2str(oldstate), statenum2str(newstate)); */
switch (oldstate) {
/* TODO: I need more code here to determine when a state should
be overridden, for example PORT_OPEN trumps PORT_FILTERED
in a SYN scan, but not necessarily for UDP scan */
case PORT_TESTING:
/* Brand new port -- add it to the list */
hss->target->ports.setPortState(portno, proto, newstate);
break;
case PORT_OPEN:
if (newstate != PORT_OPEN) {
if (noresp_open_scan) {
hss->target->ports.setPortState(portno, proto, newstate);
} /* Otherwise The old open takes precedence */
if (newstate != oldstate) {
// Check for conditions that mean we should ignore newstate (revert to oldstate)
switch (oldstate) {
/* TODO: I need more code here to determine when a state should
be overridden, for example PORT_OPEN trumps PORT_FILTERED
in a SYN scan, but not necessarily for UDP scan */
case PORT_TESTING:
/* Brand new port -- add it to the list */
hss->ports_finished++;
break;
case PORT_OPEN:
// Changing from open to anything else only valid for noresp_open_scan
if (!noresp_open_scan) {
hss->target->ports.setPortState(portno, proto, oldstate);
}
break;
case PORT_CLOSED:
// Changing from closed to filtered is never allowed.
// Changing from closed to anything else is never valid for noresp_open_scan
if (noresp_open_scan || newstate == PORT_FILTERED)
hss->target->ports.setPortState(portno, proto, oldstate);
break;
case PORT_FILTERED:
// Changing from filtered to open is not allowed for noresp_open_scan
if (noresp_open_scan && newstate == PORT_OPEN)
hss->target->ports.setPortState(portno, proto, oldstate);
break;
case PORT_UNFILTERED:
/* This could happen in an ACK scan if I receive a RST and then an
ICMP filtered message. I'm gonna stick with unfiltered in that
case. I'll change it if the new state is open or closed,
though I don't expect that to ever happen */
if (newstate != PORT_OPEN && newstate != PORT_CLOSED)
hss->target->ports.setPortState(portno, proto, oldstate);
break;
case PORT_OPENFILTERED:
// Always accepted.
break;
default:
fatal("Unexpected port state: %d\n", oldstate);
break;
}
break;
case PORT_CLOSED:
if (newstate != PORT_CLOSED) {
if (!noresp_open_scan && newstate != PORT_FILTERED)
hss->target->ports.setPortState(portno, proto, newstate);
}
break;
case PORT_FILTERED:
if (newstate != PORT_FILTERED) {
if (!noresp_open_scan || newstate != PORT_OPEN)
hss->target->ports.setPortState(portno, proto, newstate);
}
break;
case PORT_UNFILTERED:
/* This could happen in an ACK scan if I receive a RST and then an
ICMP filtered message. I'm gonna stick with unfiltered in that
case. I'll change it if the new state is open or closed,
though I don't expect that to ever happen */
if (newstate == PORT_OPEN || newstate == PORT_CLOSED)
hss->target->ports.setPortState(portno, proto, newstate);
break;
case PORT_OPENFILTERED:
if (newstate != PORT_OPENFILTERED) {
hss->target->ports.setPortState(portno, proto, newstate);
}
break;
default:
fatal("Unexpected port state: %d\n", oldstate);
break;
}
return oldstate != newstate;