diff --git a/doc/scapy/usage.rst b/doc/scapy/usage.rst
index c85dd16edc7a16767a75099b7363c5f7934eaa11..919fff1983e17880cc0c2bee9327ed795e5566d9 100644
--- a/doc/scapy/usage.rst
+++ b/doc/scapy/usage.rst
@@ -79,7 +79,7 @@ The ``/`` operator has been used as a composition operator between two layers. W
     <IP frag=0 proto=55 |<TCP |>>
 
 
-.. image:: graphics/fieldsmanagement.*
+.. image:: graphics/fieldsmanagement.png
    :scale: 90
 
 Each packet can be build or dissected (note: in Python ``_`` (underscore) is the latest result)::
@@ -520,7 +520,7 @@ Sniffing
 .. index::
    single: sniff()
 
-We can easily capture some packets or even clone tcpdump or tethereal. If no interface is given, sniffing will happen on every interfaces::
+We can easily capture some packets or even clone tcpdump or tshark. Either one interface or a list of interfaces to sniff on can be provided. If no interface is given, sniffing will happen on every interface::
 
     >>>  sniff(filter="icmp and host 66.35.250.151", count=2)
     <Sniffed: UDP:0 TCP:0 ICMP:2 Other:0>
@@ -607,6 +607,11 @@ We can easily capture some packets or even clone tcpdump or tethereal. If no int
              load      = 'B\xf7i\xa9\x00\x04\x149\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567'
     ---[ Padding ]---
                 load      = '\n_\x00\x0b'
+    >>> sniff(iface=["eth1","eth2"], prn=lambda x: x.sniffed_on+": "+x.summary())
+    eth3: Ether / IP / ICMP 192.168.5.21 > 66.35.250.151 echo-request 0 / Raw  
+    eth3: Ether / IP / ICMP 66.35.250.151 > 192.168.5.21 echo-reply 0 / Raw    
+    eth2: Ether / IP / ICMP 192.168.5.22 > 66.35.250.152 echo-request 0 / Raw  
+    eth2: Ether / IP / ICMP 66.35.250.152 > 192.168.5.22 echo-reply 0 / Raw
 
 For even more control over displayed information we can use the ``sprintf()`` function::
 
diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py
index db8b5c72743024402552972cd8f9cb973d3dab5d..f5776a1ae0361dc14e370e7696853d92a3105226 100644
--- a/scapy/arch/linux.py
+++ b/scapy/arch/linux.py
@@ -65,6 +65,17 @@ SOL_SOCKET = 1
 RTF_UP = 0x0001  # Route usable
 RTF_REJECT = 0x0200
 
+# From if_packet.h
+PACKET_HOST = 0  # To us
+PACKET_BROADCAST = 1  # To all
+PACKET_MULTICAST = 2  # To group
+PACKET_OTHERHOST = 3  # To someone else
+PACKET_OUTGOING = 4  # Outgoing of any type
+PACKET_LOOPBACK = 5  # MC/BRD frame looped back
+PACKET_USER = 6  # To user space
+PACKET_KERNEL = 7  # To kernel space
+PACKET_FASTROUTE = 6  # Fastrouted frame
+# Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space
 
 
 LOOPBACK_NAME="lo"
@@ -508,7 +519,9 @@ class L2ListenSocket(SuperSocket):
             cls = conf.l3types[sa_ll[1]]
         else:
             cls = conf.default_l2
-            warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],cls.name))
+            warning("Unable to guess type (interface=%s protocol=%#x "
+                    "family=%i). Using %s" % (sa_ll[0], sa_ll[1], sa_ll[3],
+                                              cls.name))
 
         try:
             pkt = cls(pkt)
@@ -519,6 +532,7 @@ class L2ListenSocket(SuperSocket):
                 raise
             pkt = conf.raw_layer(pkt)
         pkt.time = get_last_packet_timestamp(self.ins)
+        pkt.direction = sa_ll[2]
         return pkt
     
     def send(self, x):
diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
index ee7aaca9d9ec2ac1c7e97f78886f44066d296820..2c7218b6fc081c9d479bd028061bb1e01123a4d5 100644
--- a/scapy/sendrecv.py
+++ b/scapy/sendrecv.py
@@ -538,10 +538,12 @@ iface:    listen answers only on the given interface"""
 
 
 @conf.commands.register
-def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None,
-          opened_socket=None, stop_filter=None, *arg, **karg):
+def sniff(count=0, store=1, offline=None, prn=None, lfilter=None,
+          L2socket=None, timeout=None, opened_socket=None,
+          stop_filter=None, iface=None, *arg, **karg):
     """Sniff packets
-sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
+sniff([count=0,] [prn=None,] [store=1,] [offline=None,]
+[lfilter=None,] + L2ListenSocket args) -> list of packets
 
   count: number of packets to capture. 0 means infinity
   store: wether to store sniffed packets or discard them
@@ -558,47 +560,58 @@ opened_socket: provide an object ready to use .recv() on
 stop_filter: python function applied to each packet to determine
              if we have to stop the capture after this packet
              ex: stop_filter = lambda x: x.haslayer(TCP)
+iface: interface or list of interfaces (default: None for sniffing on all
+interfaces)
     """
     c = 0
-    
+    label = {}
+    ls = []
     if opened_socket is not None:
-        s = opened_socket
+        ls = [opened_socket]
     else:
         if offline is None:
             if L2socket is None:
                 L2socket = conf.L2listen
-            s = L2socket(type=ETH_P_ALL, *arg, **karg)
+            if type(iface) is list:
+                for i in iface:
+                    s = L2socket(type=ETH_P_ALL, iface=i, *arg, **karg)
+                    label[s] = i
+                    ls.append(s)
+            else:
+                ls = [L2socket(type=ETH_P_ALL, iface=iface, *arg, **karg)]
         else:
-            s = PcapReader(offline)
+            ls = [PcapReader(offline)]
 
     lst = []
     if timeout is not None:
         stoptime = time.time()+timeout
     remain = None
     try:
-        while 1:
+        stop_event = 0
+        while not stop_event:
             if timeout is not None:
                 remain = stoptime-time.time()
                 if remain <= 0:
                     break
-            sel = select([s],[],[],remain)
-            if s in sel[0]:
-                p = s.recv(MTU)
-                if p is None:
-                    continue
-                if lfilter and not lfilter(p):
-                    continue
-                if store:
-                    lst.append(p)
-                c += 1
-                if prn:
-                    r = prn(p)
-                    if r is not None:
-                        print r
-                if stop_filter and stop_filter(p):
-                    break
-                if count > 0 and c >= count:
-                    break
+            sel = select(ls, [], [], remain)
+            for s in sel[0]:
+                p = s.recv()
+                if p is not None:
+                    if lfilter and not lfilter(p):
+                        continue
+                    if s in label:
+                        p.sniffed_on = label[s]
+                    if store:
+                        lst.append(p)
+                    c += 1
+                    if prn:
+                        r = prn(p)
+                        if r is not None:
+                            print r
+                    if stop_filter and stop_filter(p):
+                        stop_event = 1
+                    if count > 0 and c >= count:
+                        stop_event = 1
     except KeyboardInterrupt:
         pass
     if opened_socket is None:
@@ -607,10 +620,12 @@ stop_filter: python function applied to each packet to determine
 
 
 @conf.commands.register
-def bridge_and_sniff(if1, if2, count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None,
+def bridge_and_sniff(if1, if2, count=0, store=1, offline=None, prn=None, 
+                     lfilter=None, L2socket=None, timeout=None,
                      stop_filter=None, *args, **kargs):
     """Forward traffic between two interfaces and sniff packets exchanged
-bridge_and_sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2Socket args) -> list of packets
+bridge_and_sniff([count=0,] [prn=None,] [store=1,] [offline=None,] 
+[lfilter=None,] + L2Socket args) -> list of packets
 
   count: number of packets to capture. 0 means infinity
   store: wether to store sniffed packets or discard them
@@ -639,12 +654,13 @@ stop_filter: python function applied to each packet to determine
         stoptime = time.time()+timeout
     remain = None
     try:
-        while True:
+        stop_event = 0
+        while not stop_event:
             if timeout is not None:
                 remain = stoptime-time.time()
                 if remain <= 0:
                     break
-            ins,outs,errs = select([s1,s2],[],[], remain)
+            ins, outs, errs = select([s1, s2], [], [], remain)
             for s in ins:
                 p = s.recv()
                 if p is not None:
@@ -658,11 +674,11 @@ stop_filter: python function applied to each packet to determine
                     if prn:
                         r = prn(p)
                         if r is not None:
-                            print "%s: %s" % (label[s],r)
+                            print r
                     if stop_filter and stop_filter(p):
-                        break
+                        stop_event = 1
                     if count > 0 and c >= count:
-                        break
+                        stop_event = 1
     except KeyboardInterrupt:
         pass
     finally:
@@ -674,3 +690,4 @@ def tshark(*args,**kargs):
     """Sniff packets and print them calling pkt.show(), a bit like text wireshark"""
     sniff(prn=lambda x: x.display(),*args,**kargs)
 
+