Ping (ICMP)?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
movies1978
User
Beiträge: 15
Registriert: Montag 13. Februar 2006, 13:25

Gibt es unter Python ein Möglichkeit, möglichst ohne externe Bibliotheken. Pings abzusenden? Oder ist die einzige Möglichkeit in dem Bereich Sockets? Könnte man mit Sockets denn überhaupt ICMP Pakete generieren?

Mfg
Mathias
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Ich weiß nicht ob du das suchst, aber:

Code: Alles auswählen

import os
os.system('ping 127.0.0.1')
mfg

Thomas :-)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Das kannst du mit Raw-Sockets machen, ist aber aufwendig. Musst halt das Packet selber generieren.

Hier siehst du wie:
ftp://ftp.visi.com/users/mdc/ping.py

Gruss
movies1978
User
Beiträge: 15
Registriert: Montag 13. Februar 2006, 13:25

Hi leider funktioniert keiner der beiden Lösungen auf meinem Symbian Smartphone. Dies hängt wahrscheinlich damit zusammen, dass die Implementation noch beta is und einige Funktionen nicht gar implementiert sind.
Mathias
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

movies1978 hat geschrieben:Hi leider funktioniert keiner der beiden Lösungen auf meinem Symbian Smartphone. Dies hängt wahrscheinlich damit zusammen, dass die Implementation noch beta is und einige Funktionen nicht gar implementiert sind.
Mathias
Das hättest du auch mal sagen können, dass das für ein Smartphone gedacht ist. Mein Vorschlag ist natürlich für ein Windows System gedacht. :?
mfg

Thomas :-)
jAN
User
Beiträge: 170
Registriert: Samstag 4. Juni 2005, 18:51
Wohnort: Großmehlra (in Thüringen)
Kontaktdaten:

kann man auf dem smartphone irgendwie über eine console ienne ping befehl absenden?
#adios.py
import os,sys
while 1: os.startfile(sys.argv[0])
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

movies1978 hat geschrieben:Pings abzusenden?
Hi Mathias!

Ich habe das etwas mit Google gefunden. Vielleicht bringt es dich weiter:
http://www.thescripts.com/forum/thread21672.html
http://www.python.org/~jeremy/python.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

EDIT (jens): Sourcecode ist nun auch in meinem SVN: http://pylucid.net:8080/pylucid/browser ... ts/ping.py
Ich hab den sourcecode mal umgeschrieben:

Code: Alles auswählen

#!/usr/bin/env python

#
# Original Version from Matthew Dixon Cowles:
#   -> ftp://ftp.visi.com/users/mdc/ping.py
#
# Rewrite by Jens Diemer:
#   -> http://www.python-forum.de/post-69122.html#69122
#

# Derived from ping.c distributed in Linux's netkit. That code is
# copyright (c) 1989 by The Regents of the University of California.
# That code is in turn derived from code written by Mike Muuss of the
# US Army Ballistic Research Laboratory in December, 1983 and
# placed in the public domain. They have my thanks.

# Bugs are naturally mine. I'd be glad to hear about them. There are
# certainly word - size dependenceies here.

# Copyright (c) Matthew Dixon Cowles, <http://www.visi.com/~mdc/>.
# Distributable under the terms of the GNU General Public License
# version 2. Provided with no warranties of any sort.

# Note that ICMP messages can only be sent from processes running
# as root.

# Revision history:
#
# May 30, 2007
# little rewrite by Jens Diemer:
#  -  change socket asterisk import to a normal import
#  -  replace time.time() with time.clock()
#  -  delete "return None" (or change to "return" only)
#  -  in checksum() rename "str" to "source_string"
#
# November 22, 1997
# Initial hack. Doesn't do much, but rather than try to guess
# what features I (or others) will want in the future, I've only
# put in what I need now.
#
# December 16, 1997
# For some reason, the checksum bytes are in the wrong order when
# this is run under Solaris 2.X for SPARC but it works right under
# Linux x86. Since I don't know just what's wrong, I'll swap the
# bytes always and then do an htons().
#
# December 4, 2000
# Changed the struct.pack() calls to pack the checksum and ID as
# unsigned. My thanks to Jerome Poincheval for the fix.
#

import os, sys, socket, struct, select, time

# From /usr/include/linux/icmp.h; your milage may vary.
ICMP_ECHO_REQUEST = 8 # Seems to be the same on Solaris.


def checksum(source_string):
    """
    I'm not too confident that this is right but testing seems
    to suggest that it gives the same answers as in_cksum in ping.c
    """
    sum = 0
    countTo = (len(source_string)/2)*2
    count = 0
    while count<countTo:
        thisVal = ord(source_string[count + 1])*256 + ord(source_string[count])
        sum = sum + thisVal
        sum = sum & 0xffffffff # Necessary?
        count = count + 2

    if countTo<len(source_string):
        sum = sum + ord(source_string[len(source_string) - 1])
        sum = sum & 0xffffffff # Necessary?

    sum = (sum >> 16)  +  (sum & 0xffff)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xffff

    # Swap bytes. Bugger me if I know why.
    answer = answer >> 8 | (answer << 8 & 0xff00)

    return answer


def receive_one_ping(my_socket, ID, timeout):
    """
    receive the ping from the socket.
    """
    timeLeft = timeout
    while True:
        startedSelect = time.clock()
        whatReady = select.select([my_socket], [], [], timeLeft)
        howLongInSelect = (time.clock() - startedSelect)
        if whatReady[0] == []: # Timeout
            return

        timeReceived = time.clock()
        recPacket, addr = my_socket.recvfrom(1024)
        icmpHeader = recPacket[20:28]
        type, code, checksum, packetID, sequence = struct.unpack(
            "bbHHh", icmpHeader
        )
        if packetID == ID:
            bytesInDouble = struct.calcsize("d")
            timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
            return timeReceived - timeSent

        timeLeft = timeLeft - howLongInSelect
        if timeLeft <= 0:
            return


def send_one_ping(my_socket, dest_addr, ID):
    """
    Send one ping to the given >dest_addr<.
    """
    dest_addr  =  socket.gethostbyname(dest_addr)

    # Header is type (8), code (8), checksum (16), id (16), sequence (16)
    my_checksum = 0

    # Make a dummy heder with a 0 checksum.
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
    bytesInDouble = struct.calcsize("d")
    data = (192 - bytesInDouble) * "Q"
    data = struct.pack("d", time.clock()) + data

    # Calculate the checksum on the data and the dummy header.
    my_checksum = checksum(header + data)

    # Now that we have the right checksum, we put that in. It's just easier
    # to make up a new header than to stuff it into the dummy.
    header = struct.pack(
        "bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1
    )
    packet = header + data
    my_socket.sendto(packet, (dest_addr, 1)) # Don't know about the 1


def do_one(dest_addr, timeout):
    """
    Returns either the delay (in seconds) or none on timeout.
    """
    icmp = socket.getprotobyname("icmp")
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    my_ID = os.getpid() & 0xFFFF

    send_one_ping(my_socket, dest_addr, my_ID)
    delay = receive_one_ping(my_socket, my_ID, timeout)

    my_socket.close()
    return delay


def verbose_ping(dest_addr, timeout = 2, count = 4):
    """
    Send >count< ping to >dest_addr< with the given >timeout< and display
    the result.
    """
    for i in xrange(count):
        print "ping %s..." % dest_addr,
        try:
            delay  =  do_one(dest_addr, timeout)
        except socket.gaierror, e:
            print "failed. (socket error: '%s')" % e[1]
            break

        if delay  ==  None:
            print "failed. (timeout within %ssec.)" % timeout
        else:
            delay  =  delay * 1000
            print "get ping in %0.4fms" % delay
    print


if __name__ == '__main__':
    verbose_ping("heise.de")
    verbose_ping("google.com")
    verbose_ping("a-test-url-taht-is-not-available.com")
    verbose_ping("192.168.1.1")
Beispiel Ausgabe:

Code: Alles auswählen

ping heise.de... get ping in 14.6611ms
ping heise.de... get ping in 14.3045ms
ping heise.de... get ping in 14.6112ms
ping heise.de... get ping in 14.0498ms

ping google.com... get ping in 115.8470ms
ping google.com... get ping in 115.5172ms
ping google.com... get ping in 115.3419ms
ping google.com... get ping in 115.0621ms

ping a-test-url-taht-is-not-available.com... failed. (socket error: 'getaddrinfo failed')

ping 192.168.1.1... failed. (timeout within 2sec.)
ping 192.168.1.1... failed. (timeout within 2sec.)
ping 192.168.1.1... failed. (timeout within 2sec.)
ping 192.168.1.1... failed. (timeout within 2sec.)
Ich weiß nicht was man noch verbessern könnte. In den ursprünglichen Kommentaren steht ja, das der Author auch nicht so ganz genau weiß, was er da gemacht hat ;)
Es funktioniert aber recht gut...

Alternativen findet man noch einige: http://www.google.de/search?q=ping.py
Zuletzt geändert von jens am Mittwoch 7. November 2007, 16:56, insgesamt 1-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich habe seinerzeit mal ein kleines Tool mit dem Aussehen eines Instant-Messengers gebastelt, das Hosts in Intervallen pingt. Dazu habe ich noch die Implementierungen folgender Personen/Projekte auf meiner Platte, die ich mir dazu angesehen habe: Jeremy Hylton, Lars Strand, Impacket, Scapy. Die eine oder andere mehr wird es wohl noch geben.

Über Raw-Sockets lässt sich das auch lösen (bzw. tun das wohl die meisten oder gar alle der Implementierungen auch), allerdings soll das wohl ab WinXP SP2 nicht mehr möglich sein, weil Raw-Sockets "verboten" wurden. Inwieweit das bei Symbian oder Series 60 aussieht, kann ich dir aber nicht sagen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Y0Gi hat geschrieben:allerdings soll das wohl ab WinXP SP2 nicht mehr möglich sein, weil Raw-Sockets "verboten" wurden.
Mein Skript läuft einwandfrei auf XP mit SP2... Ich kann mir vorstellen, das die Windows-Firewall evtl. dazwischen funkt. Die nutzte ich allerdings nicht ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:
Y0Gi hat geschrieben:allerdings soll das wohl ab WinXP SP2 nicht mehr möglich sein, weil Raw-Sockets "verboten" wurden.
Mein Skript läuft einwandfrei auf XP mit SP2...
Nutzt du etwa Raw-Sockets?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Leonidas hat geschrieben:
jens hat geschrieben:
Y0Gi hat geschrieben:allerdings soll das wohl ab WinXP SP2 nicht mehr möglich sein, weil Raw-Sockets "verboten" wurden.
Mein Skript läuft einwandfrei auf XP mit SP2...
Nutzt du etwa Raw-Sockets?
Ja, eigentlich schon... socket.SOCK_RAW erzeugt Raw Sockets. Mein Linux zumindest verweigert die Ausführung ohne root-Rechte.
Grossmeister_C
User
Beiträge: 36
Registriert: Montag 26. Februar 2007, 15:53

"However, the ability to send traffic over raw sockets has been restricted in two ways:

* TCP data cannot be sent over raw sockets.
* UDP datagrams with invalid source addresses cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. "


http://blogs.msdn.com/michael_howard/ar ... 13611.aspx
lunar

Grossmeister_C hat geschrieben:"However, the ability to send traffic over raw sockets has been restricted in two ways:

* TCP data cannot be sent over raw sockets.
* UDP datagrams with invalid source addresses cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. "

http://blogs.msdn.com/michael_howard/ar ... 13611.aspx
Und was genau hat das mit Pings zu tun? ICMP setzt eine Ebene tiefer an als TCP oder UDP. Die Einschränkungen betreffen ICMP Pakete (also auch Pings) nicht.
Grossmeister_C
User
Beiträge: 36
Registriert: Montag 26. Februar 2007, 15:53

Ok da haste auch wieder Recht. Ich versuche nur gerade das gesamte Dokument zu finden von dem er da redet, dem "Changes in functionality...". Aber entweder bin ich blind oder das ist nicht mehr zu finden.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Und was genau hat das mit Pings zu tun? ICMP setzt eine Ebene tiefer an als TCP oder UDP. Die Einschränkungen betreffen ICMP Pakete (also auch Pings) nicht.
Ergo das erklärt, warum das Programm auch mit SP2 funktioniert.

Wobei, ich finde die Idee Raw-Sockets zu beschneiden als Schutz gegen was auch immer ziemlich bescheuert. Würde mich interessieren, wie viel das gebracht hat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Irgendwer, ich glaube ein sogar recht bekannter und respektierter Autor, hat sich mal darüber ausgelassen, dass Windows überhaupt User-programmierbare Raw Sockets eingeführt hat. Grund war wohl, dass es Malware-Autoren und Spammern weitreichende Möglichkeiten an die Hand gibt, kompromittierte Zombie-Rechner noch umfassender und verdeckter zu missbrauchen.
Actimehl
User
Beiträge: 6
Registriert: Donnerstag 7. September 2006, 14:37

Ja wegen der Misbrauchsmöglichkeiten haben die das gemacht, auch wenn es sinnlos ist. Die Leute die Schaden anrichten wollen, können das immer noch und die Leute die das eventuell brauchen sind gekniffen.

Hab von nem Programm gelesen, dass raw-Sockets brauchte und dann nicht mehr funktioniert hat, der Workaround unter Windows: das Programm sendet jetzt raw-Ethernetframes und kann dann wieder alles machen, ergo nur eine lästige Einschränkung aber keine wirksame.
lunar

Leonidas hat geschrieben:Wobei, ich finde die Idee Raw-Sockets zu beschneiden als Schutz gegen was auch immer ziemlich bescheuert. Würde mich interessieren, wie viel das gebracht hat.
Naja, irgendwas mussten sie ja tun ;)

Unter Linux sind Raw-Sockets ja auch eingeschränkt, indem sie dem root vorbehalten sind... dumm ist halt nur, dass unter Windows jeder als "root" unterwegs ist ;)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nur zur Info, ping.py ist nun auch in meinem SVN zu finden ;)

http://pylucid.net:8080/pylucid/browser ... ts/ping.py

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten