tcpdum stream mit python bearbeiten

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hi,
ich, :K noob, würde gerne einige Datenfelder aus einem Stream "live" ausgeben.

Es kommen immer Blöcke die "Gleich Anfangen" und mit Leerzeichen und einem Punkt aufhören.
Daraus würde ich gerne immer aus der Zeile 0x010 die Felder 2 und 3 aus der Zeile 0x0040 die Felder 3 und 7 haben und ausgeben.
Wie würdet ihr das aufsetzen? Zugrunde liegt der Befehl tcpdump -i ath0 -n -e -XX -s 0
Ich dachte da so an python programm aufrufen, dort dann über "os" den tcpdump machen und den dann über den standartoutput weiter filtern lassen.

Was meint Ihr dazu? Pythonversion ist egal und über Vorschläge und ein bischen Hilfe würde ich mich freuen.

  • 09:53:52.539023 2727616481us tsft short preamble 12.0 Mb/s 5890 MHz (0x0140) -76dB signal -96dB noise antenna 1 20dB signal DA:ff:ff:ff:ff:ff:ff SA:04:e5:48:00:40:66 BSSID:ff:ff:ff:ff:ff:ff LLC, dsap Null (0x00) Individual, ssap Null (0x00) Command, ctrl 0xaaaa: Information, send seq 85, rcv seq 85, Flags [Command], length 79
    0x0000: 0000 1a00 6f18 0000 e11f 94a2 0000 0000 ....o...........
    0x0010: 1218 0217 4001 b4a0 0114 8800 3000 ffff ....@.......0...
    0x0020: ffff ffff 04e5 4800 4066 ffff ffff ffff ......H.@f......
    0x0030: 6012 0000 aaaa 0300 0000 88dc 0255 0401 `............U..
    0x0040: 2010 010c 0f01 b280 0033 3031 8001 0281 .........301....
    0x0050: 2672 0000 00e1 0000 1ddb eac4 0565 f167 &r...........e.g
    0x0060: 0562 ffff ffff 0006 0000 7f00 0000 0000 .b..............
    0x0070: 0000 0100 32c1 a4a2 0480 0210 0082 7d70 ....2.........}p
    0x0080: d4 .
    09:53:54.671950 2729749394us tsft short preamble 12.0 Mb/s 5890 MHz (0x0140) -76dB signal -96dB noise antenna 1 20dB signal DA:ff:ff:ff:ff:ff:ff SA:04:e5:48:00:40:66 BSSID:ff:ff:ff:ff:ff:ff LLC, dsap Null (0x00) Individual, ssap Null (0x00) Command, ctrl 0xaaaa: Information, send seq 85, rcv seq 85, Flags [Command], length 79
    0x0000: 0000 1a00 6f18 0000 92ab b4a2 0000 0000 ....o...........
    0x0010: 1218 0217 4001 b4a0 0114 8800 3000 ffff ....@.......0...
    0x0020: ffff ffff 04e5 4800 4066 ffff ffff ffff ......H.@f......
    0x0030: 7012 0000 aaaa 0300 0000 88dc 0255 0401 p............U..
    0x0040: 2010 010c 0f01 b280 0033 3031 8001 0281 .........301....
    0x0050: 2674 0000 00e1 0000 1ddb eaab 0565 f136 &t...........e.6
    0x0060: 0567 ffff ffff 0004 0000 7f00 0000 0000 .g..............
    0x0070: 0000 0100 32c1 a4a2 0480 0210 00b6 a149 ....2..........I
    0x0080: 20 .
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich würde `subprocess.Popen verwenden, damit sollte das recht einfach gehen. Der Interessante Parameter für dich ist `stdout`. Mit `StringIO` kommst du relativ leicht an die Daten und kannst sie weiterverarbeiten.

Sebastian
Das Leben ist wie ein Tennisball.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hi,
also auf meinem betagten Debian 4.0 mit dem python 3.2.1 sieht es nun so aus:

Code: Alles auswählen

#!/bin/local/bin/python3.2
import subprocess
subprocess.Popen('tcpdump -i ath0 -n -e -XX -s 0', shell=True)
Das funktioniert wider erwarten gleich. Wie beende ich denn dann das Teil?
deets

Indem du dir mal die subprocess-Doku durchliest und nach terminate und/oder kill suchst.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Also hier erst mal das script, das dann doch besser "passt". Es wiederholt sich immer, unterscheidet sich aber in der Ausgabenlänge.
Ich hab da für das Filtern noch keine so richtige Idee, vielleicht nach dem Mittagessen. Das FETT gedruckte ist immer der Anfang des Frames.

Code: Alles auswählen

#! /usr/bin/python2.5

#filters output
import subprocess
i = 0
proc = subprocess.Popen(['tcpdump','-i', 'ath0', '-xx', '-s 0'],stdout=subprocess.PIPE)
while True:
  line = proc.stdout.readline()
  i = i + 1
  if line != '':
    print i, line.rstrip()
  else:
    print "nix"
    break


Der Output sieht so aus:
  • 11:56:27.381862 13955881208us tsft short preamble 1.0 Mb/s 2452 MHz (0x0480) -90dB signal -95dB noise antenna 1 5dB signal Beacon (carhs-wlan02bg) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] ESS CH: 9, PRIVACY
    0x0000: 0000 1a00 6f18 0000 f8d8 d53f 0300 0000
    0x0010: 1202 9409 8004 a6a1 0105 8000 0000 ffff
    0x0020: ffff ffff 0016 01ef 96f7 0016 01ef 96f7
    0x0030: d0ae 8121 3beb f404 0000 6400 1104 000e
    0x0040: 6361 7268 732d 776c 616e 3032 6267 0108
    0x0050: 8284 8b96 0c12 1824 0301 0905 0400 0100
    0x0060: 002a 0104 3204 3048 606c 3014 0100 000f
    0x0070: ac02 0100 000f ac02 0100 000f ac02 0000
    0x0080: dd09 0003 7f01 0100 20ff 7f36 3b71 b8
    11:56:27.629841 13956129146us tsft short preamble 24.0 Mb/s 2452 MHz (0x0480) -83dB signal -95dB noise antenna 1 12dB signal 00:16:01:ef:96:f7 (oui Unknown) Unknown SSAP 0x62 > 00:26:37:b7:28:92 (oui Unknown) Unknown DSAP 0xbc Information, send seq 15, rcv seq 69, Flags [Final], length 4
    0x0000: 0000 1a00 6f18 0000 7aa1 d93f 0300 0000
    0x0010: 1230 9409 8004 ada1 010c 4819 2c00 0016
    0x0020: 01ef 96f7 0026 37b7 2892 0016 01ef 96f7
    0x0030: 10b8 bc63 1e8b
    11:56:27.629863 13956129186us tsft short preamble 24.0 Mb/s 2452 MHz (0x0480) -88dB signal -95dB noise antenna 1 7dB signal Acknowledgment RA:00:26:37:b7:28:92 (oui Unknown)
    0x0000: 0000 1a00 6f18 0000 a2a1 d93f 0300 0000
    0x0010: 1230 9409 8004 a8a1 0107 d400 0000 0026
    0x0020: 37b7 2892 aee9 4015
deets

EIn paar Anmerkungen:

- "-s 0" ist denke ich falsch, es muss sein "-s", "0" - sonst ist '-s 0' *ein* Argument, also wie ein Schalter.
- statt dem ganzen i = 0 & while=True kannst du einfach

Code: Alles auswählen

for i, line in enumerate(proc.stdout):
    ...
    print i + 1, line.rstrip()
machen.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hi,
also das mit '-s 0' stimmt natürlich. (Hatte aber auf das Ergebnis der Ausgabe keine Auswirkung)

Script hab ich geändert mit der For schleife, bekomme jetzt aber gar keine Ausgabe mehr.

Code: Alles auswählen

#! /usr/bin/python2.5
#filters output
import subprocess
i = 0
proc = subprocess.Popen(['tcpdump','-i', 'ath0', '-xx', '-s', '0'],stdout=subprocess.PIPE)
for i, line in enumerate(proc.stdout):
  line = proc.stdout.readline()
  i = i + 1
  print i, line.rstrip()
done
deets

du sollst ja auch nicht nochmal readline machen.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Ach so,
also jetzt ist es aktuell so:
Hat aber einen entscheidenden Nachteil, es macht wusch und es kommt ein großer Schwung an Zeilen auf das Terminal. Dann dauert es eine ganze Weile, es macht Wusch und dann ist wieder ein Schwung da. Gibt es da auch noch einen Schalter dafür? Ansich finde ich die for-Schleife auch schöner.

Code: Alles auswählen

#! /usr/bin/python2.5

#filters output
import subprocess
i = 0
proc = subprocess.Popen(['tcpdump','-i', 'ath0', '-xx', '-s', '0'],stdout=subprocess.PIPE)
for i, line in enumerate(proc.stdout):
  i = i + 1
  print i, line.rstrip()
done
deets

War das vorher wirklich anders? Das wundert mich etwas, da sollte eigentlich nix fundamental anderes sein. Und einen Schalter gibt's nicht.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Hm,
jetzt kommt so gar nix mehr.
Ich mach mal ein reboot.
Es scheint er bekommt alles aber gibt nichts raus ...
--> 3 Packets captures ....

Code: Alles auswählen

lisa:~/scripts# ./test.py 
tcpdump: WARNING: ath0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ath0, link-type IEEE802_11_RADIO (802.11 plus BSD radio information header), capture size 65535 bytes
3 packets captured
3 packets received by filter
0 packets dropped by kernel
Traceback (most recent call last):
  File "./test.py", line 5, in <module>
    for i, line in enumerate(proc.stdout):
KeyboardInterrupt
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Alles gut,
nach reboot alles wieder funktionabel.
Warum, keinen Schimmer.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Wie kann ich denn nun weitermachen?
Ich bräuchte nun die Möglichkeit, von Anfang der Uhrzeit bis neuer Anfang der Uhrzeit - Minus ein Feld in eine Liste zu schreiben, um das ganze dann über einen Index mir auszugeben.

Hat dazu jemand eine Idee?
BlackJack

@krischeu: Du könntest Dir mit dem `re`-Modul etwas basteln um diese erste Zeile von jedem Block zu erkennen, und dann genau das machen was Du beschreibst: Alle Zeilen von so einer Trennzeile bis zur nächsten in eine Liste stecken, und diese Listen dann wiederum in eine Liste stecken.

Ich würde wahrscheinlich etwas mit `itertools.groupby()` basteln, aber das ist den meisten Anfängern etwas zu kryptisch.

Interessant wäre auch was Du dann mit den Daten weiter anstellen willst, also bis zu welchem Grad es vielleicht auch Sinn macht das in Datenstrukturen zu parsen.
krischeu
User
Beiträge: 40
Registriert: Freitag 9. Januar 2009, 17:04

Es geht darum, daß man den HexDump und die erste Zeile in schöner lesbarer Weise auf den Bildschirm bekommt.
  • 259 16:55:01.072393 14814534748957879673us tsft short preamble 1.0 Mb/s 2452 MHz (0x0480) -82dB signal -96dB noise antenna 1 14dB signal Beacon (carhs-wlan02bg) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] ESS CH: 9, PRIVACY
    260 0x0000: 0000 1a00 6f18 0000 79ad 5008 ddcc 97cd
    261 0x0010: 1202 9409 8004 aea0 010e 8000 0000 ffff
    262 0x0020: ffff ffff 0016 01ef 96f7 0016 01ef 96f7
    263 0x0030: 3002 81c1 f716 f904 0000 6400 1104 000e
    264 0x0040: 6361 7268 732d 776c 616e 3032 6267 0108
    265 0x0050: 8284 8b96 0c12 1824 0301 0905 0400 0101
    266 0x0060: 002a 0104 3204 3048 606c 3014 0100 000f
    267 0x0070: ac02 0100 000f ac02 0100 000f ac02 0000
    268 0x0080: dd09 0003 7f01 0100 20ff 7fc8 c08a 87
Hieraus sieht man so gar nichts. Aber wenn man nun den Wert aus der Zeile 0x0000 aus der Spalte 3 nimmt (6f16) <--> entspricht den 2 Werten 6f und 16 und gibt die dann aus mit Länge: und Breite: dann ist das doch schon SUUUUUUPER. Insgesamt sind das so ca. 10 Werte die ich auslesen würde. Teilweise dann auch über Zeilen und Felder. Aber das würde ich dann schon hinbekommen, denke ich.
Antworten