File Coverage

lib/Nmap/Scanner/Scanner.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Nmap::Scanner::Scanner;
2              
3 3     3   12 use File::Spec;
  3         7  
  3         66  
4 3     3   1306 use Nmap::Scanner::Backend::XML;
  0            
  0            
5             use LWP::UserAgent;
6             use File::Temp;
7             use strict;
8              
9             =pod
10              
11             =head1 DESCRIPTION
12              
13             This is the primary class of this module; it is the driver for
14             the Nmap::Scanner hierarchy. To use it, create an instance of
15             Nmap::Scanner, possibly set the path to Nmap with nmap_location()
16             (the default behaviour of this class is to search for nmap in
17             the PATH variable.
18              
19             my $nmap = new Nmap::Scanner();
20             $nmap->nmap_location('/usr/local/bin/nmap');
21              
22             Set any options you wish to use in order to run the scan in either
23             batch or event mode, and then call scan() to start scanning. The
24             results are return in an Nmap::Scanner::Backend::Results object.
25              
26             my $results = $nmap->scan();
27              
28             For information on the options presented below, see the man page for
29             nmap or go to http://www.insecure.org/nmap/.
30              
31             =head2 NOTE
32              
33             Some descriptions of methods here are taken directly from the nmap
34             man page.
35              
36             =head2 EXAMPLE
37              
38             See examples/ directory in the distribution for many more)
39              
40             use Nmap::Scanner;
41             my $scan = Nmap::Scanner->new();
42            
43             $scan->add_target('localhost');
44             $scan->add_target('host.i.administer');
45             $scan->add_scan_port('1-1024');
46             $scan->add_scan_port('31337');
47             $scan->tcp_syn_scan();
48             $scan->noping();
49            
50             my $results = $scan->scan();
51            
52             my $hosts = $results->gethostlist();
53            
54             while (my $host = $hosts->get_next()) {
55            
56             print "On " . $host->hostname() . ": \n";
57            
58             my $ports = $host->get_port_list();
59            
60             while (my $port = $ports->get_next()) {
61             print join(' ',
62             'Port',
63             $port->service() . '/' . $port->portid(),
64             'is in state',
65             $port->state(),
66             "\n"
67             );
68             }
69            
70             }
71              
72             =cut
73              
74             sub new {
75             my $class = shift;
76             my $you = { OPTS => {'-oX' => '-'}, DEBUG => 0};
77             return bless $you, $class;
78             }
79              
80             =pod
81              
82             =head2 SCAN EVENTS
83              
84             Register for any of the below events if you wish to use Nmap::Scanner
85             in event-driven mode.
86              
87             =head2 register_scan_complete_event(\&host_done)
88              
89             Register for this event to be notified when a scan of a
90             host is complete. Pass in a function reference that can
91             accept a $self object reference and a reference to an
92             Nmap::Scanner::Host object.
93              
94             host_done($self, $host);
95              
96              
97             =cut
98              
99             sub register_scan_complete_event {
100             $_[0]->{'SCAN_COMPLETE_EVENT'} = [$_[0], $_[1]];
101             return $_[0];
102             }
103              
104             =pod
105              
106             =head2 register_scan_started_event(\&scan_started);
107              
108             Register for this event to be notified when nmap has started to
109             scan one of the targets specified in add_target. Pass in a
110             function reference that can accept a $self object reference,
111             and a reference to an Nmap::Scanner::Host object.
112              
113             scan_started($self, $host);
114              
115             =cut
116              
117             sub register_scan_started_event {
118             $_[0]->{'SCAN_STARTED_EVENT'} = [$_[0], $_[1]];
119             return $_[0];
120             }
121              
122             =pod
123              
124             =head2 register_host_closed_event(\&host_closed);
125              
126             Register to be notified if a scanned host is found to
127             be closed (no open ports). Pass in a function reference
128             that can take an $self object reference and a reference to
129             a Host object.
130              
131             XXX --- TBD (not implemented yet).
132              
133             host_closed($self, $host);
134              
135             =cut
136              
137             sub register_host_closed_event {
138             $_[0]->{'HOST_CLOSED_EVENT'} = [$_[0], $_[1]];
139             return $_[0];
140             }
141              
142             =pod
143              
144             =head2 register_port_found_event(\&port_found);
145              
146             Register to be notified when a port is scanned on a host. The
147             port may be in any state ... closed, open, filtered. Pass a
148             reference to a function that takes a $self object reference,
149             a Host reference, and a Port reference.
150              
151             port_found($self, $host, $port);
152              
153             =cut
154              
155             sub register_port_found_event {
156             $_[0]->{'PORT_FOUND_EVENT'} = [$_[0], $_[1]];
157             return $_[0];
158             }
159              
160             =pod
161              
162             =head2 register_no_ports_open_event(\&port_found);
163              
164             Register to be notified in the event that no ports are found
165             to be open on a host. Pass in a reference to a function that
166             takes a $self object reference, a Host reference, and a reference
167             to an ExtraPorts object. The ExtraPorts object describes ports
168             that are in a state other than open (e.g. flitered, closed).
169              
170             port_found($self, $host, $extra_ports);
171              
172             =cut
173              
174             # Function pointer that receives host name, IP, and status of all ports
175             sub register_no_ports_open_event {
176             $_[0]->{'NO_PORTS_OPEN_EVENT'} = [$_[0], $_[1]];
177             return $_[0];
178             }
179              
180             =head2 register_task_started_event(\&task_begin);
181              
182             Register to be notified when an internal nmap task starts.
183             Pass in a reference to a function that takes a $self object
184             reference and an Nmap::Scanner::Task reference. Note that
185             end_time() will be undefined in the Task instance as this is
186             a begin event.
187              
188             task_begin($self, $task);
189              
190             =cut
191              
192             # Function pointer that receives Nmap::Scanner::Task instance
193             sub register_task_started_event {
194             $_[0]->{'TASK_STARTED_EVENT'} = [$_[0], $_[1]];
195             return $_[0];
196             }
197              
198             =head2 register_task_ended_event(\&task_end);
199              
200             Register to be notified when an internal nmap task ends.
201             Pass in a reference to a function that takes a $self object
202             reference and an Nmap::Scanner::Task reference.
203              
204             task_end($self, $task);
205              
206             =cut
207              
208             # Function pointer that receives Nmap::Scanner::Task instance
209             sub register_task_ended_event {
210             $_[0]->{'TASK_ENDED_EVENT'} = [$_[0], $_[1]];
211             return $_[0];
212             }
213              
214             =head2 register_task_progress_event(\&task_progress);
215              
216             Register to be notified when an internal nmap task progress
217             event is fired; this happens when a task takes more than a
218             few seconds to complete (good for GUIs).
219              
220             Pass in a reference to a function that takes a $self object
221             reference and an Nmap::Scanner::TaskProgress reference.
222              
223             task_progress($self, $task_progress);
224              
225             =cut
226              
227             # Function pointer that receives Nmap::Scanner::Task instance
228             sub register_task_progress_event {
229             $_[0]->{'TASK_PROGRESS_EVENT'} = [$_[0], $_[1]];
230             return $_[0];
231             }
232              
233             =pod
234              
235             =head2 debug()
236              
237             Set this to a non-zero value to see debugging output.
238              
239             =cut
240              
241             sub debug {
242             (defined $_[1]) ? ($_[0]->{DEBUG} = $_[1]) : return $_[0]->{DEBUG};
243             }
244              
245             =pod
246              
247             =head2 norun()
248              
249             Set this to non-zero to have Nmap::Scanner::Scanner print the
250             nmap command line and exit when scan() is called.
251              
252             =cut
253              
254             sub norun {
255             $_[0]->{'NORUN'} = $_[1];
256             return $_[0];
257             }
258              
259             =pod
260              
261             =head2 use_interface()
262              
263             specify the network interface that nmap should use for scanning
264              
265             =cut
266              
267             sub use_interface {
268             $_[0]->{OPTS}->{'-e'} = $_[1];
269             return $_[0];
270             }
271              
272             =pod
273              
274             =head2 SCAN TYPES
275              
276             See the nmap man page for descriptions of all these.
277              
278             =head2 tcp_connect_scan()
279              
280             =head2 tcp_syn_scan()
281              
282             =head2 fin_scan()
283              
284             =head2 xmas_scan()
285              
286             =head2 null_scan()
287              
288             =head2 ping_scan()
289              
290             =head2 udp_scan()
291              
292             =head2 protocol_scan()
293              
294             If this scan is used, the protocols can be retrieved from
295             the Nmap::Scanner::Host objects using the method
296             get_protocol_list(); this method returns a list of
297             Nmap::Scanner::Port object references of type 'ip.'
298              
299             =head2 idle_scan($zombie_host, $probe_port)
300              
301             =head2 ack_scan()
302              
303             =head2 window_scan()
304              
305             =head2 version_scan($intestity)
306              
307             =head2 rpc_scan()
308              
309             =cut
310              
311             sub tcp_connect_scan {
312             $_[0]->{TYPE} = 'T';
313             return $_[0];
314             }
315              
316             sub tcp_syn_scan {
317             $_[0]->{TYPE} = 'S';
318             return $_[0];
319             }
320              
321             sub fin_scan {
322             $_[0]->{TYPE} = 'F';
323             return $_[0];
324             }
325              
326             sub xmas_scan {
327             $_[0]->{TYPE} = 'X';
328             return $_[0];
329             }
330              
331             sub null_scan {
332             $_[0]->{TYPE} = 'N';
333             return $_[0];
334             }
335              
336             sub ping_scan {
337             $_[0]->{TYPE} = 'P';
338             }
339              
340             sub udp_scan {
341             $_[0]->{UDPSCAN} = 'U';
342             return $_[0];
343             }
344              
345             sub protocol_scan {
346             $_[0]->{TYPE} = 'O';
347             return $_[0];
348             }
349              
350             sub idle_scan {
351             $_[0]->{TYPE} = "I $_[1]";
352             $_[0]->{TYPE} .= ":$_[2]" if $_[2];
353             return $_[0];
354             }
355              
356             sub ack_scan {
357             $_[0]->{TYPE} = 'A';
358             return $_[0];
359             }
360              
361             sub window_scan {
362             $_[0]->{TYPE} = 'W';
363             return $_[0];
364             }
365              
366             sub rpc_scan {
367             $_[0]->{'OPTS'}->{'-sR'} = '';
368             return $_[0];
369             }
370              
371             sub version_scan {
372             my $intensity = $_[1] || '5';
373             $_[0]->{'OPTS'}->{'-sV'} = "--version-intensity $intensity";
374             return $_[0];
375             }
376              
377             =pod
378              
379             =head2 SPECIFYING PORTS TO SCAN
380              
381             Use add_scan_port($port_spec) to add one or more ports
382             to scan. $port_spec can be a single port or a range:
383             $n->add_scan_port(80) or $n->add_scan_port('80-1023');
384              
385             Use delete_scan_port($portspec) to delete a port or range
386             of ports.
387              
388             Use reset_scan_ports() to cancel any adds done with add_scan_port().
389              
390             Use getports to get a hash reference in which the keys are the
391             ports you specified with add_scan_port().
392              
393             =cut
394              
395             sub add_scan_port {
396              
397             my $self = shift;
398              
399             for my $port_spec (@_) {
400             $self->{PORTS}->{$port_spec} = 1;
401             }
402              
403             return $self;
404             }
405              
406             sub delete_scan_port {
407              
408             my $self = shift;
409              
410             for my $port_spec (@_) {
411             delete $self->{'PORTS'}->{$port_spec} if
412             exists $self->{'PORTS'}->{$port_spec};
413             }
414              
415             return $self;
416             }
417              
418             sub reset_scan_ports {
419              
420             $_[0]->{PORTS} = undef;
421              
422             return $_[0];
423             }
424              
425             sub getports {
426              
427             return $_[0]->{PORTS};
428             }
429              
430             =pod
431              
432             =head2 SPECIFYING TARGETS TO SCAN
433              
434             See the nmap documentation for the full syntax nmap supports
435             for specifying hosts / subnets / networks to scan.
436              
437             Use add_target($hostspec) to add a target to scan.
438              
439             Use delete_target($hostspec) to delete a target from the
440             list of hosts/networks to scan (must match text used in
441             add_target($hostspec)).
442              
443             Use reset_targets() to cancel any targets you specified
444             with add_target().
445              
446             =cut
447              
448             sub add_target {
449              
450             my $self = shift;
451              
452             for my $host_spec (@_) {
453             $self->{'TARGETS'}->{$host_spec} = 1;
454             }
455              
456             return $self;
457             }
458              
459             sub delete_target {
460              
461             my $self = shift;
462              
463             for my $host_spec (@_) {
464              
465             $self->{'TARGETS'}->{$host_spec} = 1;
466              
467             delete $self->{'TARGETS'}->{$host_spec} if
468             exists $self->{'TARGETS'}->{$host_spec};
469              
470             }
471              
472             return $self;
473             }
474              
475             sub reset_targets {
476              
477             $_[0]->{'TARGETS'} = undef;
478              
479             return $_[0];
480             }
481              
482             =pod
483              
484             =head2 PING OPTIONS
485              
486             nmap has a very flexible mechanism for setting how a ping
487             is interpreted for hosts during a scan. See the nmap
488             documentation for more details.
489              
490             Use no_ping() to not ping hosts before scanning them.
491              
492             Use ack_ping($port) to use a TCP ACK packet as a ping to
493             the port specified on each host to be scanned.
494              
495             Use syn_ping($port) to use a TCP SYN packet as a ping
496             to the port specified on each host to be scanned.
497              
498             Use icmp_ping() to use a true ICMP ping for each host
499             to be scanned.
500              
501             Use ack_icmp_ping($port) to use an ICMP ping, then a TCP ACK packet
502             as a ping (if the ICMP ping fails) to the port specified on each host
503             to be scanned. This is the default behaviour if no ping options are
504             specified.
505              
506             =cut
507              
508             sub no_ping {
509              
510             $_[0]->{'OPTS'}->{'-P'} = "0";
511              
512             return $_[0];
513             }
514              
515             sub ack_ping {
516              
517             $_[0]->{'OPTS'}->{'-P'} = "T$_[1]";
518              
519             return $_[0];
520             }
521              
522             sub syn_ping {
523              
524             $_[0]->{'OPTS'}->{'-P'} = "S$_[1]";
525              
526             return $_[0];
527             }
528              
529             sub icmp_ping {
530              
531             $_[0]->{'OPTS'}->{'-P'} = "I";
532              
533             return $_[0];
534             }
535              
536             sub ack_icmp_ping {
537              
538             $_[0]->{'OPTS'}->{'-P'} = "B$_[1]";
539              
540             return $_[0];
541             }
542              
543             =pod
544              
545             =head2 TIMING OPTIONS
546              
547             Use these methods to set how quickly or slowly nmap scans
548             a host. For more detail on these methods, see the nmap
549             documentation.
550              
551             From slowest to fastest:
552              
553             =item * paranoid_timing()
554              
555             =item * sneaky_timing()
556              
557             =item * polite_timing()
558              
559             =item * normal_timing()
560              
561             =item * aggressive_timing()
562              
563             =item * insane_timing()
564              
565             =cut
566              
567             sub paranoid_timing {
568              
569             $_[0]->{'OPTS'}->{'-T'} = 'Paranoid';
570              
571             return $_[0];
572             }
573              
574             sub sneaky_timing {
575              
576             $_[0]->{'OPTS'}->{'-T'} = 'Sneaky';
577              
578             return $_[0];
579             }
580              
581             sub polite_timing {
582              
583             $_[0]->{'OPTS'}->{'-T'} = 'Polite';
584              
585             return $_[0];
586             }
587              
588             sub normal_timing {
589              
590             $_[0]->{'OPTS'}->{'-T'} = 'Normal';
591              
592             return $_[0];
593             }
594              
595             sub aggressive_timing {
596              
597             $_[0]->{'OPTS'}->{'-T'} = 'Aggressive';
598              
599             return $_[0];
600             }
601              
602             sub insane_timing {
603              
604             $_[0]->{'OPTS'}->{'-T'} = 'Insane';
605              
606             return $_[0];
607             }
608              
609             =pod
610              
611             =head2 OTHER OPTIONS
612              
613             There are many other nmap options. I have done my best
614             to to represent them all. I welcome patches from
615             users for any that I have missed.
616              
617             For details on any of these methods see the nmap
618             documentation.
619              
620             =cut
621              
622             =pod
623              
624             =head2 guess_os()
625              
626             Try and guess the operating system of each target host
627             using TCP fingerprinting.
628              
629             =cut
630              
631             sub guess_os {
632              
633             $_[0]->{'OPTS'}->{'-O'} = "";
634              
635             return $_[0];
636             }
637              
638             =pod
639              
640             =head2 fast_scan()
641              
642             Only scan for services listed in nmap's services file.
643              
644             =cut
645              
646             sub fast_scan {
647              
648             $_[0]->{'OPTS'}->{'-F'} = "";
649              
650             return $_[0];
651             }
652              
653             =pod
654              
655             =head2 ident_check() [DEPRECATED]
656              
657             Attempts to find the user that owns each open port by
658             querying the ident damon of the remote host. See the
659             nmap man page for more details. Support for ident
660             checking is being removed from nmap as so few hosts
661             allow or utilize IDENT anymore.
662              
663             =cut
664              
665             sub ident_check {
666              
667             $_[0]->{'OPTS'}->{'-I'} = "";
668              
669             return $_[0];
670             }
671              
672             =pod
673              
674             =head2 host_timeout($milliseconds)
675              
676             Specifies how much time nmap spends on scanning each
677             host before giving up. Not set by default.
678              
679             =cut
680              
681             sub host_timeout {
682              
683             $_[0]->{'OPTS'}->{'--host-timeout'} = $_[1];
684              
685             return $_[0];
686             }
687              
688             =pod
689              
690             =head2 max_rtt_timeout($milliseconds)
691              
692             Specifies the maximum time nmap should
693             wait for a response to a probe of a port.
694              
695             =cut
696              
697             sub max_rtt_timeout {
698              
699             $_[0]->{'OPTS'}->{'--max_rtt_timeout'} = $_[1];
700              
701             return $_[0];
702             }
703              
704             =head2 max_rtt_timeout($milliseconds)
705              
706             Specifies the minimum time nmap should
707             wait for a response to a probe of a port. Nmap
708             reduces the amoutn of time per response if the
709             scanned machines respond quickly; it will not
710             go below this threshold.
711              
712             =cut
713              
714             sub min_rtt_timeout {
715              
716             $_[0]->{'OPTS'}->{'--min_rtt_timeout'} = $_[1];
717              
718             return $_[0];
719             }
720              
721             =head2 initial_rtt_timeout($milliseconds)
722              
723             Specifies the initial probe timeout. See the
724             nmap man page for more detail.
725              
726             =cut
727              
728             sub initial_rtt_timeout {
729              
730             $_[0]->{'OPTS'}->{'--initial_rtt_timeout'} = $_[1];
731              
732             return $_[0];
733             }
734              
735             =pod
736              
737             =head2 max_parallelism($number)
738              
739             Specifies the maximum number of scans Nmap is allowed to
740             perform in parallel.
741              
742             =cut
743              
744             sub max_parallelism {
745              
746             $_[0]->{'OPTS'}->{'--max_parallelism'} = $_[1];
747              
748             return $_[0];
749             }
750              
751             =pod
752              
753             =head2 scan_delay($milliseconds)
754              
755             Specifies the minimum amount of time Nmap must wait between
756             probes.
757              
758             =cut
759              
760             sub scan_delay {
761              
762             $_[0]->{'OPTS'}->{'--scan_delay'} = $_[1];
763              
764             return $_[0];
765             }
766              
767             =pod
768              
769             =head2 open_nmap()
770              
771             This method sets up a scan, but instead of actually performing
772             the scan, it returns the PID, read filehandle, write file
773             handle, and error file handle of the opened nmap process. Use
774             this if you wish to just use Nmap::Scanner::Scanner as your
775             front end to set up a scan but you wish to process it in some
776             way not supported by Nmap::Scanner.
777              
778             Example:
779              
780             my $scan = Nmap::Scanner->new();
781              
782             my $opts = '-sS -P0 -p 1-1024 192.168.32.1-255';
783              
784             my ($pid, $in, $out, $err) = $scan->open_nmap($opts);
785              
786             =cut
787              
788             sub open_nmap {
789            
790             my $this = shift;
791              
792             my $fast_options = shift || "";
793              
794             my $cmd = $this->_setup_cmdline($fast_options);
795              
796             die "$cmd\n" if $this->{'NORUN'};
797              
798             my $processor = $this->_setup_processor();
799              
800             my ($pid, $read, $write, $error)= $processor->start_nmap($cmd);
801             return ($pid, $read, $write, $error);
802              
803             }
804              
805             =pod
806              
807             =head2 scan()
808              
809             Perform the scan. Returns a populated instance of
810             Nmap::Scanner::Backend::Results when scanning in
811             batch mode (as opposed to event-driven mode).
812              
813             =cut
814              
815             sub scan {
816            
817             my $this = shift;
818              
819             my $fast_options = shift || "";
820              
821             # If we have a file, add "< "
822              
823             my $cmd = "";
824              
825             $cmd = $this->_setup_cmdline($fast_options);
826              
827             die "$cmd\n" if $this->{'NORUN'};
828              
829             Nmap::Scanner::debug("command line: $cmd");
830              
831             my $processor = $this->_setup_processor();
832              
833             my ($pid, $read, $write, $error) = $processor->start_nmap($cmd);
834             close($write);
835              
836             $this->{'RESULTS'} = $processor->process($pid, $read, $cmd, $error);
837              
838             return $this->{'RESULTS'};
839              
840             }
841              
842             =pod
843              
844             =head2 scan_from_file()
845              
846             Recreate a scan from an existing nmap XML-formatted
847             output file. Pass this method in the name of an
848             XML file created by a previously performed nmap
849             scan done in XML output mode and the file will be
850             processed in the same manner as a live scan would
851             be processed. If the passed in file looks like a
852             URI, the module will attempt to retrieve the file
853             using an HTTP GET simple (LWP::UserAgent).
854              
855             Examples:
856              
857             my $scanner = Nmap::Scanner->new();
858             my $results = $scanner->scan_from_file('/path/to/scan_output.xml');
859             my $results = $scanner->scan_from_file('http://example.com/results.xml');
860              
861             =cut
862              
863             sub scan_from_file {
864            
865             my $this = shift;
866              
867             my $filename = shift ||
868             die "scan_from_file: missing filename to read from!";
869              
870             my $handle;
871              
872             if ($filename =~ m#://#) {
873              
874             my $agent = LWP::UserAgent->new(
875             'agent' => "Nmap::Scanner/$Nmap::Scanner::VERSION");
876             my $response = $agent->get($filename);
877              
878             if (! $response->is_success()) {
879             die "scan_from_file: unable to retrieve $filename: " .
880             $response->status_line();
881             }
882              
883             my $dir = File::Temp::tempdir( CLEANUP => 1 );
884             ($handle, $filename) = File::Temp::tempfile( DIR => $dir );
885              
886             print $handle $response->content();
887              
888             seek($handle, 0, 0);
889              
890             } else {
891              
892             local (*READ);
893              
894             open (READ, "< $filename") ||
895             die "scan_from_file: Can't read from $filename: $!";
896              
897             $handle = *READ;
898              
899             }
900              
901             my $processor = $this->_setup_processor();
902              
903             $this->{'RESULTS'} = $processor->process($$, $handle, $filename);
904              
905             return $this->{'RESULTS'};
906              
907             }
908              
909             sub _setup_cmdline {
910              
911             my $this = shift;
912             my $fast_options = shift || "";
913              
914             my $nmap = $this->{'NMAP'} || _find_nmap();
915              
916             die "Can't find nmap!\n" unless $nmap;
917              
918             unless (-f $nmap && -x _) {
919             die "Can't execute specified nmap: $this->{NMAP}\n";
920             }
921              
922             local($_);
923              
924             # Single quotes around command to handle spaces in full path
925             # ... for Windows/Cygwin users. Fix by Jon Amundsen.
926              
927             my $cmd = "'$nmap' -v -v -v";
928              
929             if (! $fast_options) {
930              
931             $cmd .= " -s$this->{'TYPE'}" if defined $this->{'TYPE'};
932              
933             $cmd .= " -s$this->{'UDPSCAN'}" if $this->{'UDPSCAN'};
934              
935             if ($this->{PORTS}) {
936             $cmd .= " -p " . join(',', keys %{$this->{PORTS}});
937             }
938              
939             # Gather other options
940             if ($this->{'OPTS'}) {
941             for my $opt (keys %{$this->{OPTS}}) {
942             $cmd .= " " . $opt . " " . $this->{'OPTS'}->{$opt};
943             }
944             }
945              
946             $cmd .= " " . join(' ', keys %{$this->{'TARGETS'}});
947              
948             } else {
949             $cmd .= " $fast_options -oX -";
950             }
951              
952             return $cmd;
953              
954             }
955              
956             sub _setup_processor {
957              
958             my $this = shift;
959              
960             my $processor = Nmap::Scanner::Backend::XML->new();
961              
962             # All backend processors support these.
963             $processor->debug($this->{'DEBUG'});
964             $processor->register_scan_complete_event($this->{'SCAN_COMPLETE_EVENT'});
965             $processor->register_scan_started_event($this->{'SCAN_STARTED_EVENT'});
966             $processor->register_host_closed_event($this->{'HOST_CLOSED_EVENT'});
967             $processor->register_port_found_event($this->{'PORT_FOUND_EVENT'});
968             $processor->register_no_ports_open_event($this->{'NO_PORTS_OPEN_EVENT'});
969             $processor->register_task_started_event($this->{'TASK_STARTED_EVENT'});
970             $processor->register_task_ended_event($this->{'TASK_ENDED_EVENT'});
971             $processor->register_task_progress_event($this->{'TASK_PROGRESS_EVENT'});
972              
973             return $processor;
974              
975             }
976              
977             sub results {
978             (defined $_[1]) ? ($_[0]->{RESULTS} = $_[1]) : return $_[0]->{RESULTS};
979             }
980              
981             =pod
982              
983             =head2 nmap_location($path)
984              
985             If nmap is not in your PATH, you can specify where it
986             is using this method.
987              
988             =cut
989              
990             sub nmap_location {
991             (defined $_[1]) ? ($_[0]->{NMAP} = $_[1]) : return $_[0]->{NMAP};
992             }
993              
994             sub _find_nmap {
995              
996             local($_);
997             local(*DIR);
998              
999             my $sep = ($^O =~ /Win32/) ? ';' : ':';
1000              
1001             for my $dir (split($sep, $ENV{'PATH'})) {
1002             opendir(DIR,$dir) || next;
1003             my @files = (readdir(DIR));
1004             closedir(DIR);
1005             my $path;
1006             for my $file (@files) {
1007             next unless $file =~ /^nmap(?:.exe)?$/;
1008             $path = File::Spec->catfile($dir, $file);
1009             # Should symbolic link be considered? Helps me on cygwin but ...
1010             next unless -r "$path" && (-x _ || -l _);
1011             return $path;
1012             last DIR;
1013             }
1014             }
1015              
1016             }
1017              
1018             1;