Plattformunabhängiges ICMP-Tool, wie mache ich das?
-
Grundsätzlich: die Netzwerkfunktionen sind betriebssystemabhängig. Also musst du platformspezifischen Code (mit
#defineo.ä. rein- oder rauskompiliert) in deiner Anwendung haben.
Aber: diesen Code musst du nicht selbst schreiben. Nimm einfach eine platformunabhängige Netzwerklibrary (die schon den Code für verschiedene Platformen enthält) wie z.B. boost.asio.Edit: zu spät.
PS: wenn es nur um Pings geht, könnte möglicherweise sogar
system("ping host");reichen.
-
Für mehrere Plattformen würde ich dir Boost.Aiso empfehlen.
*Zu spät*
-
Vielen Dank, das hilft schon mal weiter. Die einhellige Meinung ist also wohl, dass ich das nicht selbst implementieren kann, was sehr schade ist. Oder wenn ich es partout selbst implementieren will muss ich es für jedes OS anders schreiben.
Vielleicht muss ich mein Projekt nochmal überdenken.
Diese Library kannte ich noch nicht, sollte ich diese Anwendung also je schreiben müssen weil ich die Funktionalität brauche werde ich das wohl so machen. Da der Lerneffekt dabei wohl aber nicht so riesig ist, ist das nicht was ich mir erhofft hatte.Wäre schön gewesen wenn das irgendwie OS-unabhängig und nur mit der Standardlibrary möglich gewesen wäre.
-
- Boost ist Defactor-Standard.
- Du Unterschätzt den Lerneffekt.
-
Die Betriebssystemfunktionen sind absolutes Low-Level. Das ist nicht viel mehr als Senden und Empfangen von Bytestreams. Und jedes Betriebssystem hat da seine eigene Weise, wie es dir diese Funktionen zur Verfügung stellt. Das (und ein bischen mehr) wird von Bibliotheken wie Asio gekapselt.
Das eigentlich Interessante ist jetzt das darauf aufbauende Protokoll, und da musst du dir deine eigenen Gedanken machen.Du kannst die Problematik ein bisschen mit Dateien vergleichen. Das OS bietet Lesen und Schreiben aus Dateien, wobei das platformabhängig ist. Die Kapselung der Funktionen bietet dir in dem Fall gleich die Standardbibliothek durch die Filestreams, aber welche Library ist ja schlussendlich egal. Das eigentlich Interessante ist nämlich nicht das reine Lesen und Schreiben, sondern das darauf aufbauende. Z.B. wenn du die Dateifunktionen nutzt, um einen XML-Parser zu bauen.
-
Klar kannst du es selbst machen, auch so dass es auf allen von dir genannten Plattformen läuft und ohne sehr großen Aufwand. (Berkeley sockets gibt's auch für Mac oder?)
Klar du brauchst ein paar #defines, aber das passt schon.
http://www.zotteljedi.de/socket-tipps/index.html
http://www.zotteljedi.de/ping/index.htmlIst zwar C und kein C++, aber vielleicht hilft dir das ja.
Edit:
Für Windows brauchst du dann z.B. diese kleinen Extras:
http://msdn.microsoft.com/en-us/library/ms742213(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms741580(v=vs.85).aspxDas ist aber alles nichts, was man nicht selbst Plattformunabhängig hinfrickeln könnte!
-
Hallo nochmal und danke für alle Antworten.
Mittlerweile hat sich mein Zielbild in der Hinsicht etwas verschoben, da die BSD-Sockets ja ohnehin identisch sind habe ich mich mittlerweile entschieden das ganze in Objective-C für die höheren Teile (soll hauptsächlich auf Macs laufen) und plain C für die eigentlichen Netzwerkteile zu realisieren. Das reicht dann im Sinne der Portabilität. Somit ist das jetzt letztlich etwas themenfremd für dieses Forum, aber ich habe an dieser Stelle eine Frage.
Und zwar bezieht sich das auf die beste Art und Weise mein Ziel zu realisieren (abscannen eines definierten Netzwerksegments per ICMP Echo Paketen). Da ich den Netzwerkbereich von meinem Programm über IP-Adresse und Netzmaske des Hosts berechnen lasse, könnte es im Extremfall sein, dass der Rechner sich in einem riesigen Netz befindet (z.B. ehemaliges Klasse-A Netz, wie 10.0.0.0). Jetzt ist die Frage, wie scanne ich diesen Bereich ohne dass mir hier der Rechner zusammenklappt? Aus Geschwindigkeitsgründen beim Scan würde ich sagen ich kann hier nicht sequentiell vorgehen, sondern muss Childprozesse für jeden Host generieren die einen Socket erzeugen, das Echo-Paket absetzen, auf Antwort warten und dann zurückkehren (oder nach einem Timeout). Jetzt besteht da natürlich die Möglichkeit sich quasi einen hausgemachten DDoS Angriff bzw. eine Art Forkbomb zu basteln, wenn man überschreitet was das System verträgt.
Daher meine Frage, wie viele Sockets und Prozesse kann ich gleichzeitig öffnen, ohne dass mir das System zusammenklappt? Gibt es vielleicht einen besseren Ansatz? Wenn ich alles über einen Socket der Reihe nach ablaufen lasse würde der Scan wohl ewig dauern (je nach Timeout), mit der zusätzlichen Gefahr dass mir der Puffer überläuft und ich Daten verliere. Wenn ich einen Socket pro Zielhost öffne habe ich das Pufferproblem nicht, aber schneller wirds davon auch nicht. Bin ich vielleicht komplett auf dem Holzweg? Wie man leicht erkennen kann sind meine Erfahrungen in so systemnaher Programmierung bestenfalls dünn zu nennen.
Vielen Dank!
-
Generell ist das schon Netzwerktechnisch kritisch was da betreibst ....
Ne information, ob tausende Rechner grad online sind, wirst nicht zeitnah bekommen.
Wenn zeit hasst, wuerd ich dir auch dringenst empfehlen, die Zeit zu nutzen, also max vielleicht 20 verbindungen gleichzeitig zu pollen.
Selbst wenn dein System in der Lage waer, quasi ICMP -Packete für tausende von rechnern rauszuschicken ... der netzwerkAdmin fuer deinen Router / VPN Loesung spätestens wird Dir Ärger machen.
Und wenn ich (als Admin) sehe, das nen Rechner grad "so abgeht" im Netz, wuerde instiktiv zu diversen Cat / Power Kabeln greifen und dran ziehen wollen
wie viele Sockets und Prozesse kann ich gleichzeitig öffnen, ohne dass mir das System zusammenklappt?
Prozesse/Threads - fuer jedes System unterschiedlich,kann manchmal sogar konfiguriert werden (kernel) ... sagt dir normalerweisse die Spec, ne API vom System. Also Plattformunabhaengig wirst das ned hinbekommen.
Sockets ??? bei ICMP ... das ned verbindungsorientiert !
Senden: Also wirst den Socket nicht binden, also wirds eher irrelevant fuer dich sein. Eher releavnt wieviel Descriptoren dein System pro prozess gleichzeitig öffnen kann. Theorethisch kanns aber alles ueber ein Socket schicken.
Empfangen: Um alle Antwortpackete zu hören langt theorethisch auch ein socket !Trotzdem halt ich dein Ansinnen als ... naja fragwuerdig.
Warum willst du alle Hosts in nem Netzwerksegment pollen ?
Gibts da keine andere Loesung ?Ciao ...
-
Hallo,
der Admin in meinem Netzwerk bin ich, ich werd mir die Ohren nicht langziehen

Was ich damit erreichen will? Ich will sehen welche Hosts in meinem Segment up sind, quasi wer welche IP hat etc.
Ich habe prinzipiell gar kein Interesse daran ein so großes Netz zu scannen (vor allem auf einmal), aber da wie gesagt meine momentane Programmlogik das Segment selbst berechnet will ich wissen, wo ich hier die "Notbremse" ansetzen soll. Aus dem einfachen Grund damit eben kein kapitaler Absturz produziert wird sollte der Rechner doch z.B. in einem /8 Netz sein oder in der Richtung.Plattformunabhängig ist jetzt in erster Linie mal nicht so wichtig, geht um mein Macbook Pro und Geräte vergleichbarer Leistung (und Plattform).
Dass ICMP nicht verbindungsorientiert ist und ich alles von einem Socket losschießen könnte ist mir klar. Aber so wie ich das verstanden habe, blocke ich den Socket beim Empfangen der Antwort bis diese kommt oder bis zum Timeout. Wenn ich also alles über einen Socket abwickle und scanne das Netz von 192.168.1.0 bis 192.168.1.255 z.B. (ein absolut alltäglicher Vorgang bei mir), und der erste Host der up ist ist die .100, dann muss ich 99 Timeouts abwarten bis ich überhaupt die erste "ist up" Nachricht bekomme. Bzw. bis ich sie gelesen habe, da und gepuffert sollte sie bis dahin natürlich lange sein. Oder habe ich da etwas falsch verstanden? Ich gebe zu dass das reine angelesene Theorie ist, daher meine Fragen.
Router/VPN ist überhaupt nicht relevant, hier soll nichts geroutet werden, nur ein lokales Netzwerksegment abgesucht (das zudem mir gehört und von mir verwaltet wird). Solche zusätzlichen Komplikationen kann man also vernachlässigen.
Fragwürdig finde ich das nicht, eigentlich völlig alltäglich. Solche Tools sind absolut harmlos und benutze ich ständig, auf Windows z.B. das kostenlose Netscan von Softperfect. Nochmal, ich will nichts an seine Grenzen treiben, das ist nicht der Sinn der Frage. Ich will genau verhindern dass das passiert, aber dafür muss ich erst einmal wissen wo die Grenze liegt.
-
Tenthar schrieb:
dann muss ich 99 Timeouts abwarten bis ich überhaupt die erste "ist up" Nachricht bekomme.
Nein, musst du nicht, select() kehrt sofort zurück wenn an irgendeinem der übergebenen Deskriptoren etwas passiert ist. Das Timeout ist nur da, um select() vor ewigem Warten zu bewaren. (Also wenn sich an keinem der Sockets etwas tut.)
-
Tenthar schrieb:
Kann mir da jemand einen Pointer zu einem Tutorial geben
Generell wäre auch hier eine Referenz besser

* duckundweg *
-
Dagobrät Duck schrieb:
Tenthar schrieb:
Kann mir da jemand einen Pointer zu einem Tutorial geben
Generell wäre auch hier eine Referenz besser

* duckundweg *
Und was, wenn die Seite umzieht?
-
cooky451 schrieb:
Nein, musst du nicht, select() kehrt sofort zurück wenn an irgendeinem der übergebenen Deskriptoren etwas passiert ist. Das Timeout ist nur da, um select() vor ewigem Warten zu bewaren. (Also wenn sich an keinem der Sockets etwas tut.)
Habe ich dann nicht aber das Problem, dass ich nicht weiß was zurückgekommen ist? Ich verwende hier ja einen nichtverbundenen Socket (in dem Fall einen ICMP DGRAM Socket, da OSX das kann. Sonst müsste ich ja einen RAW Socket verwenden, der aber mehr Rechte benötigt). Daher sende ich ja mit sendto(), und müsste dann auch mit recvfrom() empfangen. So wie ich select() verstanden habe, sagt mir das nur Bescheid dass irgend etwas reingekommen ist. Dann muss ich aber trotzdem mit recvfrom() durchprobieren von welchem Host die Antwort kam, und wenn ich den falschen erwische blocke ich den Socket bis zum Timeout, es sei denn ich mache ihn non-blocking, wovon ich nur theoretisch gehört habe. Dann würde recvfrom() sofort zurückkehren wenn nichts entsprechendes vorliegt.
Vielleicht liege ich aber mal wieder völlig daneben, wie gesagt, ich bin hier noch in der Experimentierphase...
-
Zum allgeimen:
1. gibt es fertige Loesungen dafuer. Die funktionieren ned auf pollen, sondern die Hosts registrieren sich.
2. die rechner selber fahren teilweisse protokolle, wo jemand wissen muss, welcher rechner wo ist. Das funktioniert auch nicht mit pollen, sondern ueber A broadcasts, B. Registrierung.Beste weg ist, die vorhandenen Loesungen zu nutzen.
Du bist netzwerkadmin ... warum greifst die Info ned am DHCP server ab ? Sowas hasst du doch oder ?
Fuer wen schreibst du das Program ...
Soll es generisch funktionieren ? Also in irgendeiner Topologie, dann solltest auf das wahlweisse pollen soweiso verzichten.Ne Selbstgestrickte Loesung wuerd ich nach mit Aktiver Unterstuetzung der Clients bauen.
- mittels Registrierung:
Die Clients melden sich bei nem Server an und wieder ab. Due fragst nur noch den Server.- mittels Boradcast:
der Server setzt eine BoradcastMessage ab in dem Segment, und alle clients die aktiv sind, reagieren in dem sie eine Antwort an den server schicken ....Zu den Sockets:
du kannst nen Socket bauen, der auf jegliche ICMP nachricht hoert. also der kommt aus dem read zurueck, sobald irgendwas an dem Socket gelandet ist ...
Was das war, musst dann selber auswerten und vom wen das kam. So funktioniert auch UDP, nur mit dem unterschied, dass da scho die aufteilung auf Ports bei hasst.Wenn du schnell genug bist, bist schneller als die NW-karte und verzoegerst nichts

Wenn du nen socket fuer icmp nachrichten baust, landen auch alle icmp nachrichten in seinem Puffer, unabhaengig vom absender. Den absender musst du selber "ermitteln".Senden geht geht genau so ueber einen socket. Du schiebst das alles in nen buffer, und die karte schickt es raus, egal an wen ... ^^
wenn der buffer voll ist, blockiert dein socket so lange ...in dem Fall einen ICMP DGRAM Socket, da OSX das kann
OSX kenn ich ned , nur Linux ...
Aber hat modernes OSX ned nen linux kernel drunter ?ICMP geht IMHO nur mit Raws, deshalb brauchst bei dem doofen ping ja das suid-Bit. Oder hat sich da scho wieder was geaendert ?
Ciao ...
-
Das wird kein professionelles Tool, sondern nur für mich selbst und für den privaten Bereich. Auch und gerade um ein bisschen mit Sockets zu arbeiten. Mithilfe der Clients kann ich nicht voraussetzen, das muss schon so laufen wie ich das geplant habe. Natürlich kann ich am DHCP nachschauen, das ist aber nicht die Frage. Was hätte ich denn dabei gelernt?
Daher fällt Registrierung raus weil weder möglich noch gewünscht, und Broadcasts sind viel zu unzuverlässig (viele Geräte ignorieren das).
OSX basiert auf Unix und erlaubt ICMP Echo Requests über sowas hier:
socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)Aus genau dem von dir angeführten Grund, dass ein RAW Socket erhöhte Rechte benötigt. Das funktioniert auch einwandfrei, ich kann im Wireshark sowohl mein Paket als auch die Antwort sehen. Nur ist es im Moment halt noch ein einzelnes Paket, und ich verarbeite die Antwort noch nicht, da ich nicht sicher bin wie.
Was du zu den Sockets schreibst hört sich schon mal gut an, wäre mir ja egal ob das in einem Puffer landet oder nicht, hauptsache es funktioniert. Könntest du da noch genauer werden wie das funktionieren würde, bzw wie ich das dann auseinanderklauben müsste? Wie gesagt, ich war der Ansicht ich müsste recvfrom() benutzen und mache mir hier Sorgen um Blocken und Timeouts.
-
Wie gesagt, ich war der Ansicht ich müsste recvfrom() benutzen und mache mir hier Sorgen um Blocken und Timeouts.
ja und nein !
Wieso Sorgen ?
Du legst nen EmpfangsSocket fuer deinen ICMP Typ an, und der baut nen Buffer. In dem Buffer landen alle ICMP Datagramme.Wovor hasst du angst ? das du ned schnell genug bist und den Netzwerkverkehr "blockierst" oder ned alle packete bekommst ?
A iss unbegruendet,
B ist sogar wahrscheinlich, wenn tausende Rechner dich mit ihrer Antwort begluecken und dein Buffer voll ist, bekommst die nachfolgenden packete nicht mehr mit ... aber das ist UDP / ICMP typisch ...Was hätte ich denn dabei gelernt?
TCP/IP ist ein Protokoll fuer ein dezentrales Netzwerk. Alle Clients kennen zu wollen / muessen widerspricht der Philosophie. Eine Application die alle Computer im netzwerksegment kennen muss, wird nicht in jedem TCP/IP netzwerk funktionieren. Solche Ansaetze sind prinzipiell zu meiden ...
Ciao ...
-
Hey hey hey, warte mal, du hast recvfrom() völlig falsch verstanden! recvfrom() gibt dir die Adresse zurück, von der das Paket gesendet wurde. (Und empfängt genau so wie recv(), wenn du die Adresse nicht wissen möchtest, nimm halt recv()).
-
cooky451 schrieb:
Hey hey hey, warte mal, du hast recvfrom() völlig falsch verstanden! recvfrom() gibt dir die Adresse zurück, von der das Paket gesendet wurde. (Und empfängt genau so wie recv(), wenn du die Adresse nicht wissen möchtest, nimm halt recv()).
Tatsächlich. Jetzt wo dus sagst und ich nochmal nachgelesen habe frage ich mich, wie ich das jemals missverstehen konnte. Das kommt davon wenn man schnell obendrüber liest. Vielen Dank!
RHBaum schrieb:
B ist sogar wahrscheinlich, wenn tausende Rechner dich mit ihrer Antwort begluecken und dein Buffer voll ist, bekommst die nachfolgenden packete nicht mehr mit ... aber das ist UDP / ICMP typisch ...
Das ist tatsächlich eine meiner Sorgen. Ich muss da mal testen...
-
Das ist tatsächlich eine meiner Sorgen. Ich muss da mal testen...
Damit musst eh rechnen, wenn nicht verbindungsorientiert arbeitest!
Ich glaub aber nicht, das wenn du die pings einzeln adressierst, das du Genug anfragen rausbekommst, damit dich die Antworten ueberfluten
Das langsamere Glied in der Kette ist das Netzwerk selber hier, der Rechner sollte fix genug Daten runternehmen koennen. Kritischer seh ich nur, die Last die aufn Netzwerk erzugen könntest. Also bau einfach paar waitstates ein.
Ciao ...