0

I want to run 2 blocking loops in the same program. In my program, I'm using nfqueue to intercept packets. When the queue is created it starts waiting for packets and blocks the program. When a packet arrives it will call the cb() function and then start listening again for a new packet.

Here is my program:

import nfqueue, socket
from scapy.all import *
import os

os.system('iptables -t mangle -A PREROUTING -j NFQUEUE --queue-num 1')
os.system('iptables -t mangle -A POSTROUTING -j NFQUEUE --queue-num 2')


count = 0

def cb(payload):
    global count
    count +=1
    data = payload.get_data()
    p = IP(data) 

    print str(count) + ": TOS     = " + str(p.tos)
    payload.set_verdict(nfqueue.NF_ACCEPT)


def run_queue(queue_num):
    print "Preparing the queue"
    q = nfqueue.queue()
    q.open()
    q.unbind(socket.AF_INET)
    q.bind(socket.AF_INET)
    q.set_callback(cb)
    q.create_queue(queue_num)

    try:
        print "Running the queue"
        q.try_run()

    except KeyboardInterrupt, e:
        print "interruption"
        q.unbind(socket.AF_INET)
        q.close()


run_queue(1)
run_queue(2)

How can I run 2 or more of these blocking loops in the same program?

Any help would be very appreciated. Thank you!

HaTiMuX
  • 621
  • 2
  • 10
  • 22
  • hint: you need to use threads, and run each loop on a separate one – loopbackbee Jul 10 '14 at 15:10
  • But when the first thread is created, the blocking loop will start and then the second thread cannot be created – HaTiMuX Jul 10 '14 at 15:11
  • @HaTiMuX The blocking loop should run in its own thread, so it won't block execution of the main thread. – dano Jul 10 '14 at 15:12
  • @dano Can you please give me a basic example of using threads? I tried using threads but it seems that I'm not doing it the right way – HaTiMuX Jul 10 '14 at 15:20

1 Answers1

1

You can run each loop in its own thread, like this:

import nfqueue, socket
from threading import Thread
from scapy.all import *
import os

os.system('iptables -t mangle -A PREROUTING -j NFQUEUE --queue-num 1')
os.system('iptables -t mangle -A POSTROUTING -j NFQUEUE --queue-num 2')


count = 0

def cb(payload):
    global count
    count +=1
    data = payload.get_data()
    p = IP(data) 

    print str(count) + ": TOS     = " + str(p.tos)
    payload.set_verdict(nfqueue.NF_ACCEPT)


def run_queue(queue_num):
    print "Preparing the queue"
    q = nfqueue.queue()
    q.open()
    q.unbind(socket.AF_INET)
    q.bind(socket.AF_INET)
    q.set_callback(cb)
    q.create_queue(queue_num)

    try:
        print "Running the queue"
        q.try_run()

    except KeyboardInterrupt, e:
        print "interruption"
        q.unbind(socket.AF_INET)
        q.close()

if __name__ == "__main__":
    t1 = Thread(target=run_queue, args=(1,))
    t1.start()
    t2 = Thread(target=run_queue, args=(2,))
    t2.start()
    t1.join()
    t2.join()
dano
  • 91,354
  • 19
  • 222
  • 219
  • I get this error: q = nfqueue.queue() AttributeError: 'module' object has no attribute 'queue' – HaTiMuX Jul 10 '14 at 15:43
  • @HaTiMuX Did you name your file `nfqueue.py`? If so, rename it to something else. – dano Jul 10 '14 at 15:46
  • Thank you, the problem was indeed in the file name. Now it's working except that the second thread doesn't start till the first running queue gets 2 packets or 3. Is there any way to avoid this and start the 2 threads at the same time?? – HaTiMuX Jul 11 '14 at 08:46
  • @HaTiMuX I'm really not sure why that would happen, unless the GIL is to blame. You could try using a `multiprocessing.Process` instead of a `threading.Thread` and see if the issue goes away. You could have to tweak the way you use the `count` variable though, to make it safe to be shared between processes. I would just comment `count` out while you test to see if it fixes the issue. – dano Jul 11 '14 at 14:35