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

probably about to release Nmap 3.94ALPHA2

This commit is contained in:
fyodor
2005-12-05 01:00:03 +00:00
parent b3b937d2ca
commit 4cebcf6824
3 changed files with 61 additions and 95 deletions

View File

@@ -1,8 +1,10 @@
# Nmap Changelog ($Id$)
o Better handle ICMP type 3, code 0 (network unreachable) responses to
port scan packets. These are rarely seen when scanning hosts that
are actually online, but are still worth handling.
3.94ALPHA2
o Put Nmap on a diet, with changes to the core port scanning routine
(ultra_scan) to substantially reduce memory consumption, particularly
when tens of thousands of ports are scanned.
o Fixed a problem with the -S and option on Windows reporting "Failed
to resolve/decode supposed IPv4 source address". The -D (decoy)
@@ -10,7 +12,11 @@ o Fixed a problem with the -S and option on Windows reporting "Failed
(kxmail(a)gmail.com) for reporting the problem and tracking down a
potential solution.
o Applied some trivial fixes so that Nmap compiles with Visual C++
o Better handle ICMP type 3, code 0 (network unreachable) responses to
port scan packets. These are rarely seen when scanning hosts that
are actually online, but are still worth handling.
o Applied some small fixes so that Nmap compiles with Visual C++
2005 Express, which is free from Microsoft at
http://msdn.microsoft.com/vstudio/express/visualc/ . Thanks to kx
(kxmail(a)gmail.com) and Sina Bahram (sbahram(a)nc.rr.com)
@@ -22,17 +28,14 @@ o Removed foreign translations of the old man page from the
Portuguese (Portugal) by José Domingos (jd_pt(a)yahoo.com) and
Andreia Gaita (shana.ufie(a)gmail.com).
o Added --thc option (undocumented)
o Modified libdnet-stripped/src/eth-bsd.c to allow for up to 128 bpf
devices rather than 32. This prevents errors like "Failed to open
ethernet interface (fxp0)" when there are more than 32 interface
aliases. Thanks to Krok (krok(a)void.ru) for reporting the problem
and even sending a patch.
o Added --thc option (undocumented)
o A fix to libpcre/pcre.h that should help compilation on Visual
Studio Express. Thanks to kx (kxmail(a)gmail.com) for reporting the problem.
3.94ALPHA1
o Wrote a new man page from scratch. It is much more comprehensive

View File

@@ -434,6 +434,7 @@ PortList::~PortList() {
int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
Port *current = NULL;
map < u16, Port* > *portarray = NULL; // This has to be a pointer so that we change the original and not a copy
map <u16, Port *>::iterator pt;
char msg[128];
assert(state < PORT_HIGHEST_STATE);
@@ -457,7 +458,7 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
fatal("addPort: attempt to add port number %d with illegal state %d\n", portno, state);
if (protocol == IPPROTO_TCP) {
portarray = &tcp_ports;
portarray = &tcp_ports;
} else if (protocol == IPPROTO_UDP) {
portarray = &udp_ports;
} else if (protocol == IPPROTO_IP) {
@@ -465,10 +466,11 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
portarray = &ip_prots;
} else fatal("addPort: attempted port insertion with invalid protocol");
if (portarray->find(portno) == portarray->end()) {
pt = portarray->find(portno);
if (pt != portarray->end()) {
/* We must discount our statistics from the old values. Also warn
if a complete duplicate */
current = (*portarray)[portno];
current = pt->second;
if (o.debugging && current->state == state && (!owner || !*owner)) {
error("Duplicate port (%hu/%s)\n", portno, proto2ascii(protocol));
}
@@ -502,15 +504,6 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
current->owner = strdup(owner);
}
/*
printf("\nCurrent Port List\n");
for(map<u16,Port*>::iterator iter = (*portarray).begin(); iter != (*portarray).end(); iter++)
printf("(%d %d) ", iter->first, iter->second->portno);
printf("\n");
*/
return 0; /*success */
}
@@ -561,15 +554,24 @@ void PortList::setIdStr(const char *id) {
}
Port *PortList::lookupPort(u16 portno, u8 protocol) {
map <u16, Port *>::iterator pt;
if (protocol == IPPROTO_TCP) {
pt = tcp_ports.find(portno);
if (pt != tcp_ports.end())
return pt->second;
}
if (protocol == IPPROTO_TCP)
return tcp_ports[portno];
else if (protocol == IPPROTO_UDP) {
pt = udp_ports.find(portno);
if (pt != udp_ports.end())
return pt->second;
}
if (protocol == IPPROTO_UDP)
return udp_ports[portno];
if (protocol == IPPROTO_IP)
return ip_prots[portno];
else if (protocol == IPPROTO_IP) {
pt = ip_prots.find(portno);
if (pt != ip_prots.end())
return pt->second;
}
return NULL;
}

View File

@@ -251,11 +251,14 @@ public:
port number*/
void setConnect(u16 portno);
/* Pass an arp packet, including ethernet header. Must be 42bytes */
// REMOVED setARP because UNUSED
// void setARP(u8 *arppkt, u32 arplen);
void setARP(u8 *arppkt, u32 arplen);
// The 4 accessors below all return in HOST BYTE ORDER
u16 sport(); // source port used if TCP or UDP
u16 dport(); // destination port used if TCP or UDP
// source port used if TCP or UDP
u16 sport() {
return (mypspec.proto == IPPROTO_TCP)? probes.IP.pd.tcp.sport : probes.IP.pd.udp.sport; }
// destination port used if TCP or UDP
u16 dport() {
return (mypspec.proto == IPPROTO_TCP)? mypspec.pd.tcp.dport : mypspec.pd.udp.dport; }
u16 ipid() { return probes.IP.ipid; }
u32 tcpseq(); // TCP sequence number if protocol is TCP
/* Number, such as IPPROTO_TCP, IPPROTO_UDP, etc. */
@@ -575,7 +578,7 @@ private:
extern void CloseLibs(void);
#endif
void ultrascan_port_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
bool ultrascan_port_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
const probespec *pspec, int newstate);
/* Whether this is storing timing stats for a whole group or an
@@ -661,15 +664,14 @@ UltraProbe::~UltraProbe() {
}
/* Pass an arp packet, including ethernet header. Must be 42bytes */
/* Removed -- unused
void UltraProbe::setARP(u8 *arppkt, u32 arplen) {
type = UP_ARP;
probes.AP = new ArpProbe;
probes.AP->storePacket(arppkt, arplen);
/* probes.AP = new ArpProbe;
probes.AP->storePacket(arppkt, arplen); */
mypspec.type = PS_ARP;
return;
}
*/
/* Sets this UltraProbe as type UP_IP and creates & initializes the
internal IPProbe. The relevent probespec is necessary for setIP
@@ -702,32 +704,6 @@ void UltraProbe::setIP(u8 *ippacket, u32 iplen, const probespec *pspec) {
return;
}
u16 UltraProbe::sport() {
switch(mypspec.proto) {
case IPPROTO_TCP:
return probes.IP.pd.tcp.sport;
case IPPROTO_UDP:
return probes.IP.pd.udp.sport;
default:
fatal("Bogus port number request to %s -- type is %s", __FUNCTION__,
pspectype2ascii(mypspec.type));
}
return 0; // Unreached
}
u16 UltraProbe::dport() {
switch(mypspec.proto) {
case IPPROTO_TCP:
return mypspec.pd.tcp.dport;
case IPPROTO_UDP:
return mypspec.pd.udp.dport;
default:
fatal("Bogus port number request to %s -- type is %s", __FUNCTION__,
pspectype2ascii(mypspec.type));
}
return 0; // Unreached
}
u32 UltraProbe::tcpseq() {
if (mypspec.proto == IPPROTO_TCP)
return probes.IP.pd.tcp.seq;
@@ -1450,7 +1426,7 @@ static int get_next_target_probe(UltraScanInfo *USI, HostScanStats *hss,
if (hss->next_portidx >= USI->ports->udp_count)
return -1;
pspec->type = PS_UDP;
pspec->proto = IPPROTO_TCP;
pspec->proto = IPPROTO_UDP;
pspec->pd.udp.dport = USI->ports->udp_ports[hss->next_portidx++];
return 0;
@@ -1823,8 +1799,9 @@ static void ultrascan_host_update(UltraScanInfo *USI, HostScanStats *hss,
}
/* Like ultrascan_port_probe_update(), except it is called with just a
probespec rather than a whole UltraProbe. */
void ultrascan_port_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
probespec rather than a whole UltraProbe. Returns true if the port
was added or at least the state was changed. */
bool ultrascan_port_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
const probespec *pspec, int newstate) {
u16 portno;
u8 proto = 0;
@@ -1923,6 +1900,7 @@ void ultrascan_port_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
hss->pingprobestate = newstate;
}
}
return oldstate != newstate;
}
/* This function is called when a new status is determined for a port.
@@ -1936,34 +1914,16 @@ static void ultrascan_port_probe_update(UltraScanInfo *USI, HostScanStats *hss,
list<UltraProbe *>::iterator probeI,
int newstate, struct timeval *rcvdtime) {
UltraProbe *probe = *probeI;
int oldstate = PORT_TESTING;
Port *currentp;
u16 portno;
u8 proto = 0;
const probespec *pspec = probe->pspec();
bool changed = false;
if (rcvdtime) ultrascan_adjust_times(USI, hss, probe, rcvdtime);
/* First figure out the current state */
if (USI->prot_scan) {
proto = IPPROTO_IP;
portno = pspec->proto;
} else if (pspec->type == PS_TCP) {
proto = IPPROTO_TCP;
portno = pspec->pd.tcp.dport;
} else if (pspec->type == PS_UDP) {
proto = IPPROTO_TCP;
portno = pspec->pd.udp.dport;
} else assert(0);
currentp = hss->target->ports.lookupPort(portno, proto);
if (currentp)
oldstate = currentp->state;
ultrascan_port_pspec_update(USI, hss, pspec, newstate);
changed = ultrascan_port_pspec_update(USI, hss, pspec, newstate);
/* The rcvdtime check is because this func is called that way when
we give up on a probe because of too many retransmissions. */
if (oldstate != newstate && probe->tryno > hss->max_successful_tryno
if (changed && probe->tryno > hss->max_successful_tryno
&& rcvdtime) {
hss->max_successful_tryno = probe->tryno;
if (o.debugging)
@@ -2104,8 +2064,7 @@ static UltraProbe *sendArpScanProbe(UltraScanInfo *USI, HostScanStats *hss,
probe->tryno = tryno;
probe->pingseq = pingseq;
/* First build the probe */
// never used, so why do it?
// probe->setARP(frame, sizeof(frame));
probe->setARP(frame, sizeof(frame));
/* Now that the probe has been sent, add it to the Queue for this host */
hss->probes_outstanding.push_back(probe);
@@ -2809,7 +2768,6 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
struct sockaddr_in sin;
list<UltraProbe *>::iterator probeI;
UltraProbe *probe = NULL;
IPProbe *ipp;
unsigned int trynum = 0;
unsigned int pingseq = 0;
bool goodseq;
@@ -2833,6 +2791,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
break;
} else if (!ip)
continue;
if (TIMEVAL_SUBTRACT(USI->now, *stime) > 200000) {
/* While packets are still being received, I'll be generous and give
an extra 1/5 sec. But we have to draw the line somewhere */
@@ -2889,8 +2848,10 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
setTargetMACIfAvailable(hss->target, &linkhdr, ip, 0);
probeI = hss->probes_outstanding.end();
listsz = hss->num_probes_outstanding();
goodone = false;
u16 tsp = ntohs(tcp->th_sport);
goodone = false;
for(probenum = 0; probenum < listsz && !goodone; probenum++) {
probeI--;
probe = *probeI;
@@ -2902,7 +2863,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
/* Ensure the connection info matches. No ntohs()-style
conversion necc. b/c all in net bo */
if (probe->dport() != ntohs(tcp->th_sport) ||
if (probe->dport() != tsp ||
probe->sport() != ntohs(tcp->th_dport) ||
hss->target->v4sourceip()->s_addr != ip->ip_dst.s_addr)
continue;
@@ -3006,10 +2967,10 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
for(probenum = 0; probenum < listsz && !goodone; probenum++) {
probeI--;
probe = *probeI;
assert(ipp->af == AF_INET);
assert(o.af() == AF_INET);
if (probe->protocol() != ip2->ip_p ||
hss->target->v4sourceip()->s_addr != ip2->ip_src.s_addr ||
hss->target->v4host().s_addr != ip2->ip_dst.s_addr)
hss->target->v4hostip()->s_addr != ip2->ip_dst.s_addr)
continue;
/* Checking IPID is a little more complex because you can't always count on it */
@@ -3060,7 +3021,7 @@ static bool get_pcap_result(UltraScanInfo *USI, struct timeval *stime) {
break;
case 3: /* Port unreach */
if (USI->scantype == UDP_SCAN &&
ipp->ipv4->ip_dst.s_addr == ip->ip_src.s_addr)
hss->target->v4hostip()->s_addr == ip->ip_src.s_addr)
newstate = PORT_CLOSED;
else newstate = PORT_FILTERED;
break;