This issue is a about how to use the haskell netlink
library.
The casting (?) mechanism I have trouble with might be a more generic haskell problem, which is why I hope it's ok to ask here.
I previously exposed my problem here: https://github.com/Ongy/netlink-hs/issues/5 but here is summary:
I am trying to use the library netlink
(https://github.com/Ongy/netlink-hs, on hackage too) to communicate with a kernel module via the netlink protocol.
I receive packets through the recvOne'
call (called here https://github.com/teto/netlink_pm/blob/v5/hs/daemon.hs#L502):
results <- (recvOne' simpleSock) :: IO [Either String MptcpPacket]
defined here https://github.com/Ongy/netlink-hs/blob/master/System/Linux/Netlink.hs#L395 as:
recvOne' :: (Convertable a, Eq a, Show a) => NetlinkSocket -> IO [Either String (Packet a)]
recvOne' sock = getPackets' <$> recvmsg sock bufferSize
but on launch my program stops immediately with
daemon.hs: user error (Too short input for last message =.=)
My belief is that my recvOne'
call casts everything to a (big) MptcpPacket
type MptcpPacket = Packet GenlData NoDataMptcp
straightaway while the stack can send smaller Packets like ErrorMsg/DoneMsg https://github.com/Ongy/netlink-hs/blob/master/System/Linux/Netlink.hs#L115 :
data Packet a
= Packet -- The "normal" message
{
packetHeader :: Header -- ^The netlink message header
, packetCustom :: a -- ^The datatype for additional static data for the interface
, packetAttributes :: Attributes -- ^The netlink attributes
}
| ErrorMsg -- The error message
{
packetHeader :: Header -- ^The netlink message header
, packetError :: CInt -- ^The error ID for this error message
, errorPacket :: Packet a -- ^The offending message
}
| DoneMsg -- The done message, this should usually not be seen by a user
{
packetHeader :: Header -- ^The header of the done message
}
deriving (Eq)
My question thus becomes: - with this library, how can I retreive all packets and only afterwards distinguish between ErrorMsg / DoneMsg and the valid netlink packets. Haskell forces me to cast to something but it's weird. Should I use some kind of exception ? am I going to lose packets this way ? and so on.
As I am still a haskell beginner, any kind of example/code is welcome