packages feed

mptcp-pm-0.0.4: src/Net/Tcp/Constants.chs

{-# LANGUAGE ForeignFunctionInterface #-}
{-|
Module      : Net.Mptcp.Constants
Description : A module to bridge the haskell code to underlying C code

I consider this module internal.
The documentation may be a bit sparse.
Inspired by:
https://stackoverflow.com/questions/6689969/how-does-one-interface-with-a-c-enum-using-haskell-and-ffi

TODO might be best to just use the netlink script and adapt it
https://github.com/Ongy/netlink-hs/issues/7
-}
module Net.Tcp.Constants
where

import Data.Bits ()
import Data.Word ()
import GHC.Generics (Generic)

-- copy from include/net/tcp_states since it's not part of the user API
#include <tcp_states.h>

-- For anonymous C enums, we can use , Bits
{#enum TCP_ESTABLISHED as TcpState {underscoreToCase} deriving (Eq, Show)#}

-- tcp_ca_state is a bitfield see
-- http://www.yonch.com/tech/linux-tcp-congestion-control-internals
#include <linux/tcp.h>


{#enum TCP_CA_Open as TcpCAState {underscoreToCase} deriving (Eq, Show)#}

-- GenBind.evalCCast: Casts are implemented only for integral constants
-- {#enum define TcpFlag {TCP_FLAG_SYN as TcpFlagSyn} deriving (Eq, Show)#}

data TcpFlag = TcpFlagFin | TcpFlagSyn | TcpFlagRst | TcpFlagPsh
    | TcpFlagAck | TcpFlagUrg | TcpFlagEcn | TcpFlagCwr | TcpFlagNonce
        deriving (Eq, Show, Bounded, Generic)

-- values are power of 2 of the flag
instance Enum TcpFlag where
    toEnum 0 = TcpFlagFin
    toEnum 1 = TcpFlagSyn
    toEnum 2 = TcpFlagRst
    toEnum 3 = TcpFlagPsh
    toEnum 4 = TcpFlagAck
    toEnum 5 = TcpFlagUrg
    toEnum 6 = TcpFlagEcn
    toEnum 7 = TcpFlagCwr
    toEnum 8 = TcpFlagNonce
    toEnum n = error $ "toEnum n: " ++ show n

    fromEnum TcpFlagFin = 0
    fromEnum TcpFlagSyn = 1
    fromEnum TcpFlagRst = 2
    fromEnum TcpFlagPsh = 3
    fromEnum TcpFlagAck = 4
    fromEnum TcpFlagUrg = 5
    fromEnum TcpFlagEcn = 6
    fromEnum TcpFlagCwr = 7
    fromEnum TcpFlagNonce = 8
    -- fromEnum _ = error $ "fromEnum not implemented"

    enumFrom     x   = enumFromTo     x maxBound
    enumFromThen x y = enumFromThenTo x y bound
      where
        bound | fromEnum y >= fromEnum x = maxBound
              | otherwise                = minBound


-- TCP_FLAG_CWR = __constant_cpu_to_be32(0x00800000),
-- TCP_FLAG_ECE = __constant_cpu_to_be32(0x00400000),
-- TCP_FLAG_URG = __constant_cpu_to_be32(0x00200000),
-- TCP_FLAG_ACK = __constant_cpu_to_be32(0x00100000),
-- TCP_FLAG_PSH = __constant_cpu_to_be32(0x00080000),
-- TCP_FLAG_RST = __constant_cpu_to_be32(0x00040000),
-- TCP_FLAG_SYN = __constant_cpu_to_be32(0x00020000),
-- TCP_FLAG_FIN = __constant_cpu_to_be32(0x00010000),

-- #define TH_FIN  0x0001
-- #define TH_SYN  0x0002
-- #define TH_RST  0x0004
-- #define TH_PUSH 0x0008
-- #define TH_ACK  0x0010