module System.Socket.Family.Inet
( Inet
, SocketAddressInet (..)
, Address ()
, Port (..)
, allHostsGroup
, System.Socket.Family.Inet.any
, broadcast
, loopback
, maxLocalGroup
, none
, unspecificGroup
) where
import Data.Word
import Data.List
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BS
import Control.Applicative
import Foreign.Ptr
import Foreign.Storable
import Foreign.Marshal.Utils
import System.Socket.Family
import System.Socket.Internal.Platform
data Inet
instance Family Inet where
type SocketAddress Inet = SocketAddressInet
familyNumber _ = (2)
data SocketAddressInet
= SocketAddressInet
{ address :: Address
, port :: Port
} deriving (Eq, Show)
newtype Port
= Port Word16
deriving (Eq, Ord, Num)
instance Show Port where
show (Port p) = show p
newtype Address
= Address BS.ByteString
deriving (Eq)
any :: Address
any = Address $ BS.pack [ 0, 0, 0, 0]
broadcast :: Address
broadcast = Address $ BS.pack [255,255,255,255]
none :: Address
none = Address $ BS.pack [255,255,255,255]
loopback :: Address
loopback = Address $ BS.pack [127, 0, 0, 1]
unspecificGroup :: Address
unspecificGroup = Address $ BS.pack [224, 0, 0, 0]
allHostsGroup :: Address
allHostsGroup = Address $ BS.pack [224, 0, 0, 1]
maxLocalGroup :: Address
maxLocalGroup = Address $ BS.pack [224, 0, 0,255]
instance Show Address where
show (Address a) =
concat $ intersperse "." $ map show $ BS.unpack a
instance Storable Address where
sizeOf _ = ((4))
alignment _ = (4)
peek ptr =
Address <$> BS.packCStringLen (castPtr ptr, 4)
poke ptr (Address a) =
BS.unsafeUseAsCString a $ \aPtr-> do
copyBytes ptr (castPtr aPtr) (min 4 $ BS.length a)
instance Storable SocketAddressInet where
sizeOf _ = ((16))
alignment _ = (4)
peek ptr = do
ph <- peekByteOff (sin_port ptr) 0 :: IO Word8
pl <- peekByteOff (sin_port ptr) 1 :: IO Word8
a <- peek (sin_addr ptr) :: IO Address
return (SocketAddressInet a (Port $ fromIntegral ph * 256 + fromIntegral pl))
where
sin_port = ((\hsc_ptr -> hsc_ptr `plusPtr` 2))
sin_addr = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) . ((\hsc_ptr -> hsc_ptr `plusPtr` 4))
poke ptr (SocketAddressInet a (Port p)) = do
c_memset ptr 0 (16)
poke (sin_family ptr) ((2) :: Word16)
pokeByteOff (sin_port ptr) 0 (fromIntegral $ rem (quot p 256) 256 :: Word8)
pokeByteOff (sin_port ptr) 1 (fromIntegral $ rem p 256 :: Word8)
poke (sin_addr ptr) a
where
sin_family = ((\hsc_ptr -> hsc_ptr `plusPtr` 0))
sin_port = ((\hsc_ptr -> hsc_ptr `plusPtr` 2))
sin_addr = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) . ((\hsc_ptr -> hsc_ptr `plusPtr` 4))