    {-# LINE 1 "Network/Socket/Types.hsc" #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LINE 2 "Network/Socket/Types.hsc" #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE ForeignFunctionInterface #-}

    {-# LINE 6 "Network/Socket/Types.hsc" #-}

    module Network.Socket.Types
        (
        -- * Socket
          Socket(..)
        , sockFd
        , sockFamily
        , sockType
        , sockProtocol
        , sockStatus
        , SocketStatus(..)

        -- * Socket types
        , SocketType(..)
        , isSupportedSocketType
        , packSocketType
        , packSocketType'
        , packSocketTypeOrThrow
        , unpackSocketType
        , unpackSocketType'

        -- * Family
        , Family(..)
        , isSupportedFamily
        , packFamily
        , unpackFamily

        -- * Socket addresses
        , SockAddr(..)
        , isSupportedSockAddr
        , HostAddress

    {-# LINE 38 "Network/Socket/Types.hsc" #-}
        , HostAddress6
        , FlowInfo
        , ScopeID

    {-# LINE 42 "Network/Socket/Types.hsc" #-}
        , peekSockAddr
        , pokeSockAddr
        , sizeOfSockAddr
        , sizeOfSockAddrByFamily
        , withSockAddr
        , withNewSockAddr

        -- * Unsorted
        , ProtocolNumber
        , PortNumber(..)

        -- * Low-level helpers
        , zeroMemory
        ) where

    import Control.Concurrent.MVar
    import Control.Monad
    import Data.Bits
    import Data.Maybe
    import Data.Ratio
    import Data.Typeable
    import Data.Word
    import Data.Int
    import Foreign.C
    import Foreign.Marshal.Alloc
    import Foreign.Marshal.Array
    import Foreign.Ptr
    import Foreign.Storable

    -- | Represents a socket.  The fields are, respectively:
    --
    --   * File descriptor
    --   * Socket family
    --   * Socket type
    --   * Protocol number
    --   * Status flag
    --
    --   If you are calling the 'MkSocket' constructor directly you should ensure
    --   you have called 'Network.withSocketsDo'.
    data Socket
      = MkSocket
                CInt                 -- File Descriptor
                Family
                SocketType
                ProtocolNumber       -- Protocol Number
                (MVar SocketStatus)  -- Status Flag
      deriving Typeable

    sockFd :: Socket -> CInt
    sockFd       (MkSocket n _ _ _ _) = n

    sockFamily :: Socket -> Family
    sockFamily   (MkSocket _ f _ _ _) = f

    sockType :: Socket -> SocketType
    sockType     (MkSocket _ _ t _ _) = t

    sockProtocol :: Socket -> ProtocolNumber
    sockProtocol (MkSocket _ _ _ p _) = p

    sockStatus :: Socket -> MVar SocketStatus
    sockStatus   (MkSocket _ _ _ _ s) = s

    instance Eq Socket where
      (MkSocket _ _ _ _ m1) == (MkSocket _ _ _ _ m2) = m1 == m2

    instance Show Socket where
      showsPrec _n (MkSocket fd _ _ _ _) =
            showString "<socket: " . shows fd . showString ">"

    type ProtocolNumber = CInt

    -- | The status of the socket as /determined by this library/, not
    -- necessarily reflecting the state of the connection itself.
    --
    -- For example, the 'Closed' status is applied when the 'close'
    -- function is called.
    data SocketStatus
      -- Returned Status    Function called
      = NotConnected        -- ^ Newly created, unconnected socket
      | Bound               -- ^ Bound, via 'bind'
      | Listening           -- ^ Listening, via 'listen'
      | Connected           -- ^ Connected or accepted, via 'connect' or 'accept'
      | ConvertedToHandle   -- ^ Is now a 'Handle' (via 'socketToHandle'), don't touch
      | Closed              -- ^ Closed was closed by 'close'
        deriving (Eq, Show, Typeable)

    -----------------------------------------------------------------------------
    -- Socket types

    -- There are a few possible ways to do this.  The first is convert the
    -- structs used in the C library into an equivalent Haskell type. An
    -- other possible implementation is to keep all the internals in the C
    -- code and use an Int## and a status flag. The second method is used
    -- here since a lot of the C structures are not required to be
    -- manipulated.

    -- Originally the status was non-mutable so we had to return a new
    -- socket each time we changed the status.  This version now uses
    -- mutable variables to avoid the need to do this.  The result is a
    -- cleaner interface and better security since the application
    -- programmer now can't circumvent the status information to perform
    -- invalid operations on sockets.

    -- | Socket Types.
    --
    -- The existence of a constructor does not necessarily imply that that
    -- socket type is supported on your system: see 'isSupportedSocketType'.
    data SocketType
            = NoSocketType -- ^ 0, used in getAddrInfo hints, for example
            | Stream -- ^ SOCK_STREAM
            | Datagram -- ^ SOCK_DGRAM
            | Raw -- ^ SOCK_RAW
            | RDM -- ^ SOCK_RDM
            | SeqPacket -- ^ SOCK_SEQPACKET
            deriving (Eq, Ord, Read, Show, Typeable)

    -- | Does the SOCK_ constant corresponding to the given SocketType exist on
    -- this system?
    isSupportedSocketType :: SocketType -> Bool
    isSupportedSocketType = isJust . packSocketType'

    -- | Find the SOCK_ constant corresponding to the SocketType value.
    packSocketType' :: SocketType -> Maybe CInt
    packSocketType' stype = case Just stype of
        -- the Just above is to disable GHC's overlapping pattern
        -- detection: see comments for packSocketOption
        Just NoSocketType -> Just 0

    {-# LINE 171 "Network/Socket/Types.hsc" #-}
        Just Stream -> Just 1
    {-# LINE 172 "Network/Socket/Types.hsc" #-}

    {-# LINE 173 "Network/Socket/Types.hsc" #-}

    {-# LINE 174 "Network/Socket/Types.hsc" #-}
        Just Datagram -> Just 2
    {-# LINE 175 "Network/Socket/Types.hsc" #-}

    {-# LINE 176 "Network/Socket/Types.hsc" #-}

    {-# LINE 177 "Network/Socket/Types.hsc" #-}
        Just Raw -> Just 3
    {-# LINE 178 "Network/Socket/Types.hsc" #-}

    {-# LINE 179 "Network/Socket/Types.hsc" #-}

    {-# LINE 180 "Network/Socket/Types.hsc" #-}
        Just RDM -> Just 4
    {-# LINE 181 "Network/Socket/Types.hsc" #-}

    {-# LINE 182 "Network/Socket/Types.hsc" #-}

    {-# LINE 183 "Network/Socket/Types.hsc" #-}
        Just SeqPacket -> Just 5
    {-# LINE 184 "Network/Socket/Types.hsc" #-}

    {-# LINE 185 "Network/Socket/Types.hsc" #-}
        _ -> Nothing

    packSocketType :: SocketType -> CInt
    packSocketType stype = fromMaybe (error errMsg) (packSocketType' stype)
      where
        errMsg = concat ["Network.Socket.packSocketType: ",
                         "socket type ", show stype, " unsupported on this system"]

    -- | Try packSocketType' on the SocketType, if it fails throw an error with
    -- message starting "Network.Socket." ++ the String parameter
    packSocketTypeOrThrow :: String -> SocketType -> IO CInt
    packSocketTypeOrThrow caller stype = maybe err return (packSocketType' stype)
     where
      err = ioError . userError . concat $ ["Network.Socket.", caller, ": ",
        "socket type ", show stype, " unsupported on this system"]

    unpackSocketType:: CInt -> Maybe SocketType
    unpackSocketType t = case t of
            0 -> Just NoSocketType

    {-# LINE 206 "Network/Socket/Types.hsc" #-}
            (1) -> Just Stream
    {-# LINE 207 "Network/Socket/Types.hsc" #-}

    {-# LINE 208 "Network/Socket/Types.hsc" #-}

    {-# LINE 209 "Network/Socket/Types.hsc" #-}
            (2) -> Just Datagram
    {-# LINE 210 "Network/Socket/Types.hsc" #-}

    {-# LINE 211 "Network/Socket/Types.hsc" #-}

    {-# LINE 212 "Network/Socket/Types.hsc" #-}
            (3) -> Just Raw
    {-# LINE 213 "Network/Socket/Types.hsc" #-}

    {-# LINE 214 "Network/Socket/Types.hsc" #-}

    {-# LINE 215 "Network/Socket/Types.hsc" #-}
            (4) -> Just RDM
    {-# LINE 216 "Network/Socket/Types.hsc" #-}

    {-# LINE 217 "Network/Socket/Types.hsc" #-}

    {-# LINE 218 "Network/Socket/Types.hsc" #-}
            (5) -> Just SeqPacket
    {-# LINE 219 "Network/Socket/Types.hsc" #-}

    {-# LINE 220 "Network/Socket/Types.hsc" #-}
            _ -> Nothing

    -- | Try unpackSocketType on the CInt, if it fails throw an error with
    -- message starting "Network.Socket." ++ the String parameter
    unpackSocketType' :: String -> CInt -> IO SocketType
    unpackSocketType' caller ty = maybe err return (unpackSocketType ty)
     where
      err = ioError . userError . concat $ ["Network.Socket.", caller, ": ",
        "socket type ", show ty, " unsupported on this system"]

    ------------------------------------------------------------------------
    -- Protocol Families.

    -- | Address families.
    --
    -- A constructor being present here does not mean it is supported by the
    -- operating system: see 'isSupportedFamily'.
    data Family
        = AF_UNSPEC           -- unspecified
        | AF_UNIX             -- local to host (pipes, portals
        | AF_INET             -- internetwork: UDP, TCP, etc
        | AF_INET6            -- Internet Protocol version 6
        | AF_IMPLINK          -- arpanet imp addresses
        | AF_PUP              -- pup protocols: e.g. BSP
        | AF_CHAOS            -- mit CHAOS protocols
        | AF_NS               -- XEROX NS protocols
        | AF_NBS              -- nbs protocols
        | AF_ECMA             -- european computer manufacturers
        | AF_DATAKIT          -- datakit protocols
        | AF_CCITT            -- CCITT protocols, X.25 etc
        | AF_SNA              -- IBM SNA
        | AF_DECnet           -- DECnet
        | AF_DLI              -- Direct data link interface
        | AF_LAT              -- LAT
        | AF_HYLINK           -- NSC Hyperchannel
        | AF_APPLETALK        -- Apple Talk
        | AF_ROUTE            -- Internal Routing Protocol
        | AF_NETBIOS          -- NetBios-style addresses
        | AF_NIT              -- Network Interface Tap
        | AF_802              -- IEEE 802.2, also ISO 8802
        | AF_ISO              -- ISO protocols
        | AF_OSI              -- umbrella of all families used by OSI
        | AF_NETMAN           -- DNA Network Management
        | AF_X25              -- CCITT X.25
        | AF_AX25
        | AF_OSINET           -- AFI
        | AF_GOSSIP           -- US Government OSI
        | AF_IPX              -- Novell Internet Protocol
        | Pseudo_AF_XTP       -- eXpress Transfer Protocol (no AF)
        | AF_CTF              -- Common Trace Facility
        | AF_WAN              -- Wide Area Network protocols
        | AF_SDL              -- SGI Data Link for DLPI
        | AF_NETWARE
        | AF_NDD
        | AF_INTF             -- Debugging use only
        | AF_COIP             -- connection-oriented IP, aka ST II
        | AF_CNT              -- Computer Network Technology
        | Pseudo_AF_RTIP      -- Help Identify RTIP packets
        | Pseudo_AF_PIP       -- Help Identify PIP packets
        | AF_SIP              -- Simple Internet Protocol
        | AF_ISDN             -- Integrated Services Digital Network
        | Pseudo_AF_KEY       -- Internal key-management function
        | AF_NATM             -- native ATM access
        | AF_ARP              -- (rev.) addr. res. prot. (RFC 826)
        | Pseudo_AF_HDRCMPLT  -- Used by BPF to not rewrite hdrs in iface output
        | AF_ENCAP
        | AF_LINK             -- Link layer interface
        | AF_RAW              -- Link layer interface
        | AF_RIF              -- raw interface
        | AF_NETROM           -- Amateur radio NetROM
        | AF_BRIDGE           -- multiprotocol bridge
        | AF_ATMPVC           -- ATM PVCs
        | AF_ROSE             -- Amateur Radio X.25 PLP
        | AF_NETBEUI          -- 802.2LLC
        | AF_SECURITY         -- Security callback pseudo AF
        | AF_PACKET           -- Packet family
        | AF_ASH              -- Ash
        | AF_ECONET           -- Acorn Econet
        | AF_ATMSVC           -- ATM SVCs
        | AF_IRDA             -- IRDA sockets
        | AF_PPPOX            -- PPPoX sockets
        | AF_WANPIPE          -- Wanpipe API sockets
        | AF_BLUETOOTH        -- bluetooth sockets
        | AF_CAN              -- Controller Area Network
          deriving (Eq, Ord, Read, Show)

    packFamily :: Family -> CInt
    packFamily f = case packFamily' f of
        Just fam -> fam
        Nothing -> error $
                   "Network.Socket.packFamily: unsupported address family: " ++
                   show f

    -- | Does the AF_ constant corresponding to the given family exist on this
    -- system?
    isSupportedFamily :: Family -> Bool
    isSupportedFamily = isJust . packFamily'

    packFamily' :: Family -> Maybe CInt
    packFamily' f = case Just f of
        -- the Just above is to disable GHC's overlapping pattern
        -- detection: see comments for packSocketOption
        Just AF_UNSPEC -> Just 0
    {-# LINE 323 "Network/Socket/Types.hsc" #-}

    {-# LINE 324 "Network/Socket/Types.hsc" #-}
        Just AF_UNIX -> Just 1
    {-# LINE 325 "Network/Socket/Types.hsc" #-}

    {-# LINE 326 "Network/Socket/Types.hsc" #-}

    {-# LINE 327 "Network/Socket/Types.hsc" #-}
        Just AF_INET -> Just 2
    {-# LINE 328 "Network/Socket/Types.hsc" #-}

    {-# LINE 329 "Network/Socket/Types.hsc" #-}

    {-# LINE 330 "Network/Socket/Types.hsc" #-}
        Just AF_INET6 -> Just 10
    {-# LINE 331 "Network/Socket/Types.hsc" #-}

    {-# LINE 332 "Network/Socket/Types.hsc" #-}

    {-# LINE 335 "Network/Socket/Types.hsc" #-}

    {-# LINE 338 "Network/Socket/Types.hsc" #-}

    {-# LINE 341 "Network/Socket/Types.hsc" #-}

    {-# LINE 344 "Network/Socket/Types.hsc" #-}

    {-# LINE 347 "Network/Socket/Types.hsc" #-}

    {-# LINE 350 "Network/Socket/Types.hsc" #-}

    {-# LINE 353 "Network/Socket/Types.hsc" #-}

    {-# LINE 356 "Network/Socket/Types.hsc" #-}

    {-# LINE 357 "Network/Socket/Types.hsc" #-}
        Just AF_SNA -> Just 22
    {-# LINE 358 "Network/Socket/Types.hsc" #-}

    {-# LINE 359 "Network/Socket/Types.hsc" #-}

    {-# LINE 360 "Network/Socket/Types.hsc" #-}
        Just AF_DECnet -> Just 12
    {-# LINE 361 "Network/Socket/Types.hsc" #-}

    {-# LINE 362 "Network/Socket/Types.hsc" #-}

    {-# LINE 365 "Network/Socket/Types.hsc" #-}

    {-# LINE 368 "Network/Socket/Types.hsc" #-}

    {-# LINE 371 "Network/Socket/Types.hsc" #-}

    {-# LINE 372 "Network/Socket/Types.hsc" #-}
        Just AF_APPLETALK -> Just 5
    {-# LINE 373 "Network/Socket/Types.hsc" #-}

    {-# LINE 374 "Network/Socket/Types.hsc" #-}

    {-# LINE 375 "Network/Socket/Types.hsc" #-}
        Just AF_ROUTE -> Just 16
    {-# LINE 376 "Network/Socket/Types.hsc" #-}

    {-# LINE 377 "Network/Socket/Types.hsc" #-}

    {-# LINE 380 "Network/Socket/Types.hsc" #-}

    {-# LINE 383 "Network/Socket/Types.hsc" #-}

    {-# LINE 386 "Network/Socket/Types.hsc" #-}

    {-# LINE 389 "Network/Socket/Types.hsc" #-}

    {-# LINE 392 "Network/Socket/Types.hsc" #-}

    {-# LINE 395 "Network/Socket/Types.hsc" #-}

    {-# LINE 396 "Network/Socket/Types.hsc" #-}
        Just AF_X25 -> Just 9
    {-# LINE 397 "Network/Socket/Types.hsc" #-}

    {-# LINE 398 "Network/Socket/Types.hsc" #-}

    {-# LINE 399 "Network/Socket/Types.hsc" #-}
        Just AF_AX25 -> Just 3
    {-# LINE 400 "Network/Socket/Types.hsc" #-}

    {-# LINE 401 "Network/Socket/Types.hsc" #-}

    {-# LINE 404 "Network/Socket/Types.hsc" #-}

    {-# LINE 407 "Network/Socket/Types.hsc" #-}

    {-# LINE 408 "Network/Socket/Types.hsc" #-}
        Just AF_IPX -> Just 4
    {-# LINE 409 "Network/Socket/Types.hsc" #-}

    {-# LINE 410 "Network/Socket/Types.hsc" #-}

    {-# LINE 413 "Network/Socket/Types.hsc" #-}

    {-# LINE 416 "Network/Socket/Types.hsc" #-}

    {-# LINE 419 "Network/Socket/Types.hsc" #-}

    {-# LINE 422 "Network/Socket/Types.hsc" #-}

    {-# LINE 425 "Network/Socket/Types.hsc" #-}

    {-# LINE 428 "Network/Socket/Types.hsc" #-}

    {-# LINE 431 "Network/Socket/Types.hsc" #-}

    {-# LINE 434 "Network/Socket/Types.hsc" #-}

    {-# LINE 437 "Network/Socket/Types.hsc" #-}

    {-# LINE 440 "Network/Socket/Types.hsc" #-}

    {-# LINE 443 "Network/Socket/Types.hsc" #-}

    {-# LINE 446 "Network/Socket/Types.hsc" #-}

    {-# LINE 447 "Network/Socket/Types.hsc" #-}
        Just AF_ISDN -> Just 34
    {-# LINE 448 "Network/Socket/Types.hsc" #-}

    {-# LINE 449 "Network/Socket/Types.hsc" #-}

    {-# LINE 452 "Network/Socket/Types.hsc" #-}

    {-# LINE 455 "Network/Socket/Types.hsc" #-}

    {-# LINE 458 "Network/Socket/Types.hsc" #-}

    {-# LINE 461 "Network/Socket/Types.hsc" #-}

    {-# LINE 464 "Network/Socket/Types.hsc" #-}

    {-# LINE 467 "Network/Socket/Types.hsc" #-}

    {-# LINE 470 "Network/Socket/Types.hsc" #-}

    {-# LINE 473 "Network/Socket/Types.hsc" #-}

    {-# LINE 474 "Network/Socket/Types.hsc" #-}
        Just AF_NETROM -> Just 6
    {-# LINE 475 "Network/Socket/Types.hsc" #-}

    {-# LINE 476 "Network/Socket/Types.hsc" #-}

    {-# LINE 477 "Network/Socket/Types.hsc" #-}
        Just AF_BRIDGE -> Just 7
    {-# LINE 478 "Network/Socket/Types.hsc" #-}

    {-# LINE 479 "Network/Socket/Types.hsc" #-}

    {-# LINE 480 "Network/Socket/Types.hsc" #-}
        Just AF_ATMPVC -> Just 8
    {-# LINE 481 "Network/Socket/Types.hsc" #-}

    {-# LINE 482 "Network/Socket/Types.hsc" #-}

    {-# LINE 483 "Network/Socket/Types.hsc" #-}
        Just AF_ROSE -> Just 11
    {-# LINE 484 "Network/Socket/Types.hsc" #-}

    {-# LINE 485 "Network/Socket/Types.hsc" #-}

    {-# LINE 486 "Network/Socket/Types.hsc" #-}
        Just AF_NETBEUI -> Just 13
    {-# LINE 487 "Network/Socket/Types.hsc" #-}

    {-# LINE 488 "Network/Socket/Types.hsc" #-}

    {-# LINE 489 "Network/Socket/Types.hsc" #-}
        Just AF_SECURITY -> Just 14
    {-# LINE 490 "Network/Socket/Types.hsc" #-}

    {-# LINE 491 "Network/Socket/Types.hsc" #-}

    {-# LINE 492 "Network/Socket/Types.hsc" #-}
        Just AF_PACKET -> Just 17
    {-# LINE 493 "Network/Socket/Types.hsc" #-}

    {-# LINE 494 "Network/Socket/Types.hsc" #-}

    {-# LINE 495 "Network/Socket/Types.hsc" #-}
        Just AF_ASH -> Just 18
    {-# LINE 496 "Network/Socket/Types.hsc" #-}

    {-# LINE 497 "Network/Socket/Types.hsc" #-}

    {-# LINE 498 "Network/Socket/Types.hsc" #-}
        Just AF_ECONET -> Just 19
    {-# LINE 499 "Network/Socket/Types.hsc" #-}

    {-# LINE 500 "Network/Socket/Types.hsc" #-}

    {-# LINE 501 "Network/Socket/Types.hsc" #-}
        Just AF_ATMSVC -> Just 20
    {-# LINE 502 "Network/Socket/Types.hsc" #-}

    {-# LINE 503 "Network/Socket/Types.hsc" #-}

    {-# LINE 504 "Network/Socket/Types.hsc" #-}
        Just AF_IRDA -> Just 23
    {-# LINE 505 "Network/Socket/Types.hsc" #-}

    {-# LINE 506 "Network/Socket/Types.hsc" #-}

    {-# LINE 507 "Network/Socket/Types.hsc" #-}
        Just AF_PPPOX -> Just 24
    {-# LINE 508 "Network/Socket/Types.hsc" #-}

    {-# LINE 509 "Network/Socket/Types.hsc" #-}

    {-# LINE 510 "Network/Socket/Types.hsc" #-}
        Just AF_WANPIPE -> Just 25
    {-# LINE 511 "Network/Socket/Types.hsc" #-}

    {-# LINE 512 "Network/Socket/Types.hsc" #-}

    {-# LINE 513 "Network/Socket/Types.hsc" #-}
        Just AF_BLUETOOTH -> Just 31
    {-# LINE 514 "Network/Socket/Types.hsc" #-}

    {-# LINE 515 "Network/Socket/Types.hsc" #-}

    {-# LINE 516 "Network/Socket/Types.hsc" #-}
        Just AF_CAN -> Just 29
    {-# LINE 517 "Network/Socket/Types.hsc" #-}

    {-# LINE 518 "Network/Socket/Types.hsc" #-}
        _ -> Nothing

    --------- ----------

    unpackFamily :: CInt -> Family
    unpackFamily f = case f of
            (0) -> AF_UNSPEC
    {-# LINE 525 "Network/Socket/Types.hsc" #-}

    {-# LINE 526 "Network/Socket/Types.hsc" #-}
            (1) -> AF_UNIX
    {-# LINE 527 "Network/Socket/Types.hsc" #-}

    {-# LINE 528 "Network/Socket/Types.hsc" #-}

    {-# LINE 529 "Network/Socket/Types.hsc" #-}
            (2) -> AF_INET
    {-# LINE 530 "Network/Socket/Types.hsc" #-}

    {-# LINE 531 "Network/Socket/Types.hsc" #-}

    {-# LINE 532 "Network/Socket/Types.hsc" #-}
            (10) -> AF_INET6
    {-# LINE 533 "Network/Socket/Types.hsc" #-}

    {-# LINE 534 "Network/Socket/Types.hsc" #-}

    {-# LINE 537 "Network/Socket/Types.hsc" #-}

    {-# LINE 540 "Network/Socket/Types.hsc" #-}

    {-# LINE 543 "Network/Socket/Types.hsc" #-}

    {-# LINE 546 "Network/Socket/Types.hsc" #-}

    {-# LINE 549 "Network/Socket/Types.hsc" #-}

    {-# LINE 552 "Network/Socket/Types.hsc" #-}

    {-# LINE 555 "Network/Socket/Types.hsc" #-}

    {-# LINE 558 "Network/Socket/Types.hsc" #-}

    {-# LINE 559 "Network/Socket/Types.hsc" #-}
            (22) -> AF_SNA
    {-# LINE 560 "Network/Socket/Types.hsc" #-}

    {-# LINE 561 "Network/Socket/Types.hsc" #-}

    {-# LINE 562 "Network/Socket/Types.hsc" #-}
            (12) -> AF_DECnet
    {-# LINE 563 "Network/Socket/Types.hsc" #-}

    {-# LINE 564 "Network/Socket/Types.hsc" #-}

    {-# LINE 567 "Network/Socket/Types.hsc" #-}

    {-# LINE 570 "Network/Socket/Types.hsc" #-}

    {-# LINE 573 "Network/Socket/Types.hsc" #-}

    {-# LINE 574 "Network/Socket/Types.hsc" #-}
            (5) -> AF_APPLETALK
    {-# LINE 575 "Network/Socket/Types.hsc" #-}

    {-# LINE 576 "Network/Socket/Types.hsc" #-}

    {-# LINE 577 "Network/Socket/Types.hsc" #-}
            (16) -> AF_ROUTE
    {-# LINE 578 "Network/Socket/Types.hsc" #-}

    {-# LINE 579 "Network/Socket/Types.hsc" #-}

    {-# LINE 582 "Network/Socket/Types.hsc" #-}

    {-# LINE 585 "Network/Socket/Types.hsc" #-}

    {-# LINE 588 "Network/Socket/Types.hsc" #-}

    {-# LINE 591 "Network/Socket/Types.hsc" #-}

    {-# LINE 596 "Network/Socket/Types.hsc" #-}

    {-# LINE 599 "Network/Socket/Types.hsc" #-}

    {-# LINE 600 "Network/Socket/Types.hsc" #-}
            (9) -> AF_X25
    {-# LINE 601 "Network/Socket/Types.hsc" #-}

    {-# LINE 602 "Network/Socket/Types.hsc" #-}

    {-# LINE 603 "Network/Socket/Types.hsc" #-}
            (3) -> AF_AX25
    {-# LINE 604 "Network/Socket/Types.hsc" #-}

    {-# LINE 605 "Network/Socket/Types.hsc" #-}

    {-# LINE 608 "Network/Socket/Types.hsc" #-}

    {-# LINE 611 "Network/Socket/Types.hsc" #-}

    {-# LINE 612 "Network/Socket/Types.hsc" #-}
            (4) -> AF_IPX
    {-# LINE 613 "Network/Socket/Types.hsc" #-}

    {-# LINE 614 "Network/Socket/Types.hsc" #-}

    {-# LINE 617 "Network/Socket/Types.hsc" #-}

    {-# LINE 620 "Network/Socket/Types.hsc" #-}

    {-# LINE 623 "Network/Socket/Types.hsc" #-}

    {-# LINE 626 "Network/Socket/Types.hsc" #-}

    {-# LINE 629 "Network/Socket/Types.hsc" #-}

    {-# LINE 632 "Network/Socket/Types.hsc" #-}

    {-# LINE 635 "Network/Socket/Types.hsc" #-}

    {-# LINE 638 "Network/Socket/Types.hsc" #-}

    {-# LINE 641 "Network/Socket/Types.hsc" #-}

    {-# LINE 644 "Network/Socket/Types.hsc" #-}

    {-# LINE 647 "Network/Socket/Types.hsc" #-}

    {-# LINE 650 "Network/Socket/Types.hsc" #-}

    {-# LINE 651 "Network/Socket/Types.hsc" #-}
            (34) -> AF_ISDN
    {-# LINE 652 "Network/Socket/Types.hsc" #-}

    {-# LINE 653 "Network/Socket/Types.hsc" #-}

    {-# LINE 656 "Network/Socket/Types.hsc" #-}

    {-# LINE 659 "Network/Socket/Types.hsc" #-}

    {-# LINE 662 "Network/Socket/Types.hsc" #-}

    {-# LINE 665 "Network/Socket/Types.hsc" #-}

    {-# LINE 668 "Network/Socket/Types.hsc" #-}

    {-# LINE 671 "Network/Socket/Types.hsc" #-}

    {-# LINE 674 "Network/Socket/Types.hsc" #-}

    {-# LINE 677 "Network/Socket/Types.hsc" #-}

    {-# LINE 678 "Network/Socket/Types.hsc" #-}
            (6) -> AF_NETROM
    {-# LINE 679 "Network/Socket/Types.hsc" #-}

    {-# LINE 680 "Network/Socket/Types.hsc" #-}

    {-# LINE 681 "Network/Socket/Types.hsc" #-}
            (7) -> AF_BRIDGE
    {-# LINE 682 "Network/Socket/Types.hsc" #-}

    {-# LINE 683 "Network/Socket/Types.hsc" #-}

    {-# LINE 684 "Network/Socket/Types.hsc" #-}
            (8) -> AF_ATMPVC
    {-# LINE 685 "Network/Socket/Types.hsc" #-}

    {-# LINE 686 "Network/Socket/Types.hsc" #-}

    {-# LINE 687 "Network/Socket/Types.hsc" #-}
            (11) -> AF_ROSE
    {-# LINE 688 "Network/Socket/Types.hsc" #-}

    {-# LINE 689 "Network/Socket/Types.hsc" #-}

    {-# LINE 690 "Network/Socket/Types.hsc" #-}
            (13) -> AF_NETBEUI
    {-# LINE 691 "Network/Socket/Types.hsc" #-}

    {-# LINE 692 "Network/Socket/Types.hsc" #-}

    {-# LINE 693 "Network/Socket/Types.hsc" #-}
            (14) -> AF_SECURITY
    {-# LINE 694 "Network/Socket/Types.hsc" #-}

    {-# LINE 695 "Network/Socket/Types.hsc" #-}

    {-# LINE 696 "Network/Socket/Types.hsc" #-}
            (17) -> AF_PACKET
    {-# LINE 697 "Network/Socket/Types.hsc" #-}

    {-# LINE 698 "Network/Socket/Types.hsc" #-}

    {-# LINE 699 "Network/Socket/Types.hsc" #-}
            (18) -> AF_ASH
    {-# LINE 700 "Network/Socket/Types.hsc" #-}

    {-# LINE 701 "Network/Socket/Types.hsc" #-}

    {-# LINE 702 "Network/Socket/Types.hsc" #-}
            (19) -> AF_ECONET
    {-# LINE 703 "Network/Socket/Types.hsc" #-}

    {-# LINE 704 "Network/Socket/Types.hsc" #-}

    {-# LINE 705 "Network/Socket/Types.hsc" #-}
            (20) -> AF_ATMSVC
    {-# LINE 706 "Network/Socket/Types.hsc" #-}

    {-# LINE 707 "Network/Socket/Types.hsc" #-}

    {-# LINE 708 "Network/Socket/Types.hsc" #-}
            (23) -> AF_IRDA
    {-# LINE 709 "Network/Socket/Types.hsc" #-}

    {-# LINE 710 "Network/Socket/Types.hsc" #-}

    {-# LINE 711 "Network/Socket/Types.hsc" #-}
            (24) -> AF_PPPOX
    {-# LINE 712 "Network/Socket/Types.hsc" #-}

    {-# LINE 713 "Network/Socket/Types.hsc" #-}

    {-# LINE 714 "Network/Socket/Types.hsc" #-}
            (25) -> AF_WANPIPE
    {-# LINE 715 "Network/Socket/Types.hsc" #-}

    {-# LINE 716 "Network/Socket/Types.hsc" #-}

    {-# LINE 717 "Network/Socket/Types.hsc" #-}
            (31) -> AF_BLUETOOTH
    {-# LINE 718 "Network/Socket/Types.hsc" #-}

    {-# LINE 719 "Network/Socket/Types.hsc" #-}

    {-# LINE 720 "Network/Socket/Types.hsc" #-}
            (29) -> AF_CAN
    {-# LINE 721 "Network/Socket/Types.hsc" #-}

    {-# LINE 722 "Network/Socket/Types.hsc" #-}
            unknown -> error ("Network.Socket.unpackFamily: unknown address " ++
                              "family " ++ show unknown)

    ------------------------------------------------------------------------
    -- Port Numbers

    -- | Use the @Num@ instance (i.e. use a literal) to create a
    -- @PortNumber@ value with the correct network-byte-ordering. You
    -- should not use the PortNum constructor. It will be removed in the
    -- next release.
    newtype PortNumber = PortNum Word16 deriving (Eq, Ord, Typeable)
    -- newtyped to prevent accidental use of sane-looking
    -- port numbers that haven't actually been converted to
    -- network-byte-order first.

    {-# DEPRECATED PortNum "Do not use the PortNum constructor. Use the Num instance. PortNum will be removed in the next release." #-}

    instance Show PortNumber where
      showsPrec p pn = showsPrec p (portNumberToInt pn)

    intToPortNumber :: Int -> PortNumber
    intToPortNumber v = PortNum (htons (fromIntegral v))

    portNumberToInt :: PortNumber -> Int
    portNumberToInt (PortNum po) = fromIntegral (ntohs po)

    foreign import CALLCONV unsafe "ntohs" ntohs :: Word16 -> Word16
    foreign import CALLCONV unsafe "htons" htons :: Word16 -> Word16
    --foreign import CALLCONV unsafe "ntohl" ntohl :: Word32 -> Word32

    instance Enum PortNumber where
        toEnum   = intToPortNumber
        fromEnum = portNumberToInt

    instance Num PortNumber where
       fromInteger i = intToPortNumber (fromInteger i)
        -- for completeness.
       (+) x y   = intToPortNumber (portNumberToInt x + portNumberToInt y)
       (-) x y   = intToPortNumber (portNumberToInt x - portNumberToInt y)
       negate x  = intToPortNumber (-portNumberToInt x)
       (*) x y   = intToPortNumber (portNumberToInt x * portNumberToInt y)
       abs n     = intToPortNumber (abs (portNumberToInt n))
       signum n  = intToPortNumber (signum (portNumberToInt n))

    instance Real PortNumber where
        toRational x = toInteger x % 1

    instance Integral PortNumber where
        quotRem a b = let (c,d) = quotRem (portNumberToInt a) (portNumberToInt b) in
                      (intToPortNumber c, intToPortNumber d)
        toInteger a = toInteger (portNumberToInt a)

    instance Storable PortNumber where
       sizeOf    _ = sizeOf    (undefined :: Word16)
       alignment _ = alignment (undefined :: Word16)
       poke p (PortNum po) = poke (castPtr p) po
       peek p = PortNum `liftM` peek (castPtr p)

    ------------------------------------------------------------------------
    -- Socket addresses

    -- The scheme used for addressing sockets is somewhat quirky. The
    -- calls in the BSD socket API that need to know the socket address
    -- all operate in terms of struct sockaddr, a `virtual' type of
    -- socket address.

    -- The Internet family of sockets are addressed as struct sockaddr_in,
    -- so when calling functions that operate on struct sockaddr, we have
    -- to type cast the Internet socket address into a struct sockaddr.
    -- Instances of the structure for different families might *not* be
    -- the same size. Same casting is required of other families of
    -- sockets such as Xerox NS. Similarly for Unix domain sockets.

    -- To represent these socket addresses in Haskell-land, we do what BSD
    -- didn't do, and use a union/algebraic type for the different
    -- families. Currently only Unix domain sockets and the Internet
    -- families are supported.

    {-# LINE 801 "Network/Socket/Types.hsc" #-}
    type FlowInfo = Word32
    type ScopeID = Word32

    {-# LINE 804 "Network/Socket/Types.hsc" #-}

    -- | The existence of a constructor does not necessarily imply that
    -- that socket address type is supported on your system: see
    -- 'isSupportedSockAddr'.
    data SockAddr       -- C Names
      = SockAddrInet
        PortNumber  -- sin_port  (network byte order)
        HostAddress -- sin_addr  (ditto)
      | SockAddrInet6
            PortNumber      -- sin6_port (network byte order)
            FlowInfo        -- sin6_flowinfo (ditto)
            HostAddress6    -- sin6_addr (ditto)
            ScopeID         -- sin6_scope_id (ditto)
      | SockAddrUnix
            String          -- sun_path
      | SockAddrCan
            Int32           -- can_ifindex (can be get by Network.BSD.ifNameToIndex "can0")
            -- TODO: Extend this to include transport protocol information
      deriving (Eq, Ord, Typeable)

    -- | Is the socket address type supported on this system?
    isSupportedSockAddr :: SockAddr -> Bool
    isSupportedSockAddr addr = case addr of
      SockAddrInet {} -> True

    {-# LINE 829 "Network/Socket/Types.hsc" #-}
      SockAddrInet6 {} -> True

    {-# LINE 831 "Network/Socket/Types.hsc" #-}

    {-# LINE 832 "Network/Socket/Types.hsc" #-}
      SockAddrUnix{} -> True

    {-# LINE 834 "Network/Socket/Types.hsc" #-}

    {-# LINE 835 "Network/Socket/Types.hsc" #-}
      SockAddrCan{} -> True

    {-# LINE 837 "Network/Socket/Types.hsc" #-}
      _ -> False

    {-# LINE 844 "Network/Socket/Types.hsc" #-}
    type CSaFamily = (Word16)
    {-# LINE 845 "Network/Socket/Types.hsc" #-}

    {-# LINE 846 "Network/Socket/Types.hsc" #-}

    -- | Computes the storage requirements (in bytes) of the given
    -- 'SockAddr'.  This function differs from 'Foreign.Storable.sizeOf'
    -- in that the value of the argument /is/ used.
    sizeOfSockAddr :: SockAddr -> Int

    {-# LINE 852 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddr (SockAddrUnix path) =
        case path of
            '\0':_ -> (2) + length path
    {-# LINE 855 "Network/Socket/Types.hsc" #-}
            _      -> 110
    {-# LINE 856 "Network/Socket/Types.hsc" #-}

    {-# LINE 857 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddr (SockAddrInet _ _) = 16
    {-# LINE 858 "Network/Socket/Types.hsc" #-}

    {-# LINE 859 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddr (SockAddrInet6 _ _ _ _) = 28
    {-# LINE 860 "Network/Socket/Types.hsc" #-}

    {-# LINE 861 "Network/Socket/Types.hsc" #-}

    {-# LINE 862 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddr (SockAddrCan _) = 16
    {-# LINE 863 "Network/Socket/Types.hsc" #-}

    {-# LINE 864 "Network/Socket/Types.hsc" #-}

    -- | Computes the storage requirements (in bytes) required for a
    -- 'SockAddr' with the given 'Family'.
    sizeOfSockAddrByFamily :: Family -> Int

    {-# LINE 869 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddrByFamily AF_UNIX  = 110
    {-# LINE 870 "Network/Socket/Types.hsc" #-}

    {-# LINE 871 "Network/Socket/Types.hsc" #-}

    {-# LINE 872 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddrByFamily AF_INET6 = 28
    {-# LINE 873 "Network/Socket/Types.hsc" #-}

    {-# LINE 874 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddrByFamily AF_INET  = 16
    {-# LINE 875 "Network/Socket/Types.hsc" #-}

    {-# LINE 876 "Network/Socket/Types.hsc" #-}
    sizeOfSockAddrByFamily AF_CAN   = 16
    {-# LINE 877 "Network/Socket/Types.hsc" #-}

    {-# LINE 878 "Network/Socket/Types.hsc" #-}

    -- | Use a 'SockAddr' with a function requiring a pointer to a
    -- 'SockAddr' and the length of that 'SockAddr'.
    withSockAddr :: SockAddr -> (Ptr SockAddr -> Int -> IO a) -> IO a
    withSockAddr addr f = do
        let sz = sizeOfSockAddr addr
        allocaBytes sz $ \p -> pokeSockAddr p addr >> f (castPtr p) sz

    -- | Create a new 'SockAddr' for use with a function requiring a
    -- pointer to a 'SockAddr' and the length of that 'SockAddr'.
    withNewSockAddr :: Family -> (Ptr SockAddr -> Int -> IO a) -> IO a
    withNewSockAddr family f = do
        let sz = sizeOfSockAddrByFamily family
        allocaBytes sz $ \ptr -> f ptr sz

    -- We can't write an instance of 'Storable' for 'SockAddr' because
    -- @sockaddr@ is a sum type of variable size but
    -- 'Foreign.Storable.sizeOf' is required to be constant.

    -- Note that on Darwin, the sockaddr structure must be zeroed before
    -- use.

    -- | Write the given 'SockAddr' to the given memory location.
    pokeSockAddr :: Ptr a -> SockAddr -> IO ()

    {-# LINE 903 "Network/Socket/Types.hsc" #-}
    pokeSockAddr p (SockAddrUnix path) = do

    {-# LINE 907 "Network/Socket/Types.hsc" #-}

    {-# LINE 910 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p ((1) :: CSaFamily)
    {-# LINE 911 "Network/Socket/Types.hsc" #-}
        let pathC = map castCharToCChar path
            poker = case path of ('\0':_) -> pokeArray; _ -> pokeArray0 0
        poker (((\hsc_ptr -> hsc_ptr `plusPtr` 2)) p) pathC
    {-# LINE 914 "Network/Socket/Types.hsc" #-}

    {-# LINE 915 "Network/Socket/Types.hsc" #-}
    pokeSockAddr p (SockAddrInet (PortNum port) addr) = do

    {-# LINE 919 "Network/Socket/Types.hsc" #-}

    {-# LINE 922 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p ((2) :: CSaFamily)
    {-# LINE 923 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) p port
    {-# LINE 924 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) p addr
    {-# LINE 925 "Network/Socket/Types.hsc" #-}

    {-# LINE 926 "Network/Socket/Types.hsc" #-}
    pokeSockAddr p (SockAddrInet6 (PortNum port) flow addr scope) = do

    {-# LINE 930 "Network/Socket/Types.hsc" #-}

    {-# LINE 933 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p ((10) :: CSaFamily)
    {-# LINE 934 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) p port
    {-# LINE 935 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) p flow
    {-# LINE 936 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p addr
    {-# LINE 937 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) p scope
    {-# LINE 938 "Network/Socket/Types.hsc" #-}

    {-# LINE 939 "Network/Socket/Types.hsc" #-}

    {-# LINE 940 "Network/Socket/Types.hsc" #-}
    pokeSockAddr p (SockAddrCan ifIndex) = do

    {-# LINE 944 "Network/Socket/Types.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) p ifIndex
    {-# LINE 945 "Network/Socket/Types.hsc" #-}

    {-# LINE 946 "Network/Socket/Types.hsc" #-}

    -- | Read a 'SockAddr' from the given memory location.
    peekSockAddr :: Ptr SockAddr -> IO SockAddr
    peekSockAddr p = do
      family <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
    {-# LINE 951 "Network/Socket/Types.hsc" #-}
      case family :: CSaFamily of

    {-# LINE 953 "Network/Socket/Types.hsc" #-}
        (1) -> do
    {-# LINE 954 "Network/Socket/Types.hsc" #-}
            str <- peekCString (((\hsc_ptr -> hsc_ptr `plusPtr` 2)) p)
    {-# LINE 955 "Network/Socket/Types.hsc" #-}
            return (SockAddrUnix str)

    {-# LINE 957 "Network/Socket/Types.hsc" #-}
        (2) -> do
    {-# LINE 958 "Network/Socket/Types.hsc" #-}
            addr <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
    {-# LINE 959 "Network/Socket/Types.hsc" #-}
            port <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) p
    {-# LINE 960 "Network/Socket/Types.hsc" #-}
            return (SockAddrInet (PortNum port) addr)

    {-# LINE 962 "Network/Socket/Types.hsc" #-}
        (10) -> do
    {-# LINE 963 "Network/Socket/Types.hsc" #-}
            port <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) p
    {-# LINE 964 "Network/Socket/Types.hsc" #-}
            flow <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
    {-# LINE 965 "Network/Socket/Types.hsc" #-}
            addr <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
    {-# LINE 966 "Network/Socket/Types.hsc" #-}
            scope <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) p
    {-# LINE 967 "Network/Socket/Types.hsc" #-}
            return (SockAddrInet6 (PortNum port) flow addr scope)

    {-# LINE 969 "Network/Socket/Types.hsc" #-}

    {-# LINE 970 "Network/Socket/Types.hsc" #-}
        (29) -> do
    {-# LINE 971 "Network/Socket/Types.hsc" #-}
            ifidx <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
    {-# LINE 972 "Network/Socket/Types.hsc" #-}
            return (SockAddrCan ifidx)

    {-# LINE 974 "Network/Socket/Types.hsc" #-}

    ------------------------------------------------------------------------

    -- | Network byte order.
    type HostAddress = Word32

    {-# LINE 981 "Network/Socket/Types.hsc" #-}
    -- | Host byte order.
    type HostAddress6 = (Word32, Word32, Word32, Word32)

    -- The peek32 and poke32 functions work around the fact that the RFCs
    -- don't require 32-bit-wide address fields to be present.  We can
    -- only portably rely on an 8-bit field, s6_addr.

    s6_addr_offset :: Int
    s6_addr_offset = ((0))
    {-# LINE 990 "Network/Socket/Types.hsc" #-}

    peek32 :: Ptr a -> Int -> IO Word32
    peek32 p i0 = do
        let i' = i0 * 4
            peekByte n = peekByteOff p (s6_addr_offset + i' + n) :: IO Word8
            a `sl` i = fromIntegral a `shiftL` i
        a0 <- peekByte 0
        a1 <- peekByte 1
        a2 <- peekByte 2
        a3 <- peekByte 3
        return ((a0 `sl` 24) .|. (a1 `sl` 16) .|. (a2 `sl` 8) .|. (a3 `sl` 0))

    poke32 :: Ptr a -> Int -> Word32 -> IO ()
    poke32 p i0 a = do
        let i' = i0 * 4
            pokeByte n = pokeByteOff p (s6_addr_offset + i' + n)
            x `sr` i = fromIntegral (x `shiftR` i) :: Word8
        pokeByte 0 (a `sr` 24)
        pokeByte 1 (a `sr` 16)
        pokeByte 2 (a `sr`  8)
        pokeByte 3 (a `sr`  0)

    instance Storable HostAddress6 where
        sizeOf _    = (16)
    {-# LINE 1014 "Network/Socket/Types.hsc" #-}
        alignment _ = alignment (undefined :: CInt)

        peek p = do
            a <- peek32 p 0
            b <- peek32 p 1
            c <- peek32 p 2
            d <- peek32 p 3
            return (a, b, c, d)

        poke p (a, b, c, d) = do
            poke32 p 0 a
            poke32 p 1 b
            poke32 p 2 c
            poke32 p 3 d

    {-# LINE 1029 "Network/Socket/Types.hsc" #-}

    ------------------------------------------------------------------------
    -- Helper functions

    foreign import ccall unsafe "string.h" memset :: Ptr a -> CInt -> CSize -> IO ()

    -- | Zero a structure.
    zeroMemory :: Ptr a -> CSize -> IO ()
    zeroMemory dest nbytes = memset dest 0 (fromIntegral nbytes)