From a26d86c3ec97a495663f229166e8484ddb9ee70e Mon Sep 17 00:00:00 2001
From: Phil <phil@secdev.org>
Date: Fri, 31 Aug 2007 13:57:39 +0200
Subject: [PATCH] Fixes incomplete reception buffer flushing (ticket #55)

There is a race condition between the time a socket is created and the
time it is initialized (BPF filter pushed, bound to an interface). Indeed,
packets captured in between would still be delivered when reading the socket.
Setting reception buffers to 0 was part of the solution and greatly reduced
the race condition timeframe, but still, packet already captured where actually
not sweeped out. So this also need to be done. Thanks to AGR and Y.E. Jutard.
---
 scapy.py | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/scapy.py b/scapy.py
index 1b10e04a..4aa086a9 100755
--- a/scapy.py
+++ b/scapy.py
@@ -9217,6 +9217,15 @@ L3Types = { ETH_P_IP : IP,
             }
 
 
+def flush_fd(fd):
+    if type(fd) is not int:
+        fd = fd.fileno()
+    while 1:
+        r,w,e = select([fd],[],[],0)
+        if r:
+            os.read(fd,MTU)
+        else:
+            break
 
 class SuperSocket:
     closed=0
@@ -9265,6 +9274,7 @@ class L3PacketSocket(SuperSocket):
         self.type = type
         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
         if not nofilter:
             if conf.except_filter:
                 if filter:
@@ -9357,6 +9367,7 @@ class L2Socket(SuperSocket):
             iface = conf.iface
         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
         if not nofilter: 
             if conf.except_filter:
                 if filter:
@@ -9399,6 +9410,7 @@ class L2ListenSocket(SuperSocket):
         self.outs = None
         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+        flush_fd(self.ins)
         if iface is not None:
             self.ins.bind((iface, type))
         if not nofilter:
-- 
GitLab