module Hans.Tcp.Message where
import Hans.Lens
import Hans.Tcp.Packet
import Hans.Tcp.Tcb
import qualified Data.ByteString as S
import Data.IORef (readIORef)
mkRst :: TcpHeader -> IO TcpHeader
mkRst TcpHeader { .. } =
return $ set tcpRst True
$ emptyTcpHeader { tcpSourcePort = tcpDestPort
, tcpDestPort = tcpSourcePort
, tcpSeqNum = tcpAckNum
}
mkRstAck :: TcpHeader -> S.ByteString -> IO TcpHeader
mkRstAck hdr @ TcpHeader { .. } payload =
return $ set tcpRst True
$ set tcpAck True
$ emptyTcpHeader { tcpSourcePort = tcpDestPort
, tcpDestPort = tcpSourcePort
, tcpSeqNum = 0
, tcpAckNum = tcpSegNextAckNum hdr (S.length payload)
}
mkSyn :: Tcb -> IO TcpHeader
mkSyn Tcb { .. } =
do iss <- readIORef tcbIss
return $ set tcpSyn True
$ emptyTcpHeader { tcpSourcePort = tcbRemotePort
, tcpDestPort = tcbLocalPort
, tcpSeqNum = iss
, tcpAckNum = 0
}
mkSynAck :: Tcb -> TcpHeader -> IO TcpHeader
mkSynAck Tcb { .. } TcpHeader { .. } =
do iss <- readIORef tcbIss
ack <- getRcvNxt tcbRecvWindow
return $ set tcpSyn True
$ set tcpAck True
$ emptyTcpHeader { tcpSourcePort = tcpDestPort
, tcpDestPort = tcpSourcePort
, tcpSeqNum = iss
, tcpAckNum = ack
}
mkAck :: TcpSeqNum
-> TcpSeqNum
-> TcpPort
-> TcpPort
-> IO TcpHeader
mkAck segSeq segAck local remote =
return $ set tcpAck True
$ emptyTcpHeader { tcpSourcePort = local
, tcpDestPort = remote
, tcpSeqNum = segSeq
, tcpAckNum = segAck
}