diff --git a/scapy/arch/bpf/supersocket.py b/scapy/arch/bpf/supersocket.py
index d4f48235e3ceec4cd6dd68a32abcaa91183deed6..e0650020dbac4d421a85a5c78bfc9c1f87bd3639 100644
--- a/scapy/arch/bpf/supersocket.py
+++ b/scapy/arch/bpf/supersocket.py
@@ -4,24 +4,28 @@
 Scapy *BSD native support - BPF sockets
 """
 
+import errno
+import fcntl
+import os
+from select import select
+import struct
+import time
+
+from scapy.arch.bpf.core import get_dev_bpf, attach_filter
+from scapy.arch.bpf.consts import BIOCGBLEN, BIOCGDLT, BIOCGSTATS, \
+    BIOCIMMEDIATE, BIOCPROMISC, BIOCSBLEN, BIOCSETIF, BIOCSHDRCMPLT, \
+    BPF_BUFFER_LENGTH
 from scapy.config import conf
+from scapy.consts import FREEBSD, NETBSD
+from scapy.data import ETH_P_ALL
 from scapy.error import Scapy_Exception, warning
 from scapy.supersocket import SuperSocket
-from scapy.layers.inet import IP
-from scapy.layers.inet6 import IPv6
-from scapy.packet import Raw
-from scapy.data import ETH_P_ALL
-from scapy.consts import FREEBSD, OPENBSD, NETBSD
 
-from scapy.arch.bpf.core import get_dev_bpf, attach_filter
-from scapy.arch.bpf.consts import *
 
-import struct
-import fcntl
-import os
-import time
-import errno
-from select import select
+if FREEBSD or NETBSD:
+    BPF_ALIGNMENT = 8  # sizeof(long)
+else:
+    BPF_ALIGNMENT = 4  # sizeof(int32_t)
 
 
 # SuperSockets definitions
@@ -55,16 +59,15 @@ class _L2bpfSocket(SuperSocket):
         # Set the BPF buffer length
         try:
             fcntl.ioctl(self.ins, BIOCSBLEN, struct.pack('I', BPF_BUFFER_LENGTH))
-        except IOError as err:
-            msg = "BIOCSBLEN failed on /dev/bpf%i" % self.dev_bpf
-            raise Scapy_Exception(msg)
+        except IOError:
+            raise Scapy_Exception("BIOCSBLEN failed on /dev/bpf%i" %
+                                  self.dev_bpf)
 
         # Assign the network interface to the BPF handle
         try:
             fcntl.ioctl(self.ins, BIOCSETIF, struct.pack("16s16x", self.iface))
-        except IOError as err:
-            msg = "BIOCSETIF failed on %s" % self.iface
-            raise Scapy_Exception(msg)
+        except IOError:
+            raise Scapy_Exception("BIOCSETIF failed on %s" % self.iface)
         self.assigned_interface = self.iface
 
         # Set the interface into promiscuous
@@ -74,17 +77,17 @@ class _L2bpfSocket(SuperSocket):
         # Don't block on read
         try:
             fcntl.ioctl(self.ins, BIOCIMMEDIATE, struct.pack('I', 1))
-        except IOError as err:
-            msg = "BIOCIMMEDIATE failed on /dev/bpf%i" % self.dev_bpf
-            raise Scapy_Exception(msg)
+        except IOError:
+            raise Scapy_Exception("BIOCIMMEDIATE failed on /dev/bpf%i" %
+                                  self.dev_bpf)
 
         # Scapy will provide the link layer source address
         # Otherwise, it is written by the kernel
         try:
             fcntl.ioctl(self.ins, BIOCSHDRCMPLT, struct.pack('i', 1))
-        except IOError as err:
-            msg = "BIOCSHDRCMPLT failed on /dev/bpf%i" % self.dev_bpf
-            raise Scapy_Exception(msg)
+        except IOError:
+            raise Scapy_Exception("BIOCSHDRCMPLT failed on /dev/bpf%i" %
+                                  self.dev_bpf)
 
         # Configure the BPF filter
         if not nofilter:
@@ -104,13 +107,16 @@ class _L2bpfSocket(SuperSocket):
 
         try:
             fcntl.ioctl(self.ins, BIOCPROMISC, struct.pack('i', value))
-        except IOError as err:
-            msg = "Can't put your interface (%s) into promiscuous mode !" % self.iface
-            raise Scapy_Exception(msg)
+        except IOError:
+            raise Scapy_Exception("Cannott set promiscuous mode on interface "
+                                  "(%s)!" % self.iface)
 
     def __del__(self):
         """Close the file descriptor on delete"""
-        self.close()
+        # When the socket is deleted on Scapy exits, __del__ is
+        # sometimes called "too late", and self is None
+        if self is not None:
+            self.close()
 
     def guess_cls(self):
         """Guess the packet class that must be used on the interface"""
@@ -119,16 +125,12 @@ class _L2bpfSocket(SuperSocket):
         try:
             ret = fcntl.ioctl(self.ins, BIOCGDLT, struct.pack('I', 0))
             ret = struct.unpack('I', ret)[0]
-        except IOError as err:
+        except IOError:
             cls = conf.default_l2
             warning("BIOCGDLT failed: unable to guess type. Using %s !",
                     cls.name)
             return cls
 
-        # *BSD loopback interface
-        if OPENBSD and ret == 12:  # DTL_NULL on OpenBSD
-            return Loopback
-
         # Retrieve the corresponding class
         try:
             return conf.l2types[ret]
@@ -143,8 +145,8 @@ class _L2bpfSocket(SuperSocket):
         if self.fd_flags is None:
             try:
                 self.fd_flags = fcntl.fcntl(self.ins, fcntl.F_GETFL)
-            except IOError as err:
-                warning("Can't get flags on this file descriptor !")
+            except IOError:
+                warning("Cannot get flags on this file descriptor !")
                 return
 
         # Set the non blocking flag
@@ -165,7 +167,7 @@ class _L2bpfSocket(SuperSocket):
         try:
             ret = fcntl.ioctl(self.ins, BIOCGSTATS, struct.pack("2I", 0, 0))
             return struct.unpack("2I", ret)
-        except IOError as err:
+        except IOError:
             warning("Unable to get stats from BPF !")
             return (None, None)
 
@@ -175,7 +177,7 @@ class _L2bpfSocket(SuperSocket):
         try:
             ret = fcntl.ioctl(self.ins, BIOCGBLEN, struct.pack("I", 0))
             return struct.unpack("I", ret)[0]
-        except IOError as err:
+        except IOError:
             warning("Unable to get the BPF buffer length")
             return
 
@@ -211,25 +213,15 @@ class L2bpfListenSocket(_L2bpfSocket):
 
     def get_frame(self):
         """Get a frame or packet from the received list"""
-
         if self.received_frames:
-            pkt = self.received_frames.pop(0)
-            if isinstance(self, L3bpfSocket):
-                pkt = pkt.payload
-            return pkt
-
-        return None
+            return self.received_frames.pop(0)
 
-    def bpf_align(self, bh_h, bh_c):
+    @staticmethod
+    def bpf_align(bh_h, bh_c):
         """Return the index to the end of the current packet"""
 
-        if FREEBSD or NETBSD:
-            BPF_ALIGNMENT = 8  # sizeof(long)
-        else:
-            BPF_ALIGNMENT = 4  # sizeof(int32_t)
-
-        x = bh_h + bh_c
-        return ((x)+(BPF_ALIGNMENT-1)) & ~(BPF_ALIGNMENT-1)  # from <net/bpf.h>
+        # from <net/bpf.h>
+        return ((bh_h + bh_c)+(BPF_ALIGNMENT-1)) & ~(BPF_ALIGNMENT-1)
 
     def extract_frames(self, bpf_buffer):
         """Extract all frames from the buffer and stored them in the received list."""
@@ -263,7 +255,7 @@ class L2bpfListenSocket(_L2bpfSocket):
         except:
             if conf.debug_dissector:
                 raise
-            pkt = Raw(frame_str)
+            pkt = conf.raw_layer(frame_str)
         self.received_frames.append(pkt)
 
         # Extract the next frame
@@ -278,20 +270,17 @@ class L2bpfListenSocket(_L2bpfSocket):
             # Get a frame from the buffer
             return self.get_frame()
 
-        else:
-            # Get data from BPF
-            try:
-                bpf_buffer = os.read(self.ins, x)
-            except EnvironmentError as e:
-                if e.errno == errno.EAGAIN:
-                    return
-                else:
-                    warning("BPF recv(): %s" % e)
-                    return
+        # Get data from BPF
+        try:
+            bpf_buffer = os.read(self.ins, x)
+        except EnvironmentError as exc:
+            if exc.errno != errno.EAGAIN:
+                warning("BPF recv()", exc_info=True)
+            return
 
-            # Extract all frames from the BPF buffer
-            self.extract_frames(bpf_buffer)
-            return self.get_frame()
+        # Extract all frames from the BPF buffer
+        self.extract_frames(bpf_buffer)
+        return self.get_frame()
 
 
 class L2bpfSocket(L2bpfListenSocket):
@@ -308,34 +297,35 @@ class L2bpfSocket(L2bpfListenSocket):
             # Get a frame from the buffer
             return self.get_frame()
 
-        else:
-            # Set the non blocking flag, read from the socket, and unset the flag
-            self.set_nonblock(True)
-            pkt = L2bpfListenSocket.recv(self)
-            self.set_nonblock(False)
-            return pkt
+        # Set the non blocking flag, read from the socket, and unset the flag
+        self.set_nonblock(True)
+        pkt = L2bpfListenSocket.recv(self)
+        self.set_nonblock(False)
+        return pkt
 
 
 class L3bpfSocket(L2bpfSocket):
 
+    def get_frame(self):
+        """Get a frame or packet from the received list"""
+        pkt = super(L3bpfSocket, self).get_frame()
+        if pkt is not None:
+            return pkt.payload
+
     def send(self, pkt):
         """Send a packet"""
 
         # Use the routing table to find the output interface
-        if isinstance(pkt, IPv6):
-            iff, a, gw = conf.route6.route(pkt.dst)
-        if isinstance(pkt, IP):
-            iff, a, gw = conf.route.route(pkt.dst)
-        else:
+        iff = pkt.route()[0]
+        if iff is None:
             iff = conf.iface
 
         # Assign the network interface to the BPF handle
         if self.assigned_interface != iff:
             try:
                 fcntl.ioctl(self.outs, BIOCSETIF, struct.pack("16s16x", iff))
-            except IOError as err:
-                msg = "BIOCSETIF failed on %s" % iff
-                raise Scapy_Exception(msg)
+            except IOError:
+                raise Scapy_Exception("BIOCSETIF failed on %s" % iff)
             self.assigned_interface = iff
 
         # Build the frame
diff --git a/scapy/error.py b/scapy/error.py
index 793e220bb8a8acab44356881c68b7f96fc094696..d7273447d018e12e15534362ebf43fd3ffdfccf8 100644
--- a/scapy/error.py
+++ b/scapy/error.py
@@ -64,14 +64,13 @@ log_interactive = logging.getLogger("scapy.interactive")  # logs in interactive
 log_loading = logging.getLogger("scapy.loading")          # logs when loading Scapy
 
 
-def warning(x, onlyOnce=None):
+def warning(x, *args, **kargs):
     """
     Prints a warning during runtime.
 
     onlyOnce - if True, the warning will never be printed again.
     """ 
-    if onlyOnce:
+    if kargs.pop("onlyOnce", False):
         from scapy.config import conf
         conf.warning_next_only_once = True
-    log_runtime.warning(x)
-
+    log_runtime.warning(x, *args, **kargs)
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index 6c469416003fd4a38ecbb9ab0c3f870c4a9419ea..be474e653b4279436ecdf3b2abb2e15a3e740f11 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -18,7 +18,7 @@ from scapy.base_classes import Gen
 from scapy.data import *
 from scapy.layers.l2 import *
 from scapy.config import conf
-from scapy.consts import WINDOWS
+from scapy.consts import OPENBSD, WINDOWS
 from scapy.fields import *
 from scapy.packet import *
 from scapy.volatile import *
@@ -796,6 +796,7 @@ bind_layers( Ether,         IP,            type=2048)
 bind_layers( CookedLinux,   IP,            proto=2048)
 bind_layers( GRE,           IP,            proto=2048)
 bind_layers( SNAP,          IP,            code=2048)
+bind_layers( Loopback,      IP,            type=0)
 bind_layers( Loopback,      IP,            type=2)
 bind_layers( IPerror,       IPerror,       frag=0, proto=4)
 bind_layers( IPerror,       ICMPerror,     frag=0, proto=1)
@@ -808,7 +809,9 @@ bind_layers( IP,            UDP,           frag=0, proto=17)
 bind_layers( IP,            GRE,           frag=0, proto=47)
 
 conf.l2types.register(101, IP)
-conf.l2types.register_num2layer(12, IP)
+if not OPENBSD:
+    # see scapy.layers.l2.py
+    conf.l2types.register_num2layer(12, IP)
 conf.l2types.register(DLT_IPV4, IP)
 
 conf.l3types.register(ETH_P_IP, IP)
diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py
index ae6dc5c0b8db7b12cc4e507b2c968bf221891fc3..d8f540d77bcb1e49499510a7763c0d4067337131 100644
--- a/scapy/layers/l2.py
+++ b/scapy/layers/l2.py
@@ -13,6 +13,7 @@ import os, struct, time, socket
 
 from scapy.base_classes import Net
 from scapy.config import conf
+from scapy.consts import OPENBSD
 from scapy.data import *
 from scapy.packet import *
 from scapy.ansmachine import *
@@ -447,6 +448,9 @@ conf.l2types.register_layer2num(ARPHDR_ETHER, Dot3)
 conf.l2types.register(144, CookedLinux)  # called LINUX_IRDA, similar to CookedLinux
 conf.l2types.register(113, CookedLinux)
 conf.l2types.register(DLT_NULL, Loopback)
+# Under OpenBSD, for some reason, DLT_NULL == 12
+if OPENBSD:
+    conf.l2types.register(12, Loopback)
 
 conf.l3types.register(ETH_P_ARP, ARP)