ScanEngine

Almost all of Nmap's scans happen in the function ultra_scan in the file scan_engine.cc. Here is its declaration:

void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports,
        stype scantype);

About the parameters

The class Target stores information about a scan of a single host. As you can see, an entire vector of targets is scanned at once.

struct scan_lists (defined in global_structures.h) is just a list of TCP or UDP ports and IP protocols:

struct scan_lists {
        unsigned short *tcp_ports;
        int tcp_count;
        unsigned short *udp_ports;
        int udp_count;
        unsigned short *prots;
        int prot_count;
}; 

stype is an enum in global_structures.h:

typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN,
XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, RPC_SCAN,
MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN,
SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE, REF_TRACEROUTE}stype;

Data structures

UltraScanInfo

Each scan creates an UltraScanInfo instance. An UltraScanInfo is created using the same parameters as ultra_scan: a list of targets, a list of ports, and a scan type. It includes a bunch of bool variables like tcp_scan, udp_scan, icmp_scan, and others, which I believe are a convenient broken-down form of the scan type. There are a libdnet Ethernet handle, a pcap handle, and a raw socket descriptor.

UltraScanInfo contains a GroupScanStats, which contains statistics for the entire scan. It also contains a list of incomplete hosts (hosts which haven't finished being scanned). Each incomplete host is a HostScanStats which has the state for one host (things like outstanding probes and retransmission counts).

UltraProbe

An UltraProbe represents one of the probes that can be sent in ultra_scan. The list of outstanding probes in a HostScanStats is a list of UltraProbes. You can set it to be an IP, a connect, or an ARP probe using the methods setIP, setConnect, and setARP. When you set it to IP, you give it a struct probespec as a prototype.

struct probespec

typedef struct probespec {
  u8 type; /* PS_NONE, PS_TCP, PS_UDP, PS_PROTO, PS_ICMP, PS_ARP. */
  u8 proto; /* If not PS_ARP -- Protocol number ... eg IPPROTO_TCP, etc. */
  union {
    struct probespec_tcpdata tcp; /* if type is PS_TCP */
    struct probespec_udpdata udp; /* PS_UDP */
  } pd;
} probespec;
struct probespec_tcpdata {
  u16 dport;
  u8 flags;
};
struct probespec_udpdata {
  u16 dport;
};

A probespec is a probe type, a protocol (?), a destination ports, and flags. It can be thought of as a condensed version of UltraProbe.

ultra_scan walkthrough

ultra_scan goes like this:

Page last modified on May 28, 2007, at 01:05 PM