2013-02-22 15 views
9

Mi piacerebbe sapere se c'è un modo per scansionare l'intervallo IP della mia rete locale per porte aperte di un numero specifico.Posso eseguire rapidamente la scansione della mia rete locale per porte aperte specifiche?

In sostanza sto cercando nodejs per trovare client di un tipo specifico senza conoscere i loro indirizzi IP. In questo caso, lettori RFID che ascoltano sulla porta 14150.

Mi piacerebbe che questa scansione fosse veloce, quindi non voglio un lungo timeout tra ogni indirizzo IP. Dovrebbero accadere tutti piuttosto rapidamente, forse entro pochi secondi max per un intero intervallo IP locale fino a 255 client, escluso il mio stesso IP.

Ho scritto codice che fa quello che voglio ma è dolorosamente lento ... Mi piacerebbe vedere come posso farlo più velocemente sfogliando le connessioni e uscendo se una connessione non può essere fatta per un dato IP entro 20 ms . Voglio catturare le connessioni effettive in un array che posso quindi utilizzare per un altro scopo.

var net = require('net'); // Required to create socket connections 

var ip = 254; //IP address to start with on a C class network 

function checkConnect() { 
    ip--; 
    var thisIP = '192.168.1.' + ip; //concatenate to a real IP address 

    var S = new net.Socket(); 
    S.connect(80, thisIP); 

    if(ip > 0) { checkConnect(); } 

    S.on('connect', function() { console.log('port 80 found on ' + thisIP); }); 
    S.on('error', function() { console.log('no such port on ' + thisIP); }); 
    S.end(); 
} 

checkConnect(); 
+1

Questo sarebbe un buon inizio: http://www.hacksparrow.com/a-port-scanner-in-node-js.html –

+0

È anche possibile controllare https://github.com/danielzzz/node -portchecker il suo codice potrebbe indirizzarti nella giusta direzione – Jack

risposta

4

Nessuna delle risposte precedenti ha funzionato veramente come avevo bisogno. Ho trovato un'alternativa molto più leggera. Con questa soluzione ottengo rapidamente la mia soluzione. Il mio prossimo aggiornamento sarà quello di specificare un intervallo di host basato sulla sottorete attuale. Immagino che voglio limitare questo ai primi 254 clienti, quindi non è eccessivo. Ecco il codice:

//LLRP DEVICE SCANNER 
var net = require('net'), Socket = net.Socket; 

var checkPort = function(port, host, callback) { 
    var socket = new Socket(), status = null; 

    // Socket connection established, port is open 
    socket.on('connect', function() {status = 'open';socket.end();}); 
    socket.setTimeout(1500);// If no response, assume port is not listening 
    socket.on('timeout', function() {status = 'closed';socket.destroy();}); 
    socket.on('error', function(exception) {status = 'closed';}); 
    socket.on('close', function(exception) {callback(null, status,host,port);}); 

    socket.connect(port, host); 
} 

var LAN = '192.168.1'; //Local area network to scan (this is rough) 
var LLRP = 5084; //globally recognized LLRP port for RFID readers 

//scan over a range of IP addresses and execute a function each time the LLRP port is shown to be open. 
for(var i=1; i <=255; i++){ 
    checkPort(LLRP, LAN+'.'+i, function(error, status, host, port){ 
     if(status == "open"){ 
      console.log("Reader found: ", host, port, status); 
     } 
    }); 
} 
1

Invece di limitarsi a postare il link (link potrebbe andare morti in un dato momento), vi posterò il codice tutorial qui dal sito:

var net = require('net'); 

// the machine to scan 
var host = 'localhost'; 
// starting from port number 
var start = 1; 
// to port number 
var end = 10000; 
// sockets should timeout asap to ensure no resources are wasted 
// but too low a timeout value increases the likelyhood of missing open sockets, so be careful 
var timeout = 2000; 

// the port scanning loop 
while (start <= end) { 

    // it is always good to give meaningful names to your variables 
    // since the context is changing, we use `port` to refer to current port to scan 
    var port = start; 

    // we create an anonynous function, pass the current port, and operate on it 
    // the reason we encapsulate the socket creation process is because we want to preseve the value of `port` for the callbacks 
    (function(port) { 
     // console.log('CHECK: ' + port); 
     var s = new net.Socket(); 

     s.setTimeout(timeout, function() { s.destroy(); }); 
     s.connect(port, host, function() { 
      console.log('OPEN: ' + port); 
      // we don't destroy the socket cos we want to listen to data event 
      // the socket will self-destruct in 2 secs cos of the timeout we set, so no worries 
     }); 

     // if any data is written to the client on connection, show it 
     s.on('data', function(data) { 
      console.log(port +': '+ data); 
      s.destroy(); 
     }); 

     s.on('error', function(e) { 
      // silently catch all errors - assume the port is closed 
      s.destroy(); 
     }); 
    })(port); 

    start++; 
} 
+0

Questo cerca le porte aperte su un particolare dispositivo. Devo trovare una porta su tutti i dispositivi sulla rete. – clayperez

+0

Non penso che questa soluzione sia asincrona –

18

ho fatto per voi https://github.com/eviltik/evilscan. (V0.0.3 oggi appena rilasciato)

Installare:

npm install -g evilscan 

Uso (elenco porto + intervallo di porte):

[email protected]:~# evilscan --target=192.168.0.0/24 --port=21-446,5900 --concurrency=100 --progress 
192.168.0.3:5900|open 
192.168.0.26:53|open 
192.168.0.26:111|open 
192.168.0.26:81|open 
192.168.0.26:23|open 
Scanned 192.168.0.253:446 (100%) 

Punte:

Per scansione molto veloce, puoi giocare con il parametro "concorrenza" eter, più di 1000, ma devi aggiornare ulimit il parametro del tuo linux prima:

ulimit -u unlimited 

Spero che questo aiuto.

+0

Bel lavoro. Sto esaminando il tuo codice ora. : D –

+0

Libreria molto carina, testata da unità. –

5

È possibile utilizzare il comando arp per ottenere un elenco di dispositivi che sono vivi per primi. Pensare fuori dagli schemi;) Non è necessario eseguire la scansione di tutti i dispositivi alla cieca.

var child = require("child_process"); 
var async = require("async"); 
var net = require("net"); 
var os = require("os"); 

function scan(port, cb){ 
    var hosts = {}; 
    var result = []; 
    async.series([ 
     function scan(next, c){ 
      if(c == 1){ 
       next(); return; 
      } 
      // scan twice because arp sometimes does not list all hosts on first time 
      child.exec("arp -n | awk '{print $1}' | tail -n+2", function(err, res){ 
       if(err) cb(err); 
       else { 
        var list = res.split("\n").filter(function(x){return x !== "";}); 
        list.map(function(x){ 
         hosts[x] = x; 
        }); 
       } 
       scan(next, 1); 
      }); 
     }, 
     function(next){ 
      // if you want to scan local addresses as well 
      var ifs = os.networkInterfaces(); 
      Object.keys(ifs).map(function(x){ 
       hosts[((ifs[x][0])||{}).address] = true; 
      }); 
      // do the scan 
      async.each(Object.keys(hosts), function(x, next){ 
       var s = new net.Socket(); 
       s.setTimeout(1500, function(){s.destroy(); next();}); 
       s.on("error", function(){ 
        s.destroy(); 
        next(); 
       }); 
       s.connect(port, x, function(){ 
        result.push(x); 
        s.destroy(); 
        next(); 
       }); 
      }, function(){ 
       next(); 
      }); 
     } 
    ], function(){ 
     cb(null, result); 
    }); 
} 

scan(80, function(err, hosts){ 
    if(err){ 
     console.error(err); 
    } else { 
     console.log("Found hosts: "+hosts); 
    } 
}); 

È anche possibile utilizzare l'utility arp-scan è più affidabile. Ma arp-scan necessita di un accesso root per funzionare, quindi è meglio usare semplicemente arp. È disponibile praticamente su ogni Linux.

Problemi correlati