Basically, I have a script that sniffs packets in one thread, and appends them to a list. A second thread also runs, and if the list is not empty, then it will perform calculations with the data. However, the sniffing thread only seems to work properly after hitting Ctrl + C. Before sending the keyboard interrupt, console output that I've produced for debugging is very slow and it seems to be missing packets. Afterwards hitting Ctrl + C it runs much faster and works as expected. Any ideas why this might be occurring? My code would look something similar to what is below.
Packet sniffer:
import socket, sys
from struct import *
def eth_addr(a):
#create a AF_PACKET type raw socket (thats basically packet level)
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
try:
s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
def packet_sniff():
# receive a packet
while True:
packet = s.recvfrom(65565)
#packet string from tuple
packet = packet[0]
#parse ethernet header
eth_length = 14
eth_header = packet[:eth_length]
eth = unpack('!6s6sH' , eth_header)
eth_protocol = socket.ntohs(eth[2])
print 'Destination MAC : ' + eth_addr(packet[0:6]) + ' Source MAC : ' + eth_addr(packet[6:12]) + ' Protocol : ' + str(eth_protocol)
#TCP protocol
if protocol == 6 :
t = iph_length + eth_length
tcp_header = packet[t:t+20]
#now unpack them
tcph = unpack('!HHLLBBHHH' , tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Sequence Number : ' + str(sequence) + ' Acknowledgement : ' + str(acknowledgement) + ' TCP header length : ' + str(tcph_length)
h_size = eth_length + iph_length + tcph_length * 4
data_size = len(packet) - h_size
#get data from the packet
data = packet[h_size:]
return data
Main would look something roughly like this:
def run_program():
processThread1 = threading.Thread(target = self.sniff_data, args = [])
processThread2 = threading.Thread(target = self.process_data, args = [])
processThread1.start()
processThread2.start()
def sniff_data():
global my_list
while True:
data = packet_sniff()
my_list.append(data)
def process_data():
global my_list
while True:
if len(my_list) != 0:
# Do computation
my_list = []
run_program()