diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
index e31c83258ea1ca65e07bae0efe6c73721c192508..e242e79336b99c83f38339c49532c37ecb0124b2 100644
--- a/scapy/sendrecv.py
+++ b/scapy/sendrecv.py
@@ -70,7 +70,6 @@ def _sndrcv_snd(pks, timeout, inter, verbose, tobesent, stopevent):
         stopevent.wait(timeout)
         stopevent.set()
 
-
 class _BreakException(Exception):
     """A dummy exception used in _get_pkt() to get out of the infinite
 loop
@@ -78,33 +77,15 @@ loop
     """
     pass
 
-
-def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
-           retry=0, multi=False):
-    if not isinstance(pkt, Gen):
-        pkt = SetGen(pkt)
-    if verbose is None:
-        verbose = conf.verb
-    debug.recv = plist.PacketList([],"Unanswered")
-    debug.sent = plist.PacketList([],"Sent")
-    debug.match = plist.SndRcvList([])
-    nbrecv=0
+def _sndrcv_rcv(pks, tobesent, stopevent, nbrecv, notans, verbose, chainCC,
+                multi):
+    """Function used to recieve packets and check their hashret"""
     ans = []
-    # do it here to fix random fields, so that parent and child have the same
-    tobesent = [p for p in pkt]
-    notans = len(tobesent)
-
-    hsent={}
+    hsent = {}
     for i in tobesent:
         h = i.hashret()
         hsent.setdefault(i.hashret(), []).append(i)
 
-    if retry < 0:
-        retry = -retry
-        autostop = retry
-    else:
-        autostop = 0
-
     if WINDOWS:
         def _get_pkt():
             return pks.recv(MTU)
@@ -134,6 +115,69 @@ def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
             if stopevent.is_set():
                 raise _BreakException()
 
+    try:
+        try:
+            while True:
+                r = _get_pkt()
+                if r is None:
+                    if stopevent.is_set():
+                        break
+                    continue
+                ok = False
+                h = r.hashret()
+                if h in hsent:
+                    hlst = hsent[h]
+                    for i, sentpkt in enumerate(hlst):
+                        if r.answers(sentpkt):
+                            ans.append((sentpkt, r))
+                            if verbose > 1:
+                                os.write(1, b"*")
+                            ok = True
+                            if not multi:
+                                del hlst[i]
+                                notans -= 1
+                            else:
+                                if not hasattr(sentpkt, '_answered'):
+                                    notans -= 1
+                                sentpkt._answered = 1
+                            break
+                if notans == 0 and not multi:
+                    break
+                if not ok:
+                    if verbose > 1:
+                        os.write(1, b".")
+                    nbrecv += 1
+                    if conf.debug_match:
+                        debug.recv.append(r)
+        except KeyboardInterrupt:
+            if chainCC:
+                raise
+        except _BreakException:
+            pass
+    finally:
+        stopevent.set()
+    return (hsent, ans, nbrecv, notans)
+
+def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
+           retry=0, multi=False):
+    if not isinstance(pkt, Gen):
+        pkt = SetGen(pkt)
+    if verbose is None:
+        verbose = conf.verb
+    debug.recv = plist.PacketList([],"Unanswered")
+    debug.sent = plist.PacketList([],"Sent")
+    debug.match = plist.SndRcvList([])
+    nbrecv=0
+    # do it here to fix random fields, so that parent and child have the same
+    tobesent = [p for p in pkt]
+    notans = len(tobesent)
+
+    if retry < 0:
+        retry = -retry
+        autostop = retry
+    else:
+        autostop = 0
+
     while retry >= 0:
         if timeout < 0:
             timeout = None
@@ -145,49 +189,8 @@ def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
         )
         thread.start()
 
-        try:
-            try:
-                while True:
-                    r = _get_pkt()
-                    if r is None:
-                        if stopevent.is_set():
-                            break
-                        continue
-                    ok = False
-                    h = r.hashret()
-                    if h in hsent:
-                        hlst = hsent[h]
-                        for i, sentpkt in enumerate(hlst):
-                            if r.answers(sentpkt):
-                                ans.append((sentpkt, r))
-                                if verbose > 1:
-                                    os.write(1, b"*")
-                                ok = True
-                                if not multi:
-                                    del hlst[i]
-                                    notans -= 1
-                                else:
-                                    if not hasattr(sentpkt, '_answered'):
-                                        notans -= 1
-                                    sentpkt._answered = 1
-                                break
-                    if notans == 0 and not multi:
-                        break
-                    if not ok:
-                        if verbose > 1:
-                            os.write(1, b".")
-                        nbrecv += 1
-                        if conf.debug_match:
-                            debug.recv.append(r)
-            except KeyboardInterrupt:
-                if chainCC:
-                    raise
-            except _BreakException:
-                pass
-        finally:
-            stopevent.set()
-            thread.join()
-            pks.close()
+        hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, nbrecv, notans, verbose, chainCC, multi)
+        thread.join()
 
         remain = list(itertools.chain(*six.itervalues(hsent)))
         if multi:
@@ -403,6 +406,8 @@ iface:    work only on the given interface"""
     else:
         return None
 
+# SEND/RECV LOOP METHODS
+
 def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=None, count=None, verbose=None, store=1, *args, **kargs):
     n = 0
     r = 0
@@ -467,71 +472,55 @@ def srploop(pkts, *args, **kargs):
 srloop(pkts, [prn], [inter], [count], ...) --> None"""
     return __sr_loop(srp, pkts, *args, **kargs)
 
+# SEND/RECV FLOOD METHODS
 
-def sndrcvflood(pks, pkt, prn=lambda s_r:s_r[1].summary(), chainCC=0, store=1, unique=0):
+def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, prn=lambda x: x):
+    if not verbose:
+        verbose = conf.verb
     if not isinstance(pkt, Gen):
         pkt = SetGen(pkt)
     tobesent = [p for p in pkt]
     received = plist.SndRcvList()
     seen = {}
 
-    hsent={}
-    for i in tobesent:
-        h = i.hashret()
-        if h in hsent:
-            hsent[h].append(i)
-        else:
-            hsent[h] = [i]
+    stopevent = threading.Event()
+    count_packets = six.moves.queue.Queue()
 
-    def send_in_loop(tobesent):
+    def send_in_loop(tobesent, stopevent, count_packets=count_packets):
+        """Infinite generator that produces the same packet until stopevent is triggered."""
         while True:
             for p in tobesent:
+                if stopevent.is_set():
+                    raise StopIteration()
+                count_packets.put(0)
                 yield p
 
-    packets_to_send = send_in_loop(tobesent)
+    infinite_gen = send_in_loop(tobesent, stopevent)
 
-    ssock = rsock = pks.fileno()
+    # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after recieving)
+    thread = threading.Thread(
+        target=_sndrcv_snd,
+        args=(pks, None, inter, False, infinite_gen, stopevent),
+    )
+    thread.start()
 
-    try:
-        while True:
-            if conf.use_bpf:
-                from scapy.arch.bpf.supersocket import bpf_select
-                readyr = bpf_select([rsock])
-                _, readys, _ = select([], [ssock], [])
-            else:
-                readyr, readys, _ = select([rsock], [ssock], [])
+    hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, 0, len(tobesent), verbose, chainCC, False)
+    thread.join()
+    remain = list(itertools.chain(*six.itervalues(hsent)))
+    # Apply prn
+    ans = [(x, prn(y)) for (x, y) in ans]
 
-            if ssock in readys:
-                pks.send(packets_to_send.next())
-                
-            if rsock in readyr:
-                p = pks.recv(MTU)
-                if p is None:
-                    continue
-                h = p.hashret()
-                if h in hsent:
-                    hlst = hsent[h]
-                    for i in hlst:
-                        if p.answers(i):
-                            res = prn((i,p))
-                            if unique:
-                                if res in seen:
-                                    continue
-                                seen[res] = None
-                            if res is not None:
-                                print(res)
-                            if store:
-                                received.append((i,p))
-    except KeyboardInterrupt:
-        if chainCC:
-            raise
-    return received
+    if verbose:
+        print("\nReceived %i packets, got %i answers, remaining %i packets. Sent a total of %i packets." % (nbrecv+len(ans), len(ans), notans, count_packets.qsize()))
+    count_packets.empty()
+    del count_packets
+
+    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
 
 @conf.commands.register
 def srflood(x, promisc=None, filter=None, iface=None, nofilter=None, *args,**kargs):
     """Flood and receive packets at layer 3
-prn:      function applied to packets received. Ret val is printed if not None
-store:    if 1 (default), store answers and return them
+prn:      function applied to packets received
 unique:   only consider packets whose print 
 nofilter: put 1 to avoid use of BPF filters
 filter:   provide a BPF filter
@@ -541,11 +530,26 @@ iface:    listen answers only on the given interface"""
     s.close()
     return r
 
+@conf.commands.register
+def sr1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
+    """Flood and receive packets at layer 3 and return only the first answer
+prn:      function applied to packets received
+verbose:  set verbosity level
+nofilter: put 1 to avoid use of BPF filters
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    s=conf.L3socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)
+    ans, _ = sndrcvflood(s, x, *args, **kargs)
+    s.close()
+    if len(ans) > 0:
+        return ans[0][1]
+    else:
+        return None
+
 @conf.commands.register
 def srpflood(x, promisc=None, filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
     """Flood and receive packets at layer 2
-prn:      function applied to packets received. Ret val is printed if not None
-store:    if 1 (default), store answers and return them
+prn:      function applied to packets received
 unique:   only consider packets whose print 
 nofilter: put 1 to avoid use of BPF filters
 filter:   provide a BPF filter
@@ -557,8 +561,23 @@ iface:    listen answers only on the given interface"""
     s.close()
     return r
 
-           
+@conf.commands.register
+def srp1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args,**kargs):
+    """Flood and receive packets at layer 2 and return only the first answer
+prn:      function applied to packets received
+verbose:  set verbosity level
+nofilter: put 1 to avoid use of BPF filters
+filter:   provide a BPF filter
+iface:    listen answers only on the given interface"""
+    s=conf.L2socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)
+    ans, _ = sndrcvflood(s, x, *args, **kargs)
+    s.close()
+    if len(ans) > 0:
+        return ans[0][1]
+    else:
+        return None
 
+# SNIFF METHODS
 
 @conf.commands.register
 def sniff(count=0, store=True, offline=None, prn=None, lfilter=None,
diff --git a/scapy/supersocket.py b/scapy/supersocket.py
index cd9eb9331479421af8b72673c634337821102dfb..cfc27c559cbc26a823d01627532a5be60494d6a4 100644
--- a/scapy/supersocket.py
+++ b/scapy/supersocket.py
@@ -192,7 +192,15 @@ class L2ListenTcpdump(SuperSocket):
         self.outs = None
         args = ['-w', '-', '-s', '65535']
         if iface is not None:
-            args.extend(['-i', iface])
+            if WINDOWS:
+                try:
+                    args.extend(['-i', iface.pcap_name])
+                except AttributeError:
+                    args.extend(['-i', iface])
+            else:
+                args.extend(['-i', iface])
+        elif WINDOWS:
+            args.extend(['-i', conf.iface.pcap_name])
         if not promisc:
             args.append('-p')
         if not nofilter:
@@ -203,9 +211,13 @@ class L2ListenTcpdump(SuperSocket):
                     filter = "not (%s)" % conf.except_filter
         if filter is not None:
             args.append(filter)
-        self.ins = PcapReader(tcpdump(None, prog=prog, args=args, getfd=True))
+        self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True)
+        self.ins = PcapReader(self.tcpdump_proc.stdout)
     def recv(self, x=MTU):
         return self.ins.recv(x)
+    def close(self):
+        SuperSocket.close(self)
+        self.tcpdump_proc.kill()
 
 
 class TunTapInterface(SuperSocket):
diff --git a/scapy/utils.py b/scapy/utils.py
index 471de79db45a329bf1444c6bcdd6a27dda515dd3..28fa92c3c38a49ec725737b1d5a1b4c4cbba1dc9 100644
--- a/scapy/utils.py
+++ b/scapy/utils.py
@@ -1200,7 +1200,7 @@ def wireshark(pktlist):
 
 @conf.commands.register
 def tcpdump(pktlist, dump=False, getfd=False, args=None,
-            prog=None):
+            prog=None, getproc=False):
     """Run tcpdump or tshark on a list of packets
 
 pktlist: a Packet instance, a PacketList instance or a list of Packet
@@ -1211,6 +1211,7 @@ pktlist: a Packet instance, a PacketList instance or a list of Packet
 dump:    when set to True, returns a string instead of displaying it.
 getfd:   when set to True, returns a file-like object to read data
          from tcpdump or tshark from.
+getproc: when set to True, the subprocess.Popen object is returned
 args:    arguments (as a list) to pass to tshark (example for tshark:
          args=["-T", "json"]). Defaults to ["-n"].
 prog:    program to use (defaults to tcpdump, will work with tshark)
@@ -1249,6 +1250,7 @@ To get a JSON representation of a tshark-parsed PacketList(), one can:
 u'64'
 
     """
+    getfd = getfd or getproc
     if prog is None:
         prog = [conf.prog.tcpdump]
     elif isinstance(prog, six.string_types):
@@ -1300,6 +1302,8 @@ u'64'
             proc.stdin.close()
     if dump:
         return b"".join(iter(lambda: proc.stdout.read(1048576), b""))
+    if getproc:
+        return proc
     if getfd:
         return proc.stdout
     proc.wait()
diff --git a/test/regression.uts b/test/regression.uts
index 825e45f0f2d8c4e9ba339c45a192eb2a4ebfc0f6..1e33cb39138d0a3e03370b4fd0d370926b530608 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -730,6 +730,24 @@ assert x[IP].ottl() in [32, 64, 128, 255]
 assert 0 <= x[IP].hops() <= 126
 x is not None and ICMP in x and x[ICMP].type == 0
 
+= Sending and receiving an ICMP with flooding methods
+~ netaccess IP ICMP
+# flooding methods do not support timeout. Packing the test for security
+def _test_flood():
+    old_debug_dissector = conf.debug_dissector
+    conf.debug_dissector = False
+    x = sr1flood(IP(dst="www.google.com")/ICMP())
+    conf.debug_dissector = old_debug_dissector
+    x
+    assert x[IP].ottl() in [32, 64, 128, 255]
+    assert 0 <= x[IP].hops() <= 126
+    x is not None and ICMP in x and x[ICMP].type == 0
+
+t = Thread(target=_test_flood)
+t.start()
+t.join(3)
+assert not t.is_alive()
+
 = Sending and receiving an ICMPv6EchoRequest
 ~ netaccess ipv6
 old_debug_dissector = conf.debug_dissector
@@ -904,7 +922,7 @@ try:
 except:
     from queue import Queue as queue
 
-def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None):
+def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None, opened_socket=None):
     assert pid != -1
     if pid == 0:
         time.sleep(1)
@@ -919,7 +937,7 @@ def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None):
         old_debug_dissector = conf.debug_dissector
         conf.debug_dissector = False
         pkts = sniff(
-            timeout=timeout, filter=flt,
+            timeout=timeout, filter=flt, opened_socket=opened_socket,
             stop_filter=lambda p: pkt.__class__ in p and raw(p[pkt.__class__]) == spkt
         )
         conf.debug_dissector = old_debug_dissector
@@ -929,18 +947,18 @@ def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None):
             t_other.join()
     assert raw(pkt) in (raw(p[pkt.__class__]) for p in pkts if pkt.__class__ in p)
 
-def send_and_sniff(pkt, timeout=2, flt=None):
+def send_and_sniff(pkt, timeout=2, flt=None, opened_socket=None):
     """Send a packet, sniff, and check the packet has been seen"""
     if hasattr(os, "fork"):
         _send_or_sniff(pkt, timeout, flt, os.fork(), True)
     else:
         from threading import Thread
-        def run_function(pkt, timeout, flt, pid, thread, results):
-            _send_or_sniff(pkt, timeout, flt, pid, False, t_other=thread)
+        def run_function(pkt, timeout, flt, pid, thread, results, opened_socket):
+            _send_or_sniff(pkt, timeout, flt, pid, False, t_other=thread, opened_socket=opened_socket)
             results.put(True)
         results = queue()
-        t_parent = Thread(target=run_function, args=(pkt, timeout, flt, 0, None, results))
-        t_child = Thread(target=run_function, args=(pkt, timeout, flt, 1, t_parent, results))
+        t_parent = Thread(target=run_function, args=(pkt, timeout, flt, 0, None, results, None))
+        t_child = Thread(target=run_function, args=(pkt, timeout, flt, 1, t_parent, results, opened_socket))
         t_parent.start()
         t_child.start()
         t_parent.join()
@@ -953,6 +971,11 @@ send_and_sniff(IP(dst="secdev.org")/ICMP())
 send_and_sniff(IP(dst="secdev.org")/ICMP(), flt="icmp")
 send_and_sniff(Ether()/IP(dst="secdev.org")/ICMP())
 
+a = L2ListenTcpdump()
+icmp_r = IP(b'E\x00\x00\x1c\x00\x01\x00\x00@\x01p\xc0\x7f\x00\x00\x01\xd9\x19\xb2\x05\x08\x00\xf7\xff\x00\x00\x00\x00')
+send_and_sniff(icmp_r, timeout=10, opened_socket=a)
+a.close()
+
 ############
 ############
 + ManuFDB tests