IP Scanner

Code-Stücke können hier veröffentlicht werden.
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Samstag 30. August 2014, 03:56

Ich habe hier mal ein Lan Scanner gebastelt :D
Was haltet ihr davon und wie "sauber" ist der Code? :)

Code: Alles auswählen


import socket


def is_up(addr):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(0.1)
    if not s.connect_ex((addr, 135)):
        s.close()
        return False
    else:
        return True

def main():
	liste = []
	for ip in range(1, 256):
		addr = "192.168.0." + str(ip)
		check = is_up(addr)
		if check == False:
			print(addr, "Belegt")
			liste.append(addr)
		elif check == True:
			print(addr, "Frei")
		else:
			print("Fehler")
	print()
	print("********************************")
	print()
	anzahl = len(liste)
	for ips in range(anzahl):
		print("Belegt : ", liste[ips])

if __name__ == "__main__":
	main()

Übrigends wurde dazwischen ein Switch geschaltet, ist halt für LAN-Feten gedacht. :)

mfg
Trayser
BlackJack

Samstag 30. August 2014, 05:02

@TrayserCassa: `is_up()` verwendet `connect_ex()` statt `connect()` kümmert sich aber nicht um eventuelle Ausnahmen die ja trotzdem noch auftreten können. `connect()` und eine entsprechende Ausnahmebehandlung wäre also einfacher.

Der Rückgabewert von `is_up()` ist falsch, denn wenn die Verbindung da ist, dann wird `False` zurückgegeben. Das macht keinen Sinn. Das die Zahl die zurückgegeben wird ”Falsch” bedeutet wenn die Verbindung zustande kommt, macht das ganze auch nicht wirklich gut lesbar wenn man einfach mit ``not`` arbeitet statt explizit mit ``== 0`` auf den ”guten” Fall zu testen. Bei `connect()` hätte man das Problem nicht.

`s` ist kein guter Name. Genau so wenig ist `liste` ein guter Name. `check` ist schon besser als Name an sich, aber eher für eine Funktion oder Methode, da er eine Tätigkeit beschreibt. Eigentlich wäre für diesen Wert `is_up` ein passender Name, wenn die Funktion nicht schon so heissen würde. Bei `ips` hätte ich keine ganzen Zahlen erwartet sondern zum Beispiel eine Liste mit IPs.

Die `main()`-Funktion ist nicht vier Leerzeichen pro Ebene eingerückt.

Das explizite Prüfen auf literale `True`- und `False`-Werte ist schlechter Stil. Bei dem Vergleich kommt doch nur wieder ein Wahrheitswert heraus, da hätte man auch gleich den nehmen können mit dem man das Literal vergleicht, beziehungsweise das gegebenfalls negieren.

Die drei Zweige für `True`, `False`, und anderes sind überflüssig weil die Funktion nur `True` oder `False` zurück gibt.

``for index in range(len(sequence)):`` ist ein „anti pattern”. Man kann stattdessen direkt über die Elemente der Liste iterieren.
Sirius3
User
Beiträge: 11985
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 30. August 2014, 09:57

zusätzlich: um Strings zusammen zu bauen, ist Stringformatierung einem »+ str(x)« vorzuziehen.
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Samstag 30. August 2014, 15:41

Danke für die Verbesserungsvorschläge :D

Ich hab versucht aus der Docu über "connect" schlauer zu werden, aber versteh die exceptions nicht genau wie ich die abfangen kann :K Daher habe ich noch "connect_ex" drin. Vielleicht mag mir da jemand weiterhelfen? :)

Die Namensgebung bei mir ist wirklich bescheiden :roll:
(Hier bin ich mit connection allerdings nicht zufrieden. Ihr?)

str() habe ich ausgetauscht :wink:

hier der Code:

Code: Alles auswählen

import socket


def check(addr):
	connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	connection.settimeout(0.1)
	if connection.connect_ex((addr, 135)) == 0:
		connection.close()
		return True
	else:
		return False

def main():
	check_liste = []
	for ip in range(1, 25):
		addr = "%s%d" % ("192.168.0.", ip)
		is_up = check(addr)
		if is_up == True:
			print(addr, "Belegt")
			check_liste.append(addr)
		elif is_up == False:
			print(addr, "Frei")
	print()
	print("********************************")
	print()
	for item in check_liste:
		print("Belegt : ", item)

if __name__ == "__main__":
	main()


Sirius3
User
Beiträge: 11985
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 30. August 2014, 16:08

@TrayserCassa: Du hast die expliziten Vergleiche auf »True« und »False« immer noch drin, wobei die “False”-Bedingung durch ein einfaches »else« ersetzt werden kann.

Gemeint war

Code: Alles auswählen

addr = "192.168.0.%d" % ip
BlackJack

Samstag 30. August 2014, 16:33

Ungetestet:

Code: Alles auswählen

import socket as socketlib
from contextlib import closing
from itertools import islice

from ipaddress import ip_network


def check_if_up(ip_address):
    socket = socketlib.socket(socketlib.AF_INET, socketlib.SOCK_STREAM)
    socket.settimeout(0.1)
    try:
        with closing(socket.connect((str(ip_address), 135))):
            return True
    except socketlib.error:
        return False


def main():
    used_ips = list()
    for address in islice(ip_network('192.168.0.0/27').hosts(), 25):
        if check_if_up(address):
            used_ips.append(address)
            print(address, 'ist belegt.')
        else:
            print(address, 'ist frei.')
    print()
    print('*' * 70)
    print()
    for address in used_ips:
        print('Belegt:', address)


if __name__ == '__main__':
    main()
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Montag 1. September 2014, 13:30

@BlackJack Da kommt ein Fehler falls es die IP gibt.

Code: Alles auswählen

192.168.0.1 ist frei.
192.168.0.2 ist frei.
192.168.0.3 ist frei.
192.168.0.4 ist frei.
192.168.0.5 ist frei.
192.168.0.6 ist frei.
192.168.0.7 ist frei.
192.168.0.8 ist frei.
192.168.0.9 ist frei.
192.168.0.10 ist frei.
192.168.0.11 ist frei.
192.168.0.12 ist frei.
192.168.0.13 ist frei.
192.168.0.14 ist frei.
192.168.0.15 ist frei.
192.168.0.16 ist frei.
192.168.0.17 ist frei.
192.168.0.18 ist frei.
192.168.0.19 ist frei.
Traceback (most recent call last):
  File "test2.py", line 34, in <module>
    main()
  File "test2.py", line 21, in main
    if check_if_up(address):
  File "test2.py", line 13, in check_if_up
    return True
  File "C:\Python34\lib\contextlib.py", line 152, in __exit_
    self.thing.close()
AttributeError: 'NoneType' object has no attribute 'close'
Habe zurzeit leider wenig Zeit deshalb vergebt mir, wenn ich mal ne Woche nicht da bin. ;)

mfg
Trayser
BlackJack

Montag 1. September 2014, 13:42

Ebenfalls ungetestet:

Code: Alles auswählen

def check_if_up(ip_address):
    socket = socketlib.socket(socketlib.AF_INET, socketlib.SOCK_STREAM)
    socket.settimeout(0.1)
    try:
        with closing(socket):
            socket.connect((str(ip_address), 135))
            return True
    except socketlib.error:
        return False
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Montag 1. September 2014, 18:17

Jap so Funktioniert es :)

Danke für die mühen BlackJack

mfg
Trayser
Benutzeravatar
Fire Spike
User
Beiträge: 224
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 23. Oktober 2019, 19:20

Ich weiss das thema ist schon alt aber der code sagt bei jeder IP das sie frei ist und wie kann ich angeben welche er scannen soll? bei mir scannt er nur die ersten 30.
__deets__
User
Beiträge: 8103
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 23. Oktober 2019, 19:51

Schau mal auf die for-Schleife. Das erklaert die Limitierung. Und das ganze ist nur eine Heuristik, Port 135 ist wenn ich mich recht erinnere ein Windows port - da muss aber nix laufen, und ggf. haben neuere Versionen das auch dicht gemacht.
Benutzeravatar
Fire Spike
User
Beiträge: 224
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 23. Oktober 2019, 20:44

Wenn du diese

Code: Alles auswählen

for address in islice(ip_network('192.168.178.0/27').hosts(), 255):
meinst, da wo jetzt 255 steht zeigt immer noch nur 30 und was währe zb. ein plattformunabhängiger port?
Benutzeravatar
__blackjack__
User
Beiträge: 6006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 23. Oktober 2019, 22:22

@Fire Spike: Warum erwartest Du denn mehr als 30? Das Netzwerk das Du da angibst hat ja ganz offensichtlich 30, da wäre es sehr komisch wenn er mehr als 30 prüfen würde, oder?

Code: Alles auswählen

In [8]: 2 ** (32 - 27) - 2                                                      
Out[8]: 30
long long ago; /* in a galaxy far far away */
nezzcarth
User
Beiträge: 996
Registriert: Samstag 16. April 2011, 12:47

Donnerstag 24. Oktober 2019, 07:32

Oder mal andersrum gefragt: Hast du das /27 bewusst gesetzt, oder einfach aus dem Code oben übernommen? Wenn du das gesamte Class-C Netzwerk scannen möchtest, wäre /24 korrekt (s. CIDR-Notation).
Benutzeravatar
Fire Spike
User
Beiträge: 224
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Donnerstag 24. Oktober 2019, 11:51

@nezzcarth danke du hast mir geholfen. ist port 80 eine gute idee?
info: das ist mein eigenes wlan
Antworten