I mean, I suppose PyShark continues listening. My code is (within a class):
def Capture(self, incoming):
capture = pyshark.LiveCapture()
capture.sniff(timeout=int(incoming))
print('TIMEOUT: ' + str(int(incoming)))
print(capture)
print("Len" + str(len(capture)))
pktList = []
count=0
for pkt in capture:
count=count+1
pktList.append([int(pkt.layers[1].version), pkt.layers[2].layer_name, pkt.length])
print(f"Saved packet #{count}")
print(pktList)
print("Job is done.")
Output shows that despite after the timeout of 2 seconds the capture consists of a single packet, the program somehow continues reading some data. Output:
TIMEOUT: 2
<LiveCapture (0 packets)>
Len 0
Saved packet #1
[[4, 'tcp', '108']]
Saved packet #2
[[4, 'tcp', '108'], [4, 'tcp', '112']]
Saved packet #3
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108']]
Saved packet #4
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108'], [4, 'tcp', '112']]
Saved packet #5
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '54']]
...............
How can I fix it?
I tried to use your code, but I couldn't get it to work correctly.
I know that there are some known issues with the way that capture.sniff(timeout=x) works, so I put together some other code that is using apply_on_packets with a timeout.
import pyshark
import asyncio
packet_list = []
def process_packets(packet):
global packet_list
try:
packet_version = packet.layers[1].version
layer_name = packet.layers[2].layer_name
packet_list.append(f'{packet_version}, {layer_name}, {packet.length}')
except AttributeError:
pass
def capture_packets(timeout):
capture = pyshark.LiveCapture(interface='en0')
try:
capture.apply_on_packets(process_packets, timeout=timeout)
except asyncio.TimeoutError:
pass
finally:
global packet_list
for item in packet_list:
print(item)
capture_packets(2)
I decided to rework your code. The code below works with capture.sniff(timeout=x).
import pyshark
packet_list = []
def capture_packets(timeout):
global packet_list
capture = pyshark.LiveCapture(interface='en0')
capture.sniff(timeout=timeout)
packets = [pkt for pkt in capture._packets]
capture.close()
try:
for packet in packets:
packet_version = packet.layers[1].version
layer_name = packet.layers[2].layer_name
packet_list.append(f'{packet_version}, {layer_name}, {packet.length}')
except AttributeError:
pass
finally:
return packet_list
packets = capture_packets(2)
print(packets)
['4, tcp, 54', '6, icmpv6, 86', '6, icmpv6, 78', '4, tcp, 66']
I will answer any questions you have about the code examples above.
----------------------------------------
My system information
----------------------------------------
Platform: macOS
Python: 3.8.0
Pyshark: 0.4.3
----------------------------------------