Hallo Pythonfreunde,
Ich möchte die Netzwerkpakete von einem Server inspizieren. In der Pythondokumentation habe ich auch ein Beispiel gefunden:
import socket
HOST = socket.gethostbyname(socket.gethostname())
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print (s.recvfrom(65565))
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
Dieser Quelltext läuft aber auf meinem Debian unter Python 3.1 nicht. Durch Googln habe ich herrausgefunden das der Quelltext uralt wäre und angepasst werden müsste.
AF_INET soll man nicht nehmen, sondern AF_PACKET
Statt dem HOST soll man den Ethernetadapter eintragen
Anschließend sieht der Quelltext so aus:
import socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind(("eth0", 0))
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print (s.recvfrom(65565))
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
Dann bekomme ich aber diese Fehlermeldung wenn ich das Script als root ausführe:
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
File "<string>", line 1, in setsockopt
socket.error: [Errno 92] Protocol not available
Was mache ich falsch? Anscheinend ging das ja mal in Python irgendwie. Sachen wie Impacket, Scapy, Pycap oder wie der ganze Mist heisst möchte ich nicht verwenden.
raw socket - aber wie?
Du solltest dir mal die Dokumentation für Python 3.1 zu sockets ansehen. (Unten gibt es auch ein paar gute Beispiele)
Sieht mir aber nicht ganz danach aus, woher hast du AF_PACKET und wieso sollte man bei HOST "eth0" angeben - in der Dokumentation steht etwas anderes. Auch wenn du irgendwo etwas anderes findest, so gibt es nicht auf einmal mehr Konstanten, wie deine gegoogelte AF_PACKET.
Also wenn ich den Quelltext in der Dokumentation ausführe (also mein erstes Quelltextbeispiel ganz oben) bekomme ich diese Fehlermeldung.
Traceback (most recent call last):
File "test.py", line 3, in <module>
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
File "/usr/lib/python3.1/socket.py", line 184, in __init__
_sock = _realsocket(family, type, proto)
socket.error: [Errno 93] Protocol not supported
Nach rumgoogeln der Fehlermeldungen habe ich diese Tipps mit AF_PACKET und HOST bekommen. Das hat aber auch nicht geholfen
Traceback (most recent call last):
File "test.py", line 3, in <module>
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
File "/usr/lib/python3.1/socket.py", line 184, in __init__
_sock = _realsocket(family, type, proto)
socket.error: [Errno 93] Protocol not supported
Nach rumgoogeln der Fehlermeldungen habe ich diese Tipps mit AF_PACKET und HOST bekommen. Das hat aber auch nicht geholfen

AF_INET ist für IPv4, vieleicht brauchst du AF_INET6. - steht weiter oben in der Dokumentation. Und der Host ist immer eine IP-Adresse.
Ich brauch schon IPv4. IPV6 hab ich garnicht
Als HOST hab ich schon alles versucht. 'localhost' '127.0.0.1' '192.168.0.2' oder 'squeeze'
geht alles nicht.
Also wie gesagt. Ich habe mich exakt an die Dokumentation gehalten. Dieser Quelltext ist ja sogar aus der aktuellen Pythondokumentation:
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# receive a package
print s.recvfrom(65565)
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
mit der Fehlermeldung
Traceback (most recent call last):
File "test.py", line 3, in <module>
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
File "/usr/lib/python3.1/socket.py", line 89, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
socket.error: [Errno 93] Protocol not supported
Läuft denn der Quelltext aus der Dokumentation bei dir?
Als HOST hab ich schon alles versucht. 'localhost' '127.0.0.1' '192.168.0.2' oder 'squeeze'
geht alles nicht.
Also wie gesagt. Ich habe mich exakt an die Dokumentation gehalten. Dieser Quelltext ist ja sogar aus der aktuellen Pythondokumentation:
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# receive a package
print s.recvfrom(65565)
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
mit der Fehlermeldung
Traceback (most recent call last):
File "test.py", line 3, in <module>
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
File "/usr/lib/python3.1/socket.py", line 89, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
socket.error: [Errno 93] Protocol not supported
Läuft denn der Quelltext aus der Dokumentation bei dir?
Jupp, bei mir läuft der ohne Probleme, wieso auch nicht :K (habe allerdings keine Debaindistro zur Hand. Aber das Problem ist ja, dass das Protokoll nicht unterstützt wird und es gibt nur ein paar verschiedene AF-Protokolle und ich nehme an du hast diese alle schon ausprobiert und nicht einfach gleich abgetan?
Lass dir die Daten doch mal ausgeben mit: socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC)
Lass dir die Daten doch mal ausgeben mit: socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC)
Uiii. Bei dir läuft das echt? Interessante Info. Also muss der Fehler ja bei mir im System liegen.
Ja. Habe anstatt socket.AF_INET schon probiert:
socket.AF_UNIX¶
socket.AF_INET¶
socket.AF_INET6¶
Das interessante ist vielleicht das wenn ich AF_UNIX verwende kommt diese Fehlermeldung:
Traceback (most recent call last):
File "test.py", line 6, in <module>
s.bind((HOST, 0))
TypeError: argument must be bytes or read-only buffer, not tuple
socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC) gibt folgendes zurück
[(2, 1, 6, '', ('192.168.0.1', 0)), (2, 2, 17, '', ('192.168.0.1', 0)), (2, 3, 0, '', ('192.168.0.1', 0))]
Ja. Habe anstatt socket.AF_INET schon probiert:
socket.AF_UNIX¶
socket.AF_INET¶
socket.AF_INET6¶
Das interessante ist vielleicht das wenn ich AF_UNIX verwende kommt diese Fehlermeldung:
Traceback (most recent call last):
File "test.py", line 6, in <module>
s.bind((HOST, 0))
TypeError: argument must be bytes or read-only buffer, not tuple
socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC) gibt folgendes zurück
[(2, 1, 6, '', ('192.168.0.1', 0)), (2, 2, 17, '', ('192.168.0.1', 0)), (2, 3, 0, '', ('192.168.0.1', 0))]
Zuletzt geändert von aluis am Mittwoch 11. Mai 2011, 09:18, insgesamt 1-mal geändert.
Gib dir mal HOST aus, ist warscheinlich ein tuple.
Und was sind die Zahlen davor, die Funktion gibt dir family, socktype, proto, canonname, sockaddr zurück. "family" ist das entsprechende Protokoll.
Und was sind die Zahlen davor, die Funktion gibt dir family, socktype, proto, canonname, sockaddr zurück. "family" ist das entsprechende Protokoll.
@aluis: Zum Beispiel aus der Dokumentation mal ein Zitat aus der Dokumentation (Hervorhebung von mir):
http://docs.python.org/release/3.1.3/library/socket.html#example hat geschrieben:The last example shows how to write a very simple network sniffer with raw sockets on Windows.
@aluis: Unter Linux *musst* Du anstelle von `IPPROTO_IP` anscheinend ein konkreteres Protokoll angeben, wie zum Beispiel `IPPROTO_ICMP`, `IPPROTO_UDP`, oder `IPPROTO_TCP`. Und bekommst dann auch nur Pakete zu diesem Protokoll über die Socket.
Du kannst übrigens auch nach Dokumentation zu "raw sockets" unter C suchen, denn das `socket`-Modul ist nur ein ganz dünner Wrapper um die entsprechenden C-Funktionen.
Du kannst übrigens auch nach Dokumentation zu "raw sockets" unter C suchen, denn das `socket`-Modul ist nur ein ganz dünner Wrapper um die entsprechenden C-Funktionen.