Я хочу остановить захват пакетов во время непрерывного обнюхивания, как только будет выполнено условие

Проблема

Я написал скрипт, который обнюхивает пакеты с хоста, однако я обнюхиваю пакеты в непрерывном режиме и хотел бы прекратить обнюхивание по тайм-ауту. Я написал следующий код, чтобы остановить перехват пакетов, но, похоже, он не останавливается, когда время явно превышает тайм-аут. Что я могу здесь делать не так?

import time
import pyshark

prog_start = time.time()
capture = pyshark.LiveCapture(interface='en0')
capture.sniff(timeout=10)
start_time = capture[0].frame_info.time_epoch
end_time = capture[-1].frame_info.time_epoch
print("Capture lasted:", float(end_time) - float(start_time))
pkt_num = 0
for pkt in capture:
    pkt_num += 1
    print("Time", time.time() - prog_start, "Pkt#", pkt_num)

Затем мы получаем этот вывод с тысячами дополнительных пакетов в секунду после того, как перехват должен был прекратиться:

Capture lasted: 9.148329019546509
Time 10.346031188964844 Pkt# 1
Time 10.348641157150269 Pkt# 2
Time 10.351708889007568 Pkt# 3
Time 10.353564977645874 Pkt# 4
Time 10.35555100440979 Pkt# 5
...

Вопрос

Почему PyShark продолжает перехватывать пакеты после тайм-аута?


person Sajan Maharjan    schedule 09.10.2019    source источник
comment
Можете ли вы сократить приведенный здесь код до минимально воспроизводимого примера?   -  person Ross Jacobs    schedule 10.10.2019
comment
capture = pyshark.LiveCapture(interface='\\Device\\NPF_{9342EE7E-9981-4554-87AE-06666A717864}', display_filter='bitcoin') capture.sniff(timeout=125) start_time = capture[0].frame_info.time_epoch end_time = capture[-1].frame_info.time_epoch for pkt in capture: print(str(pkt)) Когда я использую тайм-аут, как вы упомянули, он постоянно зацикливается даже после тайм-аута.   -  person Sajan Maharjan    schedule 10.10.2019
comment
Обновленный вопрос и ответ - похоже на ошибку   -  person Ross Jacobs    schedule 10.10.2019


Ответы (2)


Проблемы с PyShark

Похоже, вы столкнулись с известной проблемой с PyShark, которая еще не фиксируется в годах. В теме автор написал

Вы можете создать подкласс LiveCapture и переопределить функцию get_parameters(), добавив свои собственные параметры.

Вы можете изменить параметры, отправляемые в tshark, но на данный момент, почему бы просто не использовать команду tshark напрямую?

Вместо этого используйте Tshark

PyShark — это просто оболочка для tshark в вашей системе. Если вы хотите использовать подпроцесс с Python, эквивалентной командой tshark будет tshark -a duration:5. Другое преимущество прямого использования tshark заключается в том, что подпроцесс дает вам pid, который вы можете убить при произвольном условии.

Дополнительные сведения см. на справочной странице. .

person Ross Jacobs    schedule 09.10.2019
comment
Спасибо, но я все еще не могу понять это правильно. Я имею в виду, если я использую параметр тайм-аута, чтобы установить тайм-аут и захватить столько пакетов, сколько захочу, но когда мне нужно снова перебрать захваченные пакеты, используя цикл for (как в моем коде выше), он переходит в асинхронный режим, а затем захватывает новые пакеты снова. Так что я все еще застрял. Любые альтернативы, которые вы могли бы предложить? - person Sajan Maharjan; 10.10.2019

У меня была такая же проблема, мне удалось найти решение для нее. Это не идеально, но он работает, сообщая циклу захвата, чтобы он остановился на следующем пакете, и отправляет пустой пакет, который он увидит, чтобы завершить его. Я сделал это udp-пакетом на высоком порту для своего случая, потому что я использую фильтр, который отфильтровывает большую часть трафика, поэтому это решение сработало для меня.

class PacketCapture(threading.Thread):
    capture = 1

    def __init__(self, interface_name):
        threading.Thread.__init__(self)
        self.interface_name = interface_name

    def stop(self):
        self.capture = 0

    def run(self):
        capture = pyshark.LiveCapture(interface=self.interface_name)
        try:
            for packet in capture.sniff_continuously():
                if not self.capture:
                    capture.close()
        except pyshark.capture.capture.TSharkCrashException:
            self.exited = 1
            print("Capture has crashed")



#start capture
pcap = PacketCapture(interface_name)
pcap.start()

#stop capture
pcap.stop()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
msg = bytes("", "UTF-8")
sock.sendto(msg, ("external IP", 12345))
sock.close

Я относительно новичок в python, но я думаю, что это должно быть несколько приемлемым решением, учитывая сценарий

person Desultory    schedule 27.05.2020