module System.Socket.Family.INET
( INET
, AddrIn ()
, SockAddrIn (..)
, inaddrANY
, inaddrBROADCAST
, inaddrNONE
, inaddrLOOPBACK
, inaddrUNSPEC_GROUP
, inaddrALLHOSTS_GROUP
, inaddrALLRTS_GROUP
, inaddrMAXLOCAL_GROUP
) 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 SockAddr INET = SockAddrIn
familyNumber _ = (2)
data SockAddrIn
= SockAddrIn
{ sinPort :: Word16
, sinAddr :: AddrIn
} deriving (Eq)
newtype AddrIn
= AddrIn BS.ByteString
deriving (Eq)
inaddrANY :: AddrIn
inaddrANY = AddrIn $ BS.pack [ 0, 0, 0, 0]
inaddrBROADCAST :: AddrIn
inaddrBROADCAST = AddrIn $ BS.pack [255,255,255,255]
inaddrNONE :: AddrIn
inaddrNONE = AddrIn $ BS.pack [255,255,255,255]
inaddrLOOPBACK :: AddrIn
inaddrLOOPBACK = AddrIn $ BS.pack [127, 0, 0, 1]
inaddrUNSPEC_GROUP :: AddrIn
inaddrUNSPEC_GROUP = AddrIn $ BS.pack [224, 0, 0, 0]
inaddrALLHOSTS_GROUP :: AddrIn
inaddrALLHOSTS_GROUP = AddrIn $ BS.pack [224, 0, 0, 1]
inaddrALLRTS_GROUP :: AddrIn
inaddrALLRTS_GROUP = AddrIn $ BS.pack [224, 0, 0, 2]
inaddrMAXLOCAL_GROUP :: AddrIn
inaddrMAXLOCAL_GROUP = AddrIn $ BS.pack [224, 0, 0,255]
instance Show SockAddrIn where
show (SockAddrIn p a) =
show a ++ ":" ++ show p
instance Show AddrIn where
show (AddrIn a) =
concat $ intersperse "." $ map show $ BS.unpack a
instance Storable AddrIn where
sizeOf _ = ((4))
alignment _ = (4)
peek ptr =
AddrIn <$> BS.packCStringLen (castPtr ptr, 4)
poke ptr (AddrIn a) =
BS.unsafeUseAsCString a $ \aPtr-> do
copyBytes ptr (castPtr aPtr) (min 4 $ BS.length a)
instance Storable SockAddrIn 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 AddrIn
return (SockAddrIn (fromIntegral ph * 256 + fromIntegral pl) a)
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 (SockAddrIn p a) = 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))