Forum: PC-Programmierung IP-Subsysteme im LAN effektiv finden?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich stehe vor der Aufgabe, bestimmte Geräte, deren IPs zusammen mit 
anderen im LAN (Class C, Subnet 255.255.255.0) "verteilt" sind, schnell 
zu finden (die IP, die per DHCP verteilt wird).

Eine Reservierung anhand der MAC-Adresse im DHCP-Server oder eine 
Abfrage von dessen Lease-List sind nicht möglich, weil kein Zugang 
besteht.

Bisher habe ich einfach alle 254 Adressen (1-254) mit einem HTTP-Request 
durchgeleiert, denn die gesuchten Geräte antworten auf 
"http://a.b.c.d/?cmd=ident"; mit ihrem Gerätenamen, z.B. 
"<html>printmanager</html>". Fremde Gerät reagieren darauf nicht oder 
mit "Unsinn", so dass die Erkennung auf diese Weise kein Problem ist. 
Zumal sind die erwarteten Antworten bzw. Gerätenamen bekannt.

Das funktioniert sehr zuverlässig, aber eben langsam. Die MAC-Adressen 
der Subsysteme sind auch bekannt. Ich könnte natürlich auch schnell mal 
Alles durchpingen und dann den ARP-Cache aus einer Shell laden und darin 
herumparsen. Hier stört, dass die ARP-Resultate auf jeder Palttform 
(Win, Mac, Linux) anders formatiert sind ...

Hat jemand eine Idee, die er zum Besten geben möchte?

Auf die Insrallation zusätzlicher Tool soll verzichtet werden (z.B. 
"macping"), es muss mit Bordmitteln funktionieren.

Ansonsten bleibe ich halt einfach bei der trivialen Scan-Methode ...

: Bearbeitet durch User
von Mi. W. (mikuwi)


Lesenswert?

Frank E. schrieb:
> Ich stehe vor der Aufgabe, bestimmte Geräte, deren IPs zusammen mit
> anderen im LAN (Class C, Subnet 255.255.255.0) "verteilt" sind, schnell
> zu finden (die IP, die per DHCP verteilt wird).
>
> Das funktioniert sehr zuverlässig, aber eben langsam.

was ist "schnell" für Dich in einer üblichen SI-Einheit?

Programmausführung ohne Installationpipapo ist ok?

von Andreas M. (andreas_m62)


Lesenswert?

Ich benutze dazu das Programm NetSetMan in der kostenlosen Version.
Dazu einfach bei den Werkzeugen den Netzwerkscanner auswählen
und den zu durchsuchenden Netzwerkbereich eintragen und starten.

Mit dem Tool kann man auch viele verschiedene Netzwerkprofile anlegen
und mit eine Klick aktivieren.
Wenn man z.Bsp. in vielen verschiedenen Netzwerken arbeitet.

von Εrnst B. (ernst)


Lesenswert?

Multicast-DNS wurde genau für sowas gemacht, müssen deine Geräte im 
Netzwerk aber natürlich unterstützen.

von Rüdiger B. (rbruns)


Lesenswert?

NMap mit ZenMAp Gui. Sucht alle offene Ports im Subnet.

von Εrnst B. (ernst)


Lesenswert?

Rüdiger B. schrieb:
> NMap mit ZenMAp Gui. Sucht alle offene Ports im Subnet.

Will er ja garnicht. Er will nur die offenen Ports 80 (das kann man nmap 
noch mitteilen), und davon nur die, die auf seinen GET-Request korrekt 
antworten.

Sind 253 GET-Requests. Wenn er die parallel startet und nicht 
sequentiell, hat er in weniger als 0.1 Sekunden seine Liste fertig.

Schneller wird's mit einem externen Port-Scanning tool auch nicht.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Εrnst B. schrieb:

> Sind 253 GET-Requests. Wenn er die parallel startet und nicht
> sequentiell, hat er in weniger als 0.1 Sekunden seine Liste fertig.

Danke, gute Idee - mein Programmierwerkzeug "Xojo" kann tatsächlich 
Threads, das hatte ich garnicht mehr auf dem Schirm ... naja klar: Der 
Wald und die Bäume oder ich werd alt :-(

Wenn es statt der bisherigen 30s nur 3 sind bin ich schon zufrieden. Ich 
werde berichten. Ich muss mal gucken, wieviel RAM so ein Thread braucht, 
muss auf einem Raspi mit 2GB laufen ... aber auch das könnte ich 
dynamisch anpassen, weil ich ja jederzeit abfragen kann, wieviel RAM 
noch frei ist ...

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Mi. W. schrieb:
> Frank E. schrieb:
>> Ich stehe vor der Aufgabe, bestimmte Geräte, deren IPs zusammen mit
>> anderen im LAN (Class C, Subnet 255.255.255.0) "verteilt" sind, schnell
>> zu finden (die IP, die per DHCP verteilt wird).
>>
>> Das funktioniert sehr zuverlässig, aber eben langsam.
>
> was ist "schnell" für Dich in einer üblichen SI-Einheit?
>
> Programmausführung ohne Installationpipapo ist ok?

Als single thread bzw. in einer ganz gewöhnlichen For-Schleife im 
Hauptprogramm bis zu 30 ... 35 Sekunden.

von Εrnst B. (ernst)


Lesenswert?

Frank E. schrieb:
> Danke, gute Idee - mein Programmierwerkzeug "Xojo" kann tatsächlich
> Threads,

Threads sind an dieser Stelle overkill und machen es nur langsamer.
Hunderte gleichzeitige TCP-Verbindungen kann Unix seit einem halben 
Jahrhundert auch ohne Threads problemlos ("select", "poll" &co).

Bei deinem Xojo läuft es darauf hinaus, einfach statt hintereinander 
jedesmal ein
"connection.SendSync" zu starten, eben "connection.Send" zu verwenden.
Das kannst du ohne Verzögerung 253mal aufrufen, die Verbindungen laufen 
parallel im Hintergrund, und du bekommst im Erfolgsfall ein 
"ContentReceived"-Event, sonst ein "Error".

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Εrnst B. schrieb:
> Frank E. schrieb:
>> Danke, gute Idee - mein Programmierwerkzeug "Xojo" kann tatsächlich
>> Threads,
>
> Threads sind an dieser Stelle overkill und machen es nur langsamer.

> "connection.SendSync" zu starten, eben "connection.Send" zu verwenden.
> Das kannst du ohne Verzögerung 253mal aufrufen, die Verbindungen laufen
> parallel im Hintergrund, und du bekommst im Erfolgsfall ein
> "ContentReceived"-Event, sonst ein "Error".

Ok, hab ich so noch nicht versucht, klingt einleuchtend.

von Pandur S. (jetztnicht)


Lesenswert?

Die Adressen 127 und 255 sind Multicast adressen. Die werden also von 
allen empfangen. Du kannst also dort einen algorithmus durchziehen, bei 
welchem dir schliesslich jeder antwortet. Und zwar schneller wie jeden 
einzeln abzufragen.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Pandur S. schrieb:
> Die Adressen 127 und 255 sind Multicast adressen.

Eine 255 als Host-Adresse wäre eine Broadcast-Adresse in einem C-Netz, 
aber 127?

Oliver

von Hmmm (hmmm)


Lesenswert?

Pandur S. schrieb:
> Die Adressen 127 und 255 sind Multicast adressen.

Die letzte Adresse im Netz ist die Broadcast-Adresse (Multicast ist noch 
eine andere Baustelle), bei einem /24 also die .255.

Die .127 ist in diesem Fall ein Host wie jeder andere.

von Rüdiger B. (rbruns)


Lesenswert?

Einen Ping auf die Broadcast Adresse und der ARP Cache ist gefüllt.

von (prx) A. K. (prx)


Lesenswert?

Rüdiger B. schrieb:
> Einen Ping auf die Broadcast Adresse und der ARP Cache ist gefüllt.

Schon ausprobiert?

von Oliver R. (orb)


Lesenswert?

Rüdiger B. schrieb:
> Einen Ping auf die Broadcast Adresse und der ARP Cache ist
> gefüllt.

Ja?
> arp -a

Schnittstelle: 10.10.10.1 --- 0x1
Internetadresse       Physische Adresse     Typ
10.10.10.2         54-a6-02-d1-02-e5     dynamisch
10.10.10.255       ff-ff-ff-ff-ff-ff     statisch

> ping 10.10.10.255

Ping wird ausgeführt für 10.10.10.255 mit 32 Bytes Daten:
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.

Ping-Statistik für 10.10.10.255:
    Pakete: Gesendet = 4, Empfangen = 0, Verloren = 4
    (100% Verlust),

> arp -a

Schnittstelle: 10.10.10.1 --- 0x1
Internetadresse       Physische Adresse     Typ
10.10.10.2         54-a6-02-d1-02-e5     dynamisch
10.10.10.255       ff-ff-ff-ff-ff-ff     statisch


ups.

Hmmm schrieb:
> Die .127 ist in diesem Fall ein Host wie jeder andere.

Aber nicht bei /25 ;-)

von Mario M. (thelonging)


Lesenswert?

Rüdiger B. schrieb:
> Einen Ping auf die Broadcast Adresse und der ARP Cache ist gefüllt.

"An ICMP Echo Request destined to an IP broadcast or IP multicast 
address MAY be silently discarded."

http://www.faqs.org/rfcs/rfc1122.html

von Hmmm (hmmm)


Lesenswert?

Mario M. schrieb:
> "An ICMP Echo Request destined to an IP broadcast or IP multicast
> address MAY be silently discarded."

Das ist heutzutage auch der Regelfall, bei mir antwortet gerade mal ein 
Drucker darauf.

In den 90ern war das noch anders, da wurden Unternehmen auch gerne mal 
zu unfreiwilligen DoS-Helfern, wenn die Admins "no ip 
directed-broadcast" nicht kannten.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich mach das inzwischen mit einer Kombination aus Ping auf die IP und 
anschließendem arp mit der IP als Argument. Das ergibt als Antwort die 
MAC-Adresse für genau diese IP und keine meterlange Liste :-)

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Frank E. schrieb:

> Ich mach das inzwischen mit einer Kombination aus Ping auf die IP und
> anschließendem arp mit der IP als Argument. Das ergibt als Antwort die
> MAC-Adresse für genau diese IP und keine meterlange Liste :-)

So ein Blödsinn. Richtig wäre natürlich einfach ein ARP-WhoHas an die 
Broadcast-Adresse des interessierenden Netzes für jede IP-Adresse des 
interessierenden Netzes.

Und asynchron dazu einsammeln, was da an ARP-IsAt-Antworten eintrudelt. 
Also genau das tun, was ARP halt so tut (wenn eben auch normalerweise 
nur für gezielte Fragen).

Kein Ahnung, was Ping (also ICMP-Echo) dabei soll. Hat doch mit der 
Sache garnix zu schaffen. Kein Schwein interessiert sich dafür, ob das 
Target gewillt ist, auf ICMP-Echo zu antworten. Was interessiert ist: 
ist es überhaupt gewillt, irgendwie per IP zu kommunizieren.

Aber:
1. Es gibt Geräte, die ihre Bereitschaft, per IP zu kommunizieren, nicht 
so einfach verraten. Die wollen vorher erstmal noch einen anderen 
Broadcast sehen. Oder sogar eine ganz bestimmte Folge solcher 
Broadcasts. Bis sie die sehen, halten sie sich IP-mäßig bedeckt.
2. Es gibt sogar Geräte, die überhaupt niemals per IP kommunizieren, 
aber trotzdem das Netz benutzen. Halt nur auf Layer2.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ob S. schrieb:
> Frank E. schrieb:
>
>> Ich mach das inzwischen mit einer Kombination aus Ping auf die IP und
>> anschließendem arp mit der IP als Argument. Das ergibt als Antwort die
>> MAC-Adresse für genau diese IP und keine meterlange Liste :-)

> So ein Blödsinn. Richtig wäre natürlich einfach ein ARP-WhoHas an die
> Broadcast-Adresse des interessierenden Netzes für jede IP-Adresse des
> interessierenden Netzes.

Mag sein. Und wie starte ich das per CLI? ARP kennt keinen Befehl, mit 
"who". Aber vielleicht ist es ja das, was ich ohnehin mache?

> Kein Ahnung, was Ping (also ICMP-Echo) dabei soll. Hat doch mit der
> Sache garnix zu schaffen. Kein Schwein interessiert sich dafür, ob das
> Target gewillt ist ...

Doch. Die Targets, um die es MIR geht, abntworten definitiv auf Ping. 
Ich mache ja keinen allgemeinen Scan, sondern suche genau diese.

Aus Experimenten weiss ich, dass ich eine ARP-Antwort nur dann sicher 
erhalte, wenn vorher eine Kommuniktion stattfand, z.B. Ping.

von Mario M. (thelonging)


Lesenswert?

Ob S. schrieb:
> Kein Ahnung, was Ping (also ICMP-Echo) dabei soll.

Ping löst einen ARP-Request aus. Die MAC landet im ARP-Cache und kann 
mit arp -a angezeigt werden. Sozusagen ein "poor mans" arping.

von Εrnst B. (ernst)


Lesenswert?

Und 253-mal Ping (ggfs sogar auch per Kommandozeilen-Ping-Tool) und dann 
den arp-cache auslesen (per Kommandozeilen-Tool) soll schneller sein, 
als einfach aus deinem Programm die 253 IPs per HTTP-Get durchzutesten?
Kann ich mir nicht vorstellen. Und du brauchst den HTTP-Get nach dem ARP 
sowieso auch noch, für dein ?cmd=ident...

Und das Vorab-Filtern nach bekannter MAC kann dir bei etwas komplexeren 
Network-Setups auch auf die Füße fallen, Stichwort VPN, ProxyArp, usw...

von Jens B. (dasjens)


Lesenswert?

Εrnst B. schrieb:

> Sind 253 GET-Requests. Wenn er die parallel startet und nicht
> sequentiell, hat er in weniger als 0.1 Sekunden seine Liste fertig.
>

Wie kann ich über eine Serielle Leitung Parallel scannen? :P

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Jens B. schrieb:
> Εrnst B. schrieb:
>
>> Sind 253 GET-Requests. Wenn er die parallel startet und nicht
>> sequentiell, hat er in weniger als 0.1 Sekunden seine Liste fertig.
>>
>
> Wie kann ich über eine Serielle Leitung Parallel scannen? :P

Nur quasi: Threads.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Εrnst B. schrieb:

> Und das Vorab-Filtern nach bekannter MAC kann dir bei etwas komplexeren
> Network-Setups auch auf die Füße fallen, Stichwort VPN, ProxyArp, usw...

Ich will kein universelles Werkzeug, ich brauche nur die Antwort der 
Clients im gleichen LAN/24. Und ich weiss, wie viele ich finden muss (4 
Stück), kann also aufhören, sobald alle erkannt sind.

Allzuviele Sockets gleichzeitig scheint mir auch keine so gute Idee, 
weil das Ganze am Raspi 4 mit 2GB laufen muss, keine Ahnung wie viele 
das Raspian  abkann. Vielleicht hat jemand dazu eine Idee.

Es ist ja nicht so, dass die biherige Methode nicht funktioniert, ich 
hätte sie nur gerne etwas beschleunigt. Deshalb alles komplett 
umzustellen lohnt sich allerdings auch nur in Grenzen.

von Franko S. (frank_s866)


Lesenswert?

Frank E. schrieb:
> Nur quasi: Threads.
So machen das DAUs wenn sie besonders schlau sein wollen.

von Εrnst B. (ernst)


Lesenswert?

Frank E. schrieb:
> Allzuviele Sockets gleichzeitig scheint mir auch keine so gute Idee,
> weil das Ganze am Raspi 4 mit 2GB laufen muss

Auf dem Raspi kriegst du locker 10000 gleichzeitige GET-Requests mit 
deinen Datenmengen hin, bevor der überhaupt auf 1% CPU-Auslastung 
kommt... Allerdings nicht wenn man das über 10000 gleichzeitig laufende 
Threads löst.
Ein einziger Aufruf des "arp"-Utilities aus deinem Programm heraus 
braucht schon mehr Ressourcen als der ganze Scan per TCP/HTTP... Und ist 
ja scheinbar auch kein Thema, was deinen RasPi irgendwie überfordert.

Kurz getestet: 254 sockets (NONBLOCK) aufgemacht, allen ein "connect" 
gegeben, alle per epoll_ctl(...EPOLL_ADD zu einem epoll-fd hinzugefügt.

Dann per epoll_wait warten, was auf den einzelnen sockets passiert, mit 
timeout.

Die Userspace-CPU-Zeit ist mit "time" nicht mehr messbar, 
system/kernel-Zeit liegt bei ~12millisekunden, "real"-Zeit hängt vom 
gewählten Timeout ab.
1
> time ./conn_test 192.168.23
2
Successful connection to 192.168.23.1
3
Successful connection to 192.168.23.8
4
Successful connection to 192.168.23.17
5
Successful connection to 192.168.23.120
6
Timeout reached. Stopping.
7
8
real    0m0,279s
9
user    0m0,000s
10
sys     0m0,012s

Das wird auch nicht mehr fett, wenn man dann die sowieso schon 
verbundenen Sockets nimmt um ein "GET /?cmd=ident HTTP/1.0\r\n\r\n" 
hinterherzuschicken, und die Antwort auszulesen.

von Εrnst B. (ernst)


Lesenswert?

Nachtrag: Das mit <1% CPU war etwas übertrieben.
Wenn ich auf die Weise 192.168.0.0/16 scanne (Also ~ 64k gleichzeitig 
verbindende TCP-Sockets)
dann lastet das für etwas über 2 Sekunden einen CPU-Kern aus.
d.H. da würde es dann langsam Sinn machen das Ganze auf 4 Threads zu 
verteilen.
1
Successful connection to 192.168.1.8
2
Successful connection to 192.168.1.10
3
Successful connection to 192.168.1.11
4
Successful connection to 192.168.1.182
5
Successful connection to 192.168.1.189
6
Successful connection to 192.168.1.125
7
Successful connection to 192.168.1.163
8
Successful connection to 192.168.1.254
9
Successful connection to 192.168.1.154
10
Successful connection to 192.168.1.190
11
Successful connection to 192.168.1.191
12
Successful connection to 192.168.23.8
13
Successful connection to 192.168.23.17
14
Successful connection to 192.168.1.188
15
Successful connection to 192.168.1.134
16
Successful connection to 192.168.23.1
17
Successful connection to 192.168.1.184
18
Successful connection to 192.168.1.124
19
Successful connection to 192.168.144.1
20
Successful connection to 192.168.144.22
21
Timeout reached. Stopping.
22
23
real    0m2,415s
24
user    0m0,048s
25
sys     0m2,105s

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.