Go to the documentation of this file.00001
00002 import java.io.FileOutputStream;
00003 import java.io.IOException;
00004 import java.io.PrintStream;
00005 import java.net.InetAddress;
00006 import java.net.InetSocketAddress;
00007 import java.net.UnknownHostException;
00008 import java.text.SimpleDateFormat;
00009 import java.util.Calendar;
00010 import java.util.concurrent.ExecutorService;
00011 import java.util.concurrent.Executors;
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 public class PortScanner extends Thread implements PortConnect.Context
00026 {
00027
00028
00029
00030
00031 private final static int connectionTimeout = 0;
00032
00033
00034
00035 private final static int maxThreadCount = 1000;
00036
00037
00038
00039 private final static int maxEndpointsToScan = 1024 * 1024;
00040
00041
00042
00043
00044 private final static boolean reportFailedEndpoints = false;
00045
00046
00047
00048
00049
00050 private ServiceNames verboseServices;
00051
00052
00053
00054 private PrintStream out;
00055
00056
00057
00058
00059
00060
00061
00062
00063 private boolean endpointDepleted;
00064
00065
00066
00067 private RawIpAddress currentAddr;
00068
00069
00070
00071 private int currentPort;
00072
00073
00074
00075 private RawIpAddress firstAddr;
00076
00077
00078
00079 private RawIpAddress lastAddr;
00080
00081
00082
00083 private int firstPort;
00084
00085
00086
00087 private int lastPort;
00088
00089
00090
00091
00092
00093
00094
00095 private int workerThreadCount = 0;
00096
00097
00098
00099 private int scannedEndpointCount = 0;
00100
00101
00102
00103 private int okEndpointCount = 0;
00104
00105
00106
00107 private int failedEndpointCount = 0;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 public PortScanner(
00121 RawIpAddress firstAddr, RawIpAddress lastAddr,
00122 int firstPort, int lastPort,
00123 PrintStream out )
00124 {
00125 this.firstAddr = firstAddr;
00126 this.lastAddr = lastAddr;
00127 this.firstPort = firstPort;
00128 this.lastPort = lastPort;
00129 this.out = out;
00130
00131 this.endpointDepleted = false;
00132
00133
00134
00135 this.currentAddr = new RawIpAddress( firstAddr );
00136
00137
00138
00139 this.currentPort = firstPort;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 @Override
00161 public synchronized InetSocketAddress getNextSocketAddress ()
00162 {
00163 InetSocketAddress endpoint = null;
00164
00165 while( ! endpointDepleted && endpoint == null )
00166 {
00167
00168
00169 try {
00170 InetAddress addr = currentAddr.getInetAddress ();
00171 endpoint = new InetSocketAddress( addr, currentPort );
00172 } catch( Exception e ) {
00173
00174 e.printStackTrace ();
00175 }
00176
00177
00178
00179 currentAddr.increase ();
00180
00181 if ( currentAddr.compare( lastAddr ) > 0 )
00182 {
00183 currentAddr.set( firstAddr );
00184
00185 if ( ++currentPort > lastPort ) {
00186 currentPort = firstPort;
00187 endpointDepleted = true;
00188 }
00189 }
00190 }
00191
00192 return endpoint;
00193 }
00194
00195
00196
00197
00198
00199 @Override
00200 public synchronized void onPortConnected( long threadId, InetSocketAddress addr,
00201 boolean ok, String error, int timeMillis )
00202 {
00203 ++scannedEndpointCount;
00204
00205 if ( ok ) {
00206 ++okEndpointCount;
00207 } else {
00208 ++failedEndpointCount;
00209 }
00210
00211 if ( ok || ( ! ok && reportFailedEndpoints ) )
00212 {
00213 String serviceName = verboseServices.lookup( "tcp", addr.getPort () );
00214
00215 if ( serviceName != null ) {
00216 out.println( now ()
00217 + error + ": " + addr.getAddress() + ":" + addr.getPort ()
00218 + " (" + serviceName + ")"
00219 + ", Thread " + threadId + ", Elapsed " + timeMillis + " ms" );
00220 } else {
00221 out.println( now ()
00222 + error + ": " + addr.getAddress() + ":" + addr.getPort ()
00223 + ", Thread " + threadId + ", Elapsed " + timeMillis + " ms" );
00224 }
00225
00226 out.flush ();
00227 }
00228 }
00229
00230
00231
00232
00233 @Override
00234 public synchronized void workerThreadSignIn( long threadId )
00235 {
00236 ++workerThreadCount;
00237 }
00238
00239
00240
00241
00242 public synchronized void workerThreadSignOut( long threadId )
00243 {
00244 --workerThreadCount;
00245 }
00246
00247
00248
00249
00250
00251
00252 private static String now ()
00253 {
00254 Calendar cal = Calendar.getInstance ();
00255 SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS " );
00256 return sdf.format( cal.getTime() );
00257 }
00258
00259
00260
00261
00262 @Override
00263 public void run()
00264 {
00265 long startTime = System.nanoTime ();
00266
00267 out.println( now () + "Started...\n" );
00268
00269
00270
00271 verboseServices = new ServiceNames( "services.txt" );
00272
00273
00274
00275
00276 int addrSpanSize = (int)( lastAddr.subtract( firstAddr ) + 1 );
00277 int portSpanSize = lastPort - firstPort + 1;
00278 int endpointCount = addrSpanSize * portSpanSize;
00279
00280 System.out.println( "\nScanning "
00281 + addrSpanSize + " hosts * "
00282 + portSpanSize + " ports/host = total "
00283 + endpointCount + " end-points..."
00284 );
00285
00286
00287
00288 if ( endpointCount >= maxEndpointsToScan ) {
00289 String error = "Error: Cowardly refusing to scan more than "
00290 + maxEndpointsToScan + " end-points!\n\n"
00291 + "If you really wanted to scan " + endpointCount + " end-points, "
00292 + "please start multiple instances of the port scanner "
00293 + "(either sequantially or in parallel).\n";
00294
00295 out.println( now () + error );
00296 out.println( now () + "Completed." );
00297
00298 System.err.println( "\n" + error );
00299 System.out.println( "Completed." );
00300
00301 out.flush ();
00302 out.close ();
00303
00304 return;
00305 }
00306
00307
00308
00309
00310 ExecutorService threadPool = Executors.newFixedThreadPool( maxThreadCount );
00311 for ( int i = 0; i < maxThreadCount; ++ i )
00312 {
00313 threadPool.execute( new PortConnect( this, connectionTimeout ) );
00314 }
00315
00316
00317
00318 while( true )
00319 {
00320 try {
00321 Thread.sleep( 1000 );
00322 } catch( InterruptedException e ) {
00323 break;
00324 }
00325
00326 synchronized( this )
00327 {
00328
00329
00330 int elapsed = (int) ( ( System.nanoTime () - startTime ) / 1000000000l );
00331
00332 System.out.print(
00333 "\rElapsed " + elapsed + " sec; "
00334 + "Scanned " + scannedEndpointCount
00335 + " of " + endpointCount
00336 + " end-points (" + okEndpointCount
00337 + " alive + " + failedEndpointCount
00338 + " dead); " + workerThreadCount
00339 + " threads active "
00340 );
00341 System.out.flush ();
00342
00343
00344
00345 if ( workerThreadCount <= 0) {
00346 break;
00347 }
00348 }
00349 }
00350
00351
00352
00353 out.println( "\n" + now() + "Completed." );
00354
00355 out.flush ();
00356 out.close ();
00357
00358 threadPool.shutdownNow ();
00359
00360 System.out.println( "\nCompleted." );
00361 }
00362
00363
00364
00365
00366
00367
00368 public static void main( String[] args )
00369 {
00370 if ( args.length < 5 ) {
00371 System.err.println(
00372 "\nUsage: java -jar portScan.jar "
00373 + "startAddr stopAddr startPort stopPort resultFile\n"
00374 );
00375 System.exit( 0 );
00376 }
00377
00378 String firstHostname = args[0];
00379 String lastHostname = args[1];
00380
00381
00382
00383
00384
00385 RawIpAddress firstAddr = null;
00386 try {
00387 firstAddr = new RawIpAddress( firstHostname );
00388 } catch( UnknownHostException e ) {
00389 System.err.println(
00390 "\nError: Failed to parse startAddr " + firstHostname + "\n"
00391 + e.toString () );
00392 System.exit( 0 );
00393 }
00394
00395
00396
00397
00398
00399 RawIpAddress lastAddr = null;
00400 try {
00401 lastAddr = new RawIpAddress( lastHostname );
00402 } catch( UnknownHostException e ) {
00403 System.err.println(
00404 "\nError: Failed to parse stopAddr " + lastHostname + "\n"
00405 + e.toString () );
00406 System.exit( 0 );
00407 }
00408
00409
00410
00411
00412
00413 if ( ! firstAddr.isSameVersion( lastAddr ) ) {
00414 System.err.println(
00415 "\nError: The first and last IP addresses must be of the same IP version\n"
00416 );
00417 System.exit( 0 );
00418 }
00419
00420
00421
00422
00423
00424 long spanSize = lastAddr.subtract( firstAddr ) + 1;
00425 if ( spanSize <= 0 ) {
00426 System.out.println(
00427 "\nWarning: The first IP address is greater than the last "
00428 + "IP address.\nSwapping IP addresses...\n"
00429 );
00430 RawIpAddress temp = firstAddr; firstAddr = lastAddr; lastAddr = temp;
00431 }
00432
00433
00434
00435
00436
00437 int firstPort = -1;
00438 try {
00439 firstPort = Integer.parseInt( args[2] );
00440 } catch( NumberFormatException e ) {
00441
00442 }
00443 if ( firstPort < 0 ) {
00444 System.err.println(
00445 "\nError: The startPort must be integer between 0 and 65535\n"
00446 );
00447 System.exit( 0 );
00448 }
00449
00450
00451
00452
00453
00454 int lastPort = 80;
00455 try {
00456 lastPort = Integer.parseInt( args[3] );
00457 } catch( NumberFormatException e ) {
00458
00459 }
00460 if ( lastPort < 0 ) {
00461 System.err.println(
00462 "\nError: The stopPort must be integer between 0 and 65535\n"
00463 );
00464 System.exit( 0 );
00465 }
00466
00467
00468
00469
00470
00471 if ( firstPort > lastPort ) {
00472 System.out.println(
00473 "\nWarning: The first TCP port is greater than the last "
00474 + "TCP port.\nSwapping TCP ports...\n"
00475 );
00476
00477 int temp = firstPort; firstPort = lastPort; lastPort = temp;
00478 }
00479
00480
00481
00482
00483
00484 String result = args[4];
00485
00486 PrintStream out = null;
00487 try {
00488 FileOutputStream file = new FileOutputStream( result );
00489 out = new PrintStream( file );
00490 } catch( IOException e ) {
00491 System.err.println(
00492 "\nError: Failed to open file '" + result + "' for writing\n"
00493 + e.toString () );
00494 System.exit( 0 );
00495 }
00496
00497
00498
00499
00500
00501
00502 PortScanner ps = new PortScanner( firstAddr, lastAddr, firstPort, lastPort, out );
00503 ps.start ();
00504 }
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633