Encapsulates port scanning application. More...
Public Member Functions | |
PortScanner (RawIpAddress firstAddr, RawIpAddress lastAddr, int firstPort, int lastPort, PrintStream out) | |
Creates instance of the PortScanner worker thread. | |
synchronized InetSocketAddress | getNextSocketAddress () |
Gets next socket address (end-point) from the pool. | |
synchronized void | onPortConnected (long threadId, InetSocketAddress addr, boolean ok, String error, int timeMillis) |
Reports information about end-point. | |
synchronized void | workerThreadSignIn (long threadId) |
Call-back from the worker thread reporting that it is alive. | |
synchronized void | workerThreadSignOut (long threadId) |
Call-back from the worker thread reporting that it is zombie (dead waiting) | |
void | run () |
Starts working threads and monitors end-point scanning progress. | |
Static Public Member Functions | |
static void | main (String[] args) |
Parses arguments then starts port scanner worker thread. | |
Static Private Member Functions | |
static String | now () |
Gets current time stamp (millis resolution) | |
Private Attributes | |
ServiceNames | verboseServices |
Instance of the lookup database for TCP and UDP service names. | |
PrintStream | out |
Output stream where the results are written. | |
boolean | endpointDepleted |
True if pool is depleted. | |
RawIpAddress | currentAddr |
The current IP address. | |
int | currentPort |
The current TCP port. | |
RawIpAddress | firstAddr |
The first IP address in the pool. | |
RawIpAddress | lastAddr |
The last IP address in the pool. | |
int | firstPort |
The first TCP port in the pool. | |
int | lastPort |
The last TCP port in the pool. | |
int | workerThreadCount = 0 |
Number of active working threads. | |
int | scannedEndpointCount = 0 |
Number of scanned end-points. | |
int | okEndpointCount = 0 |
Number of connected end-points. | |
int | failedEndpointCount = 0 |
Number of failed to connect end-points. | |
Static Private Attributes | |
static final int | connectionTimeout = 0 |
Connection timeout constant. | |
static final int | maxThreadCount = 1000 |
Number of maximum allowed worker threads. | |
static final int | maxEndpointsToScan = 1024 * 1024 |
Maximum allowed number of end-points to scan. | |
static final boolean | reportFailedEndpoints = false |
Should application report failed end-points or not. |
Encapsulates port scanning application.
The instance maintains pool of end-points (to be scanned) starts worker threads that scan end-points from the pool and displays progress to the user.
The static main() entry point facility parses command line arguments and starts the single instance of the class.
Definition at line 25 of file PortScanner.java.
PortScanner.PortScanner | ( | RawIpAddress | firstAddr, |
RawIpAddress | lastAddr, | ||
int | firstPort, | ||
int | lastPort, | ||
PrintStream | out | ||
) |
Creates instance of the PortScanner worker thread.
firstAddr | the first raw IP address in range |
lastAddr | the last raw IP address in range |
firstPort | the first port in range |
lastPort | the last port in range |
out | output stream for results |
Definition at line 120 of file PortScanner.java.
References currentAddr, currentPort, endpointDepleted, firstAddr, firstPort, lastAddr, lastPort, and out.
Referenced by main().
{ this.firstAddr = firstAddr; this.lastAddr = lastAddr; this.firstPort = firstPort; this.lastPort = lastPort; this.out = out; this.endpointDepleted = false; /* Set currentAddr <= copy of the firstAddr */ this.currentAddr = new RawIpAddress( firstAddr ); /* Set currentPort <= firstPort */ this.currentPort = firstPort; }
synchronized InetSocketAddress PortScanner.getNextSocketAddress | ( | ) | [virtual] |
Gets next socket address (end-point) from the pool.
The next end-point is retrieved by first scanning all addresses in range keeping the TCP port constant. This means that worker threads do not flood the specific IP address with different simultaneous connections on different TCP ports all at once.
The next algorithm clarifies previous explanation:
for( all ports in range ) { for ( all addresses in range ) { end-point := address + port; perform scan on end-point; } }
Implements PortConnect.Context.
Definition at line 161 of file PortScanner.java.
References RawIpAddress.compare(), currentAddr, currentPort, endpointDepleted, firstAddr, firstPort, RawIpAddress.getInetAddress(), RawIpAddress.increase(), lastAddr, lastPort, and RawIpAddress.set().
{ InetSocketAddress endpoint = null; while( ! endpointDepleted && endpoint == null ) { /* Create end-point from the current IP address and the current TCP port */ try { InetAddress addr = currentAddr.getInetAddress (); endpoint = new InetSocketAddress( addr, currentPort ); } catch( Exception e ) { /* this should not happen; however, skip this address */ e.printStackTrace (); } /* Advance to the next end-point */ currentAddr.increase (); if ( currentAddr.compare( lastAddr ) > 0 ) { currentAddr.set( firstAddr ); // set currentAddr := firstAddr if ( ++currentPort > lastPort ) { currentPort = firstPort; // start the loop all over again endpointDepleted = true; // suppress further 'gets' } } } return endpoint; }
static void PortScanner.main | ( | String[] | args ) | [static] |
Parses arguments then starts port scanner worker thread.
args |
Definition at line 368 of file PortScanner.java.
References firstAddr, firstPort, RawIpAddress.isSameVersion(), lastAddr, lastPort, out, PortScanner(), and RawIpAddress.subtract().
{ if ( args.length < 5 ) { System.err.println( "\nUsage: java -jar portScan.jar " + "startAddr stopAddr startPort stopPort resultFile\n" ); System.exit( 0 ); } String firstHostname = args[0]; String lastHostname = args[1]; ////////////////////////////////////////////////////////////////////////////////// /* Get the first raw IP address in range to scan */ RawIpAddress firstAddr = null; try { firstAddr = new RawIpAddress( firstHostname ); } catch( UnknownHostException e ) { System.err.println( "\nError: Failed to parse startAddr " + firstHostname + "\n" + e.toString () ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* Get the last raw IP address in range to scan */ RawIpAddress lastAddr = null; try { lastAddr = new RawIpAddress( lastHostname ); } catch( UnknownHostException e ) { System.err.println( "\nError: Failed to parse stopAddr " + lastHostname + "\n" + e.toString () ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* Ensure not to mix IPv4 and IPv6 addresses */ if ( ! firstAddr.isSameVersion( lastAddr ) ) { System.err.println( "\nError: The first and last IP addresses must be of the same IP version\n" ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* Ensure that the first is less then or equal the last IP address */ long spanSize = lastAddr.subtract( firstAddr ) + 1; if ( spanSize <= 0 ) { System.out.println( "\nWarning: The first IP address is greater than the last " + "IP address.\nSwapping IP addresses...\n" ); RawIpAddress temp = firstAddr; firstAddr = lastAddr; lastAddr = temp; } ////////////////////////////////////////////////////////////////////////////////// /* Parse the first port in range */ int firstPort = -1; try { firstPort = Integer.parseInt( args[2] ); } catch( NumberFormatException e ) { /* will fail later */ } if ( firstPort < 0 ) { System.err.println( "\nError: The startPort must be integer between 0 and 65535\n" ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* Parse the last port in range */ int lastPort = 80; try { lastPort = Integer.parseInt( args[3] ); } catch( NumberFormatException e ) { /* will fail later */ } if ( lastPort < 0 ) { System.err.println( "\nError: The stopPort must be integer between 0 and 65535\n" ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* Ensure that the first port is less or equal than the last port */ if ( firstPort > lastPort ) { System.out.println( "\nWarning: The first TCP port is greater than the last " + "TCP port.\nSwapping TCP ports...\n" ); int temp = firstPort; firstPort = lastPort; lastPort = temp; } ////////////////////////////////////////////////////////////////////////////////// /* Open the results file */ String result = args[4]; PrintStream out = null; try { FileOutputStream file = new FileOutputStream( result ); out = new PrintStream( file ); } catch( IOException e ) { System.err.println( "\nError: Failed to open file '" + result + "' for writing\n" + e.toString () ); System.exit( 0 ); } ////////////////////////////////////////////////////////////////////////////////// /* We have all parameters valid now. * Create the instance of the port scanner and start its main thread... */ PortScanner ps = new PortScanner( firstAddr, lastAddr, firstPort, lastPort, out ); ps.start (); }
static String PortScanner.now | ( | ) | [static, private] |
Gets current time stamp (millis resolution)
Definition at line 252 of file PortScanner.java.
Referenced by onPortConnected(), and run().
{ Calendar cal = Calendar.getInstance (); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS " ); return sdf.format( cal.getTime() ); }
synchronized void PortScanner.onPortConnected | ( | long | threadId, |
InetSocketAddress | addr, | ||
boolean | ok, | ||
String | error, | ||
int | timeMillis | ||
) | [virtual] |
Reports information about end-point.
(Call-back from the scanning worker thread.)
Implements PortConnect.Context.
Definition at line 200 of file PortScanner.java.
References failedEndpointCount, ServiceNames.lookup(), now(), okEndpointCount, out, reportFailedEndpoints, scannedEndpointCount, and verboseServices.
{ ++scannedEndpointCount; if ( ok ) { ++okEndpointCount; } else { ++failedEndpointCount; } if ( ok || ( ! ok && reportFailedEndpoints ) ) { String serviceName = verboseServices.lookup( "tcp", addr.getPort () ); if ( serviceName != null ) { out.println( now () + error + ": " + addr.getAddress() + ":" + addr.getPort () + " (" + serviceName + ")" + ", Thread " + threadId + ", Elapsed " + timeMillis + " ms" ); } else { out.println( now () + error + ": " + addr.getAddress() + ":" + addr.getPort () + ", Thread " + threadId + ", Elapsed " + timeMillis + " ms" ); } out.flush (); } }
void PortScanner.run | ( | ) |
Starts working threads and monitors end-point scanning progress.
Definition at line 263 of file PortScanner.java.
References connectionTimeout, failedEndpointCount, firstAddr, firstPort, lastAddr, lastPort, maxEndpointsToScan, maxThreadCount, now(), okEndpointCount, out, scannedEndpointCount, RawIpAddress.subtract(), verboseServices, and workerThreadCount.
{ long startTime = System.nanoTime (); out.println( now () + "Started...\n" ); /* Load service names */ verboseServices = new ServiceNames( "services.txt" ); /* Calculate how long it will take to perform the scan * (if all ports throw timeouts) */ int addrSpanSize = (int)( lastAddr.subtract( firstAddr ) + 1 ); int portSpanSize = lastPort - firstPort + 1; int endpointCount = addrSpanSize * portSpanSize; System.out.println( "\nScanning " + addrSpanSize + " hosts * " + portSpanSize + " ports/host = total " + endpointCount + " end-points..." ); /* Ensure that we do not scan impossible range of end-points */ if ( endpointCount >= maxEndpointsToScan ) { String error = "Error: Cowardly refusing to scan more than " + maxEndpointsToScan + " end-points!\n\n" + "If you really wanted to scan " + endpointCount + " end-points, " + "please start multiple instances of the port scanner " + "(either sequantially or in parallel).\n"; out.println( now () + error ); out.println( now () + "Completed." ); System.err.println( "\n" + error ); System.out.println( "Completed." ); out.flush (); out.close (); return; } /* Start port scanner working threads (see PortConnect.run()) in the pool. * */ ExecutorService threadPool = Executors.newFixedThreadPool( maxThreadCount ); for ( int i = 0; i < maxThreadCount; ++ i ) { threadPool.execute( new PortConnect( this, connectionTimeout ) ); } /* Wait all threads to complete. While waiting, display the progress. */ while( true ) { try { Thread.sleep( 1000 ); } catch( InterruptedException e ) { break; } synchronized( this ) { /* Display progress... */ int elapsed = (int) ( ( System.nanoTime () - startTime ) / 1000000000l ); System.out.print( "\rElapsed " + elapsed + " sec; " + "Scanned " + scannedEndpointCount + " of " + endpointCount + " end-points (" + okEndpointCount + " alive + " + failedEndpointCount + " dead); " + workerThreadCount + " threads active " ); System.out.flush (); /* Done if no more working threads. */ if ( workerThreadCount <= 0) { break; } } } /* Be nice and clean-up... */ out.println( "\n" + now() + "Completed." ); out.flush (); out.close (); threadPool.shutdownNow (); System.out.println( "\nCompleted." ); }
synchronized void PortScanner.workerThreadSignIn | ( | long | threadId ) | [virtual] |
Call-back from the worker thread reporting that it is alive.
Implements PortConnect.Context.
Definition at line 234 of file PortScanner.java.
References workerThreadCount.
{ ++workerThreadCount; }
synchronized void PortScanner.workerThreadSignOut | ( | long | threadId ) | [virtual] |
Call-back from the worker thread reporting that it is zombie (dead waiting)
Implements PortConnect.Context.
Definition at line 242 of file PortScanner.java.
References workerThreadCount.
{ --workerThreadCount; }
final int PortScanner.connectionTimeout = 0 [static, private] |
RawIpAddress PortScanner.currentAddr [private] |
The current IP address.
Definition at line 67 of file PortScanner.java.
Referenced by getNextSocketAddress(), and PortScanner().
int PortScanner.currentPort [private] |
The current TCP port.
Definition at line 71 of file PortScanner.java.
Referenced by getNextSocketAddress(), and PortScanner().
boolean PortScanner.endpointDepleted [private] |
True if pool is depleted.
Definition at line 63 of file PortScanner.java.
Referenced by getNextSocketAddress(), and PortScanner().
int PortScanner.failedEndpointCount = 0 [private] |
Number of failed to connect end-points.
Definition at line 107 of file PortScanner.java.
Referenced by onPortConnected(), and run().
RawIpAddress PortScanner.firstAddr [private] |
The first IP address in the pool.
Definition at line 75 of file PortScanner.java.
Referenced by getNextSocketAddress(), main(), PortScanner(), and run().
int PortScanner.firstPort [private] |
The first TCP port in the pool.
Definition at line 83 of file PortScanner.java.
Referenced by getNextSocketAddress(), main(), PortScanner(), and run().
RawIpAddress PortScanner.lastAddr [private] |
The last IP address in the pool.
Definition at line 79 of file PortScanner.java.
Referenced by getNextSocketAddress(), main(), PortScanner(), and run().
int PortScanner.lastPort [private] |
The last TCP port in the pool.
Definition at line 87 of file PortScanner.java.
Referenced by getNextSocketAddress(), main(), PortScanner(), and run().
final int PortScanner.maxEndpointsToScan = 1024 * 1024 [static, private] |
Maximum allowed number of end-points to scan.
Definition at line 39 of file PortScanner.java.
Referenced by run().
final int PortScanner.maxThreadCount = 1000 [static, private] |
Number of maximum allowed worker threads.
Definition at line 35 of file PortScanner.java.
Referenced by run().
int PortScanner.okEndpointCount = 0 [private] |
Number of connected end-points.
Definition at line 103 of file PortScanner.java.
Referenced by onPortConnected(), and run().
PrintStream PortScanner.out [private] |
Output stream where the results are written.
Definition at line 54 of file PortScanner.java.
Referenced by main(), onPortConnected(), PortScanner(), and run().
final boolean PortScanner.reportFailedEndpoints = false [static, private] |
Should application report failed end-points or not.
Disabled by default: Who is interested in failed ports at all?
Definition at line 44 of file PortScanner.java.
Referenced by onPortConnected().
int PortScanner.scannedEndpointCount = 0 [private] |
Number of scanned end-points.
Definition at line 99 of file PortScanner.java.
Referenced by onPortConnected(), and run().
ServiceNames PortScanner.verboseServices [private] |
Instance of the lookup database for TCP and UDP service names.
Definition at line 50 of file PortScanner.java.
Referenced by onPortConnected(), and run().
int PortScanner.workerThreadCount = 0 [private] |
Number of active working threads.
Definition at line 95 of file PortScanner.java.
Referenced by run(), workerThreadSignIn(), and workerThreadSignOut().