diff --git a/enet/host.c b/enet/host.c
--- a/enet/host.c
+++ b/enet/host.c
@@ -4,7 +4,6 @@
 */
 #define ENET_BUILDING_LIB 1
 #include <string.h>
-#include <time.h>
 #include "enet/enet.h"
 
 /** @defgroup host ENet host functions
@@ -76,11 +75,7 @@
       channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
 
     host -> randomSeed = (enet_uint32) (size_t) host;
-#ifdef WIN32
-    host -> randomSeed += (enet_uint32) timeGetTime();
-#else
-    host -> randomSeed += (enet_uint32) time(NULL);
-#endif
+    host -> randomSeed += enet_host_random_seed ();
     host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
     host -> channelLimit = channelLimit;
     host -> incomingBandwidth = incomingBandwidth;
diff --git a/enet/include/enet/enet.h b/enet/include/enet/enet.h
--- a/enet/include/enet/enet.h
+++ b/enet/include/enet/enet.h
@@ -25,7 +25,7 @@
 
 #define ENET_VERSION_MAJOR 1
 #define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 8
+#define ENET_VERSION_PATCH 9
 #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
 #define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
 #define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
@@ -60,7 +60,8 @@
    ENET_SOCKOPT_SNDBUF    = 4,
    ENET_SOCKOPT_REUSEADDR = 5,
    ENET_SOCKOPT_RCVTIMEO  = 6,
-   ENET_SOCKOPT_SNDTIMEO  = 7
+   ENET_SOCKOPT_SNDTIMEO  = 7,
+   ENET_SOCKOPT_ERROR     = 8
 } ENetSocketOption;
 
 typedef enum _ENetSocketShutdown
@@ -491,6 +492,7 @@
 ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
 ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
 ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
+ENET_API int        enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
 ENET_API int        enet_socket_shutdown (ENetSocket, ENetSocketShutdown);
 ENET_API void       enet_socket_destroy (ENetSocket);
 ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
@@ -549,6 +551,7 @@
 ENET_API void       enet_host_channel_limit (ENetHost *, size_t);
 ENET_API void       enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
 extern   void       enet_host_bandwidth_throttle (ENetHost *);
+extern  enet_uint32 enet_host_random_seed (void);
 
 ENET_API int                 enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
 ENET_API ENetPacket *        enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
diff --git a/enet/protocol.c b/enet/protocol.c
--- a/enet/protocol.c
+++ b/enet/protocol.c
@@ -1666,12 +1666,7 @@
            enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
 
 #ifdef ENET_DEBUG
-#ifdef WIN32
-           printf (
-#else
-           fprintf (stderr, 
-#endif
-                    "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
+           printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
 #endif
           
            currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
@@ -1716,12 +1711,7 @@
                 host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
                 shouldCompress = compressedSize;
 #ifdef ENET_DEBUG_COMPRESS
-#ifdef WIN32
-           printf (
-#else
-           fprintf (stderr,
-#endif
-                    "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
+                printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
 #endif
             }
         }
diff --git a/enet/unix.c b/enet/unix.c
--- a/enet/unix.c
+++ b/enet/unix.c
@@ -69,6 +69,12 @@
 }
 
 enet_uint32
+enet_host_random_seed (void)
+{
+    return (enet_uint32) time (NULL);
+}
+
+enet_uint32
 enet_time_get (void)
 {
     struct timeval timeVal;
@@ -257,6 +263,24 @@
 
         case ENET_SOCKOPT_SNDTIMEO:
             result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == -1 ? -1 : 0;
+}
+
+int
+enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
+{
+    int result = -1;
+    socklen_t len;
+    switch (option)
+    {
+        case ENET_SOCKOPT_ERROR:
+            len = sizeof (int);
+            result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
             break;
 
         default:
diff --git a/enet/win32.c b/enet/win32.c
--- a/enet/win32.c
+++ b/enet/win32.c
@@ -41,6 +41,12 @@
 }
 
 enet_uint32
+enet_host_random_seed (void)
+{
+    return (enet_uint32) timeGetTime ();
+}
+
+enet_uint32
 enet_time_get (void)
 {
     return (enet_uint32) timeGetTime () - timeBase;
@@ -187,6 +193,23 @@
 
         case ENET_SOCKOPT_SNDTIMEO:
             result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
+{
+    int result = SOCKET_ERROR, len;
+    switch (option)
+    {
+        case ENET_SOCKOPT_ERROR:
+            len = sizeof(int);
+            result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
             break;
 
         default:
diff --git a/henet.cabal b/henet.cabal
--- a/henet.cabal
+++ b/henet.cabal
@@ -1,5 +1,5 @@
 Name:                 henet
-Version:              1.3.8.1.1
+Version:              1.3.9.0
 Synopsis:             Bindings and high level interface for to ENet v1.3.8
 Description:
   ENet is a networking library on top of UDP. In it's own words:
@@ -34,10 +34,10 @@
   try to add Haddock documentation for everywhere it does not.
   .
   ENet currently only supports IPv4 at the moment (though that should soon
-  change), and is only safe to use as when used in one thread. Richer native
-  networking libraries leveraging Haskell's strengths exist, and for new
-  projects I'd recommend those. But for interfacing with existing protocols
-  using ENet, this package should be quite useful.
+  change), and must be called from only one bound thread (i.e. thread created
+  with 'forkOS'). Richer native networking libraries leveraging Haskell's
+  strengths exist, and for new projects I'd recommend those. But for interfacing
+  with existing protocols using ENet, this package should be quite useful.
 
 License-file:         enet/LICENSE
 License:              MIT
@@ -72,10 +72,9 @@
 
 
   build-depends:      base            >= 3 && < 5
-    ,                 bitset          >= 1.4.0
+    ,                 bitset          >= 1.4.7
     ,                 network         >= 2.4.1
     ,                 bytestring      >= 0.10
-    ,                 primitive       >= 0.2.1
     ,                 typesafe-endian == 0.1.*
 
   exposed-modules:    Network.ENet
@@ -87,7 +86,6 @@
   other-modules:      Network.ENet.Internal
     ,                 Network.ENet.Bindings.System
     ,                 Network.ENet.Bindings.Callbacks
---    ,                 Network.ENet.Bindings.Protocol
     ,                 Network.ENet.Bindings.List
 
   c-sources:          enet/callbacks.c
diff --git a/src/Network/ENet/Bindings.hsc b/src/Network/ENet/Bindings.hsc
--- a/src/Network/ENet/Bindings.hsc
+++ b/src/Network/ENet/Bindings.hsc
@@ -49,6 +49,7 @@
                   | ReuseAddress
                   | ReceiveTimeIs0
                   | SendTimeIs0
+                  | Error
                   deriving (Show, Eq)
 
 instance Enum SocketOption where
@@ -172,130 +173,132 @@
 
  -- Global functions
 
-foreign import ccall "enet.h enet_initialize"                initialize
+foreign import ccall unsafe "enet.h enet_initialize"                initialize
   :: IO CInt
-foreign import ccall "enet.h enet_initialize_with_callbacks" initializeWithCallbacks
+foreign import ccall unsafe "enet.h enet_initialize_with_callbacks" initializeWithCallbacks
   :: Version -> Ptr Callbacks -> IO CInt
-foreign import ccall "enet.h enet_deinitialize"              deinitialize
+foreign import ccall unsafe "enet.h enet_deinitialize"              deinitialize
   :: IO ()
-foreign import ccall "enet.h enet_linked_version"            linkedVersion
+foreign import ccall unsafe "enet.h enet_linked_version"            linkedVersion
   :: IO Version
 
-foreign import ccall "enet.h enet_time_get"                  timeGet
+foreign import ccall unsafe "enet.h enet_time_get"                  timeGet
   :: IO Word32
-foreign import ccall "enet.h enet_time_set"                  timeSet
+foreign import ccall unsafe "enet.h enet_time_set"                  timeSet
   :: Word32 -> IO ()
 
 
  -- Socket Functions
 
-foreign import ccall "enet.h enet_socket_create"      socketCreate
+foreign import ccall unsafe "enet.h enet_socket_create"      socketCreate
   :: CUInt -> IO Socket
-foreign import ccall "enet.h enet_socket_bind"        socketBind
+foreign import ccall unsafe "enet.h enet_socket_bind"        socketBind
   :: Socket -> Ptr Address -> IO CInt
-foreign import ccall "enet.h enet_socket_get_address" socketGetAddress
+foreign import ccall unsafe "enet.h enet_socket_get_address" socketGetAddress
   :: Socket -> Ptr Address -> IO CInt
-foreign import ccall "enet.h enet_socket_listen"      socketListen
+foreign import ccall unsafe "enet.h enet_socket_listen"      socketListen
   :: Socket -> CInt -> IO CInt
-foreign import ccall "enet.h enet_socket_accept"      socketAccept
+foreign import ccall unsafe "enet.h enet_socket_accept"      socketAccept
   :: Socket -> Ptr Address -> IO Socket
-foreign import ccall "enet.h enet_socket_connect"     socketConnect
+foreign import ccall unsafe "enet.h enet_socket_connect"     socketConnect
   :: Socket -> Ptr Address -> IO CInt
-foreign import ccall "enet.h enet_socket_send"        socketSend
+foreign import ccall unsafe "enet.h enet_socket_send"        socketSend
   :: Socket -> Ptr Address -> Ptr Buffer -> CSize -> IO CInt
-foreign import ccall "enet.h enet_socket_receive"     socketReceive
+foreign import ccall unsafe "enet.h enet_socket_receive"     socketReceive
   :: Socket -> Ptr Address -> Ptr Buffer -> CSize -> IO CInt
-foreign import ccall "enet.h enet_socket_wait"        socketWait
+foreign import ccall unsafe "enet.h enet_socket_wait"        socketWait
   :: Socket -> Ptr Word32 -> Ptr Word32 -> IO CInt
-foreign import ccall "enet.h enet_socket_set_option"  socketSetOption
+foreign import ccall unsafe "enet.h enet_socket_set_option"  socketSetOption
   :: Socket -> CUInt -> CInt -> IO CInt
-foreign import ccall "enet.h enet_socket_shutdown"    socketShutdown
+foreign import ccall unsafe "enet.h enet_socket_get_option"  socketGetOption
+  :: Socket -> CUInt -> Ptr CInt -> IO CInt
+foreign import ccall unsafe "enet.h enet_socket_shutdown"    socketShutdown
   :: Socket -> CUInt -> IO CInt
-foreign import ccall "enet.h enet_socket_destroy"     socketDestroy
+foreign import ccall unsafe "enet.h enet_socket_destroy"     socketDestroy
   :: Socket -> IO ()
-foreign import ccall "enet.h enet_socketset_select"   socketSelectSet
+foreign import ccall unsafe "enet.h enet_socketset_select"   socketSelectSet
   :: Socket -> Ptr SocketSet -> Ptr SocketSet -> Word32 -> IO CInt
 
 
  -- Address Functions
 
-foreign import ccall "enet.h enet_address_set_host"    addressSetHost
+foreign import ccall unsafe "enet.h enet_address_set_host"    addressSetHost
   :: Ptr Address -> IO CString
-foreign import ccall "enet.h enet_address_get_host_ip" addressGetHostIP
+foreign import ccall unsafe "enet.h enet_address_get_host_ip" addressGetHostIP
   :: Ptr Address -> CString -> IO CSize
-foreign import ccall "enet.h enet_address_get_host"    addressGetHost
+foreign import ccall unsafe "enet.h enet_address_get_host"    addressGetHost
   :: Ptr Address -> CString -> IO CSize
 
 
  -- Packet Functions
 
-foreign import ccall "enet.h enet_packet_create"   packetCreate
+foreign import ccall unsafe "enet.h enet_packet_create"   packetCreate
   :: Ptr () -> CSize -> Word32 -> IO (Ptr Packet)
-foreign import ccall "enet.h enet_packet_destroy"  packetDestroy
+foreign import ccall unsafe "enet.h enet_packet_destroy"  packetDestroy
   :: Ptr Packet -> IO ()
-foreign import ccall "enet.h enet_packet_resize"   packetResize
+foreign import ccall unsafe "enet.h enet_packet_resize"   packetResize
   :: Ptr Packet -> CSize -> IO CInt
-foreign import ccall "enet.h enet_crc32"           crc32
+foreign import ccall unsafe "enet.h enet_crc32"           crc32
   :: Ptr Buffer -> CSize -> IO Word32
 
 
  -- Host Functions
 
-foreign import ccall "enet.h enet_host_create"                    hostCreate
+foreign import ccall unsafe "enet.h enet_host_create"                    hostCreate
   :: Ptr Address -> CSize -> CSize -> Word32 -> Word32 -> IO (Ptr Host)
-foreign import ccall "enet.h enet_host_destroy"                   hostDestroy
+foreign import ccall unsafe "enet.h enet_host_destroy"                   hostDestroy
   :: Ptr Host -> IO ()
-foreign import ccall "enet.h enet_host_connect"                   hostConnect
+foreign import ccall unsafe "enet.h enet_host_connect"                   hostConnect
   :: Ptr Host -> Ptr Address -> CSize -> Word32 -> IO (Ptr Peer)
-foreign import ccall "enet.h enet_host_check_events"              hostCheckEvents
+foreign import ccall unsafe "enet.h enet_host_check_events"              hostCheckEvents
   :: Ptr Host -> Ptr Event -> IO CUInt
-foreign import ccall "enet.h enet_host_service"                   hostService
+foreign import ccall unsafe "enet.h enet_host_service"                   hostService
   :: Ptr Host -> Ptr Event -> Word32 -> IO CUInt
-foreign import ccall "enet.h enet_host_flush"                     hostFlush
+foreign import ccall unsafe "enet.h enet_host_flush"                     hostFlush
   :: Ptr Host -> IO ()
-foreign import ccall "enet.h enet_host_broadcast"                 hostBroadcast
+foreign import ccall unsafe "enet.h enet_host_broadcast"                 hostBroadcast
   :: Ptr Host -> ChannelID -> Ptr Packet -> IO ()
-foreign import ccall "enet.h enet_host_compress"                  hostCompress
+foreign import ccall unsafe "enet.h enet_host_compress"                  hostCompress
   :: Ptr Host -> Ptr Compressor -> IO ()
-foreign import ccall "enet.h enet_host_compress_with_range_coder" hostCompressWithRangeCoder
+foreign import ccall unsafe "enet.h enet_host_compress_with_range_coder" hostCompressWithRangeCoder
   :: Ptr Host -> IO CUInt
-foreign import ccall "enet.h enet_host_channel_limit"             hostChannelLimit
+foreign import ccall unsafe "enet.h enet_host_channel_limit"             hostChannelLimit
   :: Ptr Host -> CSize -> IO ()
-foreign import ccall "enet.h enet_host_bandwidth_limit"           hostBandwidthLimit
+foreign import ccall unsafe "enet.h enet_host_bandwidth_limit"           hostBandwidthLimit
   :: Ptr Host -> Word32 -> Word32 -> IO ()
 
 
  -- Peer Functions
 
-foreign import ccall "enet.h enet_peer_send"               peerSend
+foreign import ccall unsafe "enet.h enet_peer_send"               peerSend
   :: Ptr Peer -> ChannelID -> Ptr Packet -> IO CInt
-foreign import ccall "enet.h enet_peer_receive"            peerReceive
+foreign import ccall unsafe "enet.h enet_peer_receive"            peerReceive
   :: Ptr Peer -> ChannelID -> IO (Ptr Packet)
-foreign import ccall "enet.h enet_peer_ping"               peerPing
+foreign import ccall unsafe "enet.h enet_peer_ping"               peerPing
   :: Ptr Peer -> IO ()
-foreign import ccall "enet.h enet_peer_ping_interval"      peerPingInterval
+foreign import ccall unsafe "enet.h enet_peer_ping_interval"      peerPingInterval
   :: Ptr Peer -> Word32 -> IO ()
-foreign import ccall "enet.h enet_peer_timeout"            peerTimeout
+foreign import ccall unsafe "enet.h enet_peer_timeout"            peerTimeout
   :: Ptr Peer -> Word32 -> Word32 -> Word32 -> IO ()
-foreign import ccall "enet.h enet_peer_reset"              peerReset
+foreign import ccall unsafe "enet.h enet_peer_reset"              peerReset
   :: Ptr Peer -> IO ()
-foreign import ccall "enet.h enet_peer_disconnect"         peerDisconnect
+foreign import ccall unsafe "enet.h enet_peer_disconnect"         peerDisconnect
   :: Ptr Peer -> Word32 -> IO ()
-foreign import ccall "enet.h enet_peer_disconnect_now"     peerDisconnectNow
+foreign import ccall unsafe "enet.h enet_peer_disconnect_now"     peerDisconnectNow
   :: Ptr Peer -> Word32 -> IO ()
-foreign import ccall "enet.h enet_peer_disconnect_later"   peerDisconnectLater
+foreign import ccall unsafe "enet.h enet_peer_disconnect_later"   peerDisconnectLater
   :: Ptr Peer -> Word32 -> IO ()
-foreign import ccall "enet.h enet_peer_throttle_configure" peerThrottleConfigure
+foreign import ccall unsafe "enet.h enet_peer_throttle_configure" peerThrottleConfigure
   :: Ptr Peer -> Word32 -> Word32 -> Word32 -> IO ()
 
 
  -- Range Coder Functions
 
-foreign import ccall "enet.h enet_range_coder_create"     rangeCoderCreate
+foreign import ccall unsafe "enet.h enet_range_coder_create"     rangeCoderCreate
   :: IO (Ptr  RangeCoder)
-foreign import ccall "enet.h enet_range_coder_destroy"    rangeCoderDestroy
+foreign import ccall unsafe "enet.h enet_range_coder_destroy"    rangeCoderDestroy
   :: Ptr RangeCoder -> IO ()
-foreign import ccall "enet.h enet_range_coder_compress"   rangeCoderCompress
+foreign import ccall unsafe "enet.h enet_range_coder_compress"   rangeCoderCompress
   :: Ptr RangeCoder -> Ptr Buffer -> CSize -> CSize -> Word8 -> CSize -> IO CSize
-foreign import ccall "enet.h enet_range_coder_decompress" rangeCoderDecompress
+foreign import ccall unsafe "enet.h enet_range_coder_decompress" rangeCoderDecompress
   :: Ptr RangeCoder -> Ptr Buffer -> CSize -> Word8 -> CSize -> IO CSize
diff --git a/src/Network/ENet/Host.hs b/src/Network/ENet/Host.hs
--- a/src/Network/ENet/Host.hs
+++ b/src/Network/ENet/Host.hs
@@ -20,7 +20,7 @@
 connect host address channelCount datum = alloca $ \addr -> do
   poke addr $ toENetAddress address
   throwErrnoIf
-    (/=nullPtr)
+    (==nullPtr)
     "could not connect to peer"
     $ B.hostConnect host addr channelCount datum
 
diff --git a/src/Network/ENet/Packet.hs b/src/Network/ENet/Packet.hs
--- a/src/Network/ENet/Packet.hs
+++ b/src/Network/ENet/Packet.hs
@@ -4,26 +4,20 @@
 import Foreign.C.Error
 import Foreign.C.Types
 
-import Data.Word
-
-import Data.BitSet.Generic(GBitSet, toBits, unsafeFromBits)
+import Data.BitSet.Generic(BitSet(getBits))
 
 import qualified Data.ByteString        as SB
 import qualified Data.ByteString.Unsafe as SB
 
-import Data.Endian
-import Data.Endian.Unsafe( unsafeUnwrapBigEndian
-                         , unsafeAssertBigEndian)
-
 import qualified Network.ENet.Bindings as B
 
-type PacketFlagSet = GBitSet Word32 B.PacketFlag
+type PacketFlagSet = BitSet Word32 B.PacketFlag
 
 -- String is defensively coppied, so unsafe is appropriate
 
 create :: SB.ByteString -> PacketFlagSet -> IO (Ptr B.Packet)
-create bytes flags = SB.unsafeUseAsCStringLen bytes $
-              \(ptr,len) -> B.packetCreate (castPtr ptr) (fromIntegral len) $ toBits flags
+create bytes flags = SB.unsafeUseAsCStringLen bytes $ \(ptr,len) ->
+  B.packetCreate (castPtr ptr) (fromIntegral len) $ getBits flags
 
 destroy :: Ptr B.Packet -> IO ()
 destroy = B.packetDestroy
