Ping (ICMP)?
-
- User
- Beiträge: 15
- Registriert: Montag 13. Februar 2006, 13:25
Ping (ICMP)?
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
Mfg
Mathias
-
- 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
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
-
- User
- Beiträge: 15
- Registriert: Montag 13. Februar 2006, 13:25
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
Thomas

- gerold
- Python-Forum Veteran
- Beiträge: 5554
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Telfs (Tirol)
- Kontaktdaten:
Re: Ping (ICMP) ????
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.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- jens
- Moderator
- Beiträge: 8458
- 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:
Beispiel Ausgabe:
[code=]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.)[/code]
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
rayo hat geschrieben:ftp://ftp.visi.com/users/mdc/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=]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.)[/code]
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.
CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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.
Ü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.
- jens
- Moderator
- Beiträge: 8458
- 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

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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.
-
- 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
* 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
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.
-
- User
- Beiträge: 36
- Registriert: Montag 26. Februar 2007, 15:53
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder