1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 22:21:29 +00:00

Merge from /nmap-exp/david/nmap-mem. This brings in two memory-reducing

changes. The first is that Port objects don't allocate memory for
service and RPC results unless that information is set. This reduces the
size of a bare Port from 92 to 40 bytes on my machine. The second change
is that PortList now has the notion of a "default port state," which is
the state of any ports that didn't receive a response. These ports don't
need an allocated Port object, which saves a lot of memory in scans
where most ports didn't get a response.
This commit is contained in:
david
2009-12-19 21:26:14 +00:00
parent 9f0e11f035
commit b838242e01
15 changed files with 593 additions and 517 deletions

View File

@@ -140,25 +140,25 @@ enum service_tunnel_type { SERVICE_TUNNEL_NONE, SERVICE_TUNNEL_SSL };
void random_port_cheat(u16 *ports, int portcount);
struct serviceDeductions {
const char *name; // will be NULL if can't determine
serviceDeductions();
void populateFullVersionString(char *buf, size_t n) const;
char *name; // will be NULL if can't determine
// Confidence is a number from 0 (least confident) to 10 (most
// confident) expressing how accurate the service detection is
// likely to be.
int name_confidence;
// Any of these 6 can be NULL if we weren't able to determine it
const char *product;
const char *version;
const char *extrainfo;
const char *hostname;
const char *ostype;
const char *devicetype;
char *product;
char *version;
char *extrainfo;
char *hostname;
char *ostype;
char *devicetype;
// SERVICE_TUNNEL_NONE or SERVICE_TUNNEL_SSL
enum service_tunnel_type service_tunnel;
// This is a combined representation of product, version, and extrainfo.
// It will be zero length if unavailable.
char fullversion[160];
// if we should give the user a service fingerprint to submit, here it is. Otherwise NULL.
const char *service_fp;
char *service_fp;
enum service_detection_type dtype; // definition above
int rpc_status; /* RPC_STATUS_UNTESTED means we haven't checked
RPC_STATUS_UNKNOWN means the port appears to be RPC
@@ -173,38 +173,12 @@ struct serviceDeductions {
};
class Port {
friend class PortList;
public:
Port();
~Port();
// pass in an allocated struct serviceDeductions (don't worry about initializing, and
// you don't have to free any internal ptrs. See the serviceDeductions definition for
// the fields that are populated. Returns 0 if at least a name is available.
int getServiceDeductions(struct serviceDeductions *sd);
// sname should be NULL if sres is not
// PROBESTATE_FINISHED_MATCHED. product,version, and/or extrainfo
// will be NULL if unavailable. Note that this function makes its
// own copy of sname and product/version/extrainfo. This function
// also takes care of truncating the version strings to a
// 'reasonable' length if neccessary, and cleaning up any unprinable
// chars. (these tests are to avoid annoying DOS (or other) attacks
// by malicious services). The fingerprint should be NULL unless
// one is available and the user should submit it. tunnel must be
// SERVICE_TUNNEL_NULL (normal) or SERVICE_TUNNEL_SSL (means ssl was
// detected and we tried to tunnel through it ).
void setServiceProbeResults(enum serviceprobestate sres, const char *sname,
enum service_tunnel_type tunnel, const char *product,
const char *version, const char *hostname,
const char *ostype, const char *devicetype,
const char *extrainfo, const char *fingerprint);
/* Sets the results of an RPC scan. if rpc_status is not
RPC_STATUS_GOOD_PROGRAM, pass 0 for the other args. This function
takes care of setting the port's service and version
appropriately. */
void setRPCProbeResults(int rpc_status, unsigned long rpc_program,
unsigned int rpc_lowver, unsigned int rpc_highver);
void getNmapServiceName(char *namebuf, int buflen) const;
u16 portno;
u8 proto;
@@ -216,28 +190,10 @@ class Port {
#endif
private:
int rpc_status; /* RPC_STATUS_UNTESTED means we haven't checked
RPC_STATUS_UNKNOWN means the port appears to be RPC
but we couldn't find a match
RPC_STATUS_GOOD_PROG means rpc_program gives the prog #
RPC_STATUS_NOT_RPC means the port doesn't appear to
be RPC */
unsigned long rpc_program; /* Only valid if rpc_state == RPC_STATUS_GOOD_PROG */
unsigned int rpc_lowver;
unsigned int rpc_highver;
enum serviceprobestate serviceprobe_results; // overall results of service scan
char *serviceprobe_service; // If a service was discovered, points to the name
// Any of these next three can be NULL if the details are not available
char *serviceprobe_product;
char *serviceprobe_version;
char *serviceprobe_extrainfo;
char *serviceprobe_hostname;
char *serviceprobe_ostype;
char *serviceprobe_devicetype;
enum service_tunnel_type serviceprobe_tunnel;
// A fingerprint that the user can submit if the service wasn't recognized
char *serviceprobe_fp;
/* This is allocated only on demand by PortList::setServiceProbeResults or
PortList::setRPCProbeResults, to save memory for the many closed or
filtered ports that don't need it. */
serviceDeductions *service;
};
@@ -261,10 +217,10 @@ class PortList {
/* Free memory used by port_map. It should be done somewhere before quitting*/
static void freePortMap();
/* Add a new port to this list. If the state has changed, it is
OK to call this function to effect the change */
int addPort(u16 portno, u8 protocol, int state);
int removePort(u16 portno, u8 protocol);
void setDefaultPortState(u8 protocol, int state);
void setPortState(u16 portno, u8 protocol, int state);
int getPortState(u16 portno, u8 protocol);
int forgetPort(u16 portno, u8 protocol);
/* Saves an identification string for the target containing these
ports (an IP addrss might be a good example, but set what you
want). Only used when printing new port updates. Optional. A
@@ -280,17 +236,11 @@ class PortList {
function returns ports in numeric order from lowest to highest,
except that if you ask for TCP, UDP & SCTP, all TCP ports will be
returned before we start returning UDP and finally SCTP ports */
Port *nextPort(Port *afterthisport,
int allowed_protocol, int allowed_state);
/* Get Port structure from PortList structure.*/
Port *getPortEntry(u16 portno, u8 protocol);
/* Set Port structure to PortList structure.*/
void setPortEntry(u16 portno, u8 protocol, Port *port);
Port *nextPort(const Port *cur, Port *next,
int allowed_protocol, int allowed_state);
int setStateReason(u16 portno, u8 proto, reason_t reason, u8 ttl, u32 ip_addr);
int numports; /* Total number of ports in list in ANY state */
int numscriptresults; /* Total number of scripts which produced output */
/* Get number of ports in this state. This a sum for protocols. */
@@ -298,6 +248,38 @@ class PortList {
/* Get number of ports in this state for requested protocol. */
int getStateCounts(int protocol, int state);
// sname should be NULL if sres is not
// PROBESTATE_FINISHED_MATCHED. product,version, and/or extrainfo
// will be NULL if unavailable. Note that this function makes its
// own copy of sname and product/version/extrainfo. This function
// also takes care of truncating the version strings to a
// 'reasonable' length if neccessary, and cleaning up any unprinable
// chars. (these tests are to avoid annoying DOS (or other) attacks
// by malicious services). The fingerprint should be NULL unless
// one is available and the user should submit it. tunnel must be
// SERVICE_TUNNEL_NULL (normal) or SERVICE_TUNNEL_SSL (means ssl was
// detected and we tried to tunnel through it ).
void setServiceProbeResults(u16 portno, int protocol,
enum serviceprobestate sres, const char *sname,
enum service_tunnel_type tunnel, const char *product,
const char *version, const char *hostname,
const char *ostype, const char *devicetype,
const char *extrainfo, const char *fingerprint);
// pass in an allocated struct serviceDeductions (don't worry about initializing, and
// you don't have to free any internal ptrs. See the serviceDeductions definition for
// the fields that are populated. Returns 0 if at least a name is available.
const void getServiceDeductions(u16 portno, int protocol, struct serviceDeductions *sd) const;
/* Sets the results of an RPC scan. if rpc_status is not
RPC_STATUS_GOOD_PROGRAM, pass 0 for the other args. This function
takes care of setting the port's service and version
appropriately. */
void setRPCProbeResults(u16 portno, int proto, int rpc_status, unsigned long rpc_program,
unsigned int rpc_lowver, unsigned int rpc_highver);
void addScriptResult(u16 portno, int protocol, ScriptResult& sr);
/* Cycles through the 0 or more "ignored" ports which should be
consolidated for Nmap output. They are returned sorted by the
number of prots in the state, starting with the most common. It
@@ -313,12 +295,20 @@ class PortList {
int numIgnoredStates();
int numIgnoredPorts();
int numPorts() const;
private:
bool mapPort(u16 *portno, u8 *protocol) const;
/* Get Port structure from PortList structure.*/
const Port *lookupPort(u16 portno, u8 protocol) const;
Port *createPort(u16 portno, u8 protocol);
/* Set Port structure to PortList structure.*/
void setPortEntry(u16 portno, u8 protocol, Port *port);
/* A string identifying the system these ports are on. Just used for
printing open ports, if it is set with setIdStr() */
char *idstr;
/* Number of ports in each state per each protocol */
/* Number of ports in each state per each protocol. */
int state_counts_proto[PORTLIST_PROTO_MAX][PORT_HIGHEST_STATE];
Port **port_list[PORTLIST_PROTO_MAX];
protected:
@@ -326,8 +316,10 @@ class PortList {
* Only functions: getPortEntry, setPortEntry, initializePortMap and
* nextPort should access this structure directly. */
static u16 *port_map[PORTLIST_PROTO_MAX];
static u16 *port_map_rev[PORTLIST_PROTO_MAX];
/* Number of allocated elements in port_list per each protocol. */
static int port_list_count[PORTLIST_PROTO_MAX];
Port default_port_state[PORTLIST_PROTO_MAX];
};
#endif