packages feed

rws-0.1.1.2: src/Packet.hs

module Packet where

import Data.Binary.Put
import Data.Bits
import qualified Data.ByteString.Lazy as B
import Data.Word
import Text.Printf

class PayloadCarrier a where
  payloadCarried :: a -> [Packet]

class PacketWriteable a where
  packetWrite :: a -> Maybe Packet -> B.ByteString -> Put

data MacAddress = MacAddress {
  macAddress0 :: Word8,
  macAddress1 :: Word8,
  macAddress2 :: Word8,
  macAddress3 :: Word8,
  macAddress4 :: Word8,
  macAddress5 :: Word8
} deriving Eq

instance Show MacAddress where show = showMacAddress
showMacAddress :: MacAddress -> String
showMacAddress a = printf "%02x:%02x:%02x:%02x:%02x:%02x" (macAddress0 a) (macAddress1 a)
  (macAddress2 a) (macAddress3 a) (macAddress4 a) (macAddress5 a)  

data Ethernet = Ethernet {
  ethernetDst :: MacAddress,
  ethernetSrc :: MacAddress,
  ethernetType :: Word16
} deriving (Show,Eq)

data EthernetFrame = EthernetFrame {
 ethernFrameHeader :: Ethernet,
 ethernPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier EthernetFrame where payloadCarried = ethernPayload

defaultEthernet :: Ethernet
defaultEthernet = Ethernet (MacAddress 0 0 0 0 0 1) 
                            (MacAddress 0 0 0 0 0 2)
                            0x800
defaultEthernetFrame :: EthernetFrame
defaultEthernetFrame = EthernetFrame defaultEthernet
                        [PPayload defaultPayload]

data IPv6Addr = IPv6Addr {
             ipv6Addr0 :: !Word32,
             ipv6Addr1 :: !Word32,
             ipv6Addr2 :: !Word32,
             ipv6Addr3 :: !Word32
} deriving Eq

instance Show IPv6Addr where show = showIPv6Addr
showIPv6Addr :: IPv6Addr -> String
showIPv6Addr a = printf "0x%04x:0x%04x:0x%04x:0x%04x:0x%04x:0x%04x:0x%04x:0x%04x"
  (ipv6Addr0 a `shiftR` 16) (ipv6Addr0 a .&. 0xffff)
  (ipv6Addr1 a `shiftR` 16) (ipv6Addr1 a .&. 0xffff)
  (ipv6Addr2 a `shiftR` 16) (ipv6Addr2 a .&. 0xffff)
  (ipv6Addr3 a `shiftR` 16) (ipv6Addr3 a .&. 0xffff)

data IPv6 = IPv6 {
    ipv6Ver          :: !Word8,
    ipv6Tcl          :: !Word8,
    ipv6Flow         :: !Word32,
    ipv6Length       :: !Word16,
    ipv6Nh           :: !Word8,
    ipv6Hl           :: !Word8,
    ipv6Src          :: !IPv6Addr,
    ipv6Dst          :: !IPv6Addr
} deriving (Show,Eq)

data IPv6Pkt = IPv6Pkt {
  ipv6PktHeader :: IPv6,
  ipv6PktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier IPv6Pkt where payloadCarried = ipv6PktPayload

defaultIPv6 :: IPv6
defaultIPv6 = IPv6 6 0 0 0 17 64 (IPv6Addr 0x2001000 0 0 1) (IPv6Addr 0x2001000 0 0 2)
defaultIPv6Packet :: IPv6Pkt
defaultIPv6Packet = IPv6Pkt defaultIPv6 [PPayload $ Payload 0 0]



data IPv4 = IPv4 {
  ipv4Ver    :: !Word8,
  ipv4Hlen   :: !Word8,
  ipv4Tos    :: !Word8,
  ipv4Len    :: !Word16,
  ipv4Id     :: !Word16,
  ipv4Offset :: !Word16,
  ipv4Ttl    :: !Word8,
  ipv4Prot   :: !Word8,
  ipv4Csum   :: !Word16,
  ipv4Src    :: !Word32,
  ipv4Dst    :: !Word32,
  ipv4CorrectCsum :: Bool
} deriving (Show,Eq)

defaultIPv4 :: IPv4
defaultIPv4 = IPv4 4 5 0 0 0x1234 0 64 17 0 0xa0a0a0a1 0xa0a0a0a2 True
defaultIPv4Packet :: IPv4Pkt
defaultIPv4Packet = IPv4Pkt defaultIPv4 [PPayload defaultPayload]

data IPv4Pkt = IPv4Pkt {
  ipv4PktHeader :: IPv4,
  ipv4PktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier IPv4Pkt where payloadCarried = ipv4PktPayload

data Udp = Udp {
  udpSrc :: !Word16,
  udpDst :: !Word16,
  udpLen :: !Word16,
  udpCsum :: !Word16,
  udpCorrectCsum :: Bool
} deriving (Show,Eq)

data UdpPkt = UdpPkt {
  udpPktHeader :: Udp,
  udpPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier UdpPkt where payloadCarried = udpPktPayload

defaultUdp :: Udp
defaultUdp = Udp 7 7 8 0 True
defaultUdpPacket :: UdpPkt
defaultUdpPacket = UdpPkt defaultUdp [PPayload defaultPayload]

data Tcp = Tcp {
    tcpSrc :: !Word16,
    tcpDst :: !Word16,
    tcpSeqNo :: !Word32,
    tcpAckNo :: !Word32,
    tcpFlags :: !Word16,
    tcpWin :: !Word16,
    tcpCsum :: !Word16,
    tcpUrg :: !Word16,
    tcpOffset :: !Word8,
    tcpCorrectCsum :: Bool,
    tcpWindowScale :: !Word8,
    tcpTimeStamp :: !Word64
    -- options
} deriving (Show,Eq)

defaultTcp :: Tcp
defaultTcp = Tcp 7 7 0 0 0x5000 0xffff 0 0 20 True 0 0
defaultTcpPacket :: TcpPkt
defaultTcpPacket = TcpPkt defaultTcp [PPayload $ Payload 0 0]



data TcpPkt = TcpPkt {
    tcpPktHeader :: Tcp,
    tcpPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier TcpPkt where payloadCarried = tcpPktPayload

data Gtp = Gtp {
  gtpFlags :: !Word8,
  gtpType :: !Word8,
  gtpLen :: !Word16,
  gtpTeid :: !Word32,
  gtpSeq :: !Word16,
  gtpNpdu :: !Word8,
  gtpNh :: !Word8
} deriving (Show,Eq)

defaultGtp :: Gtp
defaultGtp = Gtp 0x32 0xff 0 0x012345678 0 0 0
defaultGtpPacket :: GtpPkt
defaultGtpPacket = GtpPkt defaultGtp [PPayload defaultPayload]


data GtpPkt = GtpPkt {
  gtpPktHeader :: Gtp,
  gtpPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier GtpPkt where payloadCarried = gtpPktPayload

data Ppp = Ppp {
    pppAddress :: !Word8,
    pppControl :: !Word8,
    pppProtocol :: !Word16
} deriving (Show,Eq)

data PppPkt = PppPkt {
  pppPktHeader :: Ppp,
  pppPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier PppPkt where payloadCarried = pppPktPayload

defaultPpp :: Ppp
defaultPpp = Ppp 0xff 0x03 0x0021
defaultPppPacket :: PppPkt
defaultPppPacket = PppPkt defaultPpp [PPayload $ Payload 0 0]

data L2tp = L2tp {
    l2tpFlags :: !Word16,
    l2tpLength :: !Word16,
    l2tpTid :: !Word16,
    l2tpSid :: !Word16,
    l2tpNs :: !Word16,
    l2tpNr :: !Word16,
    l2tpOffset :: !Word16,
    l2tpCorrectOffset :: Bool
} deriving (Show,Eq)

data L2tpPkt = L2tpPkt {
  l2tpPktHeader :: L2tp,
  l2tpPktPayload :: [Packet]
} deriving (Show,Eq)

defaultL2tp :: L2tp
defaultL2tp = L2tp 0x2 0 0x1234 0x5678 0 0 0 True
defaultL2tpPacket :: L2tpPkt
defaultL2tpPacket = L2tpPkt defaultL2tp [PPayload $ Payload 0 0]

instance PayloadCarrier L2tpPkt where payloadCarried = l2tpPktPayload

data Gre = Gre {
    greFlags :: !Word16,
    greProtocol :: !Word16,
    greKey :: !Word32,
    greSeq :: !Word32
} deriving (Show,Eq)

data GrePkt = GrePkt {
    grePktHeader :: Gre,
    grePktPayload :: [Packet]
} deriving (Show,Eq)

defaultGre :: Gre
defaultGre = Gre 0x3000 0x0800 0xcafecafe 0
defaultGrePacket :: GrePkt
defaultGrePacket = GrePkt defaultGre [PPayload $ Payload 0 0]

instance PayloadCarrier GrePkt where payloadCarried = grePktPayload

data Icmp = Icmp {
    icmpType :: !Word8,
    icmpCode :: !Word8,
    icmpCsum :: !Word16,
    icmpId :: !Word16,
    icmpSeq :: !Word16,
    icmpCorrectCsum :: Bool
} deriving (Show,Eq)

defaultIcmp :: Icmp
defaultIcmp = Icmp 8 0 0 0xcafe 1 True
defaultIcmpPacket :: IcmpPkt
defaultIcmpPacket = IcmpPkt defaultIcmp [PPayload $ Payload 0 0]

data IcmpPkt = IcmpPkt {
    icmpPktHeader :: Icmp,
    icmpPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier IcmpPkt where payloadCarried = icmpPktPayload

data IcmpV6 = IcmpV6 {
    icmpV6Type :: !Word8,
    icmpV6Code :: !Word8,
    icmpV6Csum :: !Word16,
    icmpV6Pad  :: !Word32,
    icmpV6CorrectCsum :: Bool
} deriving (Show,Eq)

defaultIcmpV6 :: IcmpV6
defaultIcmpV6 = IcmpV6 8 0 0 0xffffffff True
defaultIcmpV6Packet :: IcmpV6Pkt
defaultIcmpV6Packet = IcmpV6Pkt defaultIcmpV6 [PPayload $ Payload 0 0]

data IcmpV6Pkt = IcmpV6Pkt {
    icmpV6PktHeader :: IcmpV6,
    icmpV6PktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier IcmpV6Pkt where payloadCarried = icmpV6PktPayload

data Teredo = Teredo {
    teredoOrgTag :: !Word16,
    teredoOrgPort :: !Word16,
    teredoAddr :: !Word32,
    teredoAuthTag :: !Word16,
    teredoAuthIdLen :: !Word8,
    teredoAuthAuLen :: !Word8,
    teredoHaveOrg :: Bool,
    teredoHaveAuth :: Bool,
    teredoFixSrc :: Bool,
    teredoFixDst :: Bool
} deriving (Show,Eq)

defaultTeredo :: Teredo
defaultTeredo = Teredo 0 0 0 0 0 0 False False True True
defaultTeredoPacket :: TeredoPkt
defaultTeredoPacket = TeredoPkt defaultTeredo $ PPayload $ Payload 0 0

data TeredoPkt = TeredoPkt {
    teredoPktHeader :: Teredo,
    teredoPktPayload :: Packet
} deriving (Show,Eq)

data EngineId = EngineId {
  eid0 :: Word8,
  eid1 :: Word8,
  eid2 :: Word8,
  eid3 :: Word8,
  eid4 :: Word8,
  eid5 :: Word8
} deriving (Show,Eq)

data ConnSync = ConnSync {
    connSyncVer :: !Word32,
    connSyncArmcs :: !Word32,
    connSyncDst :: !Word32,
    connSyncSrc :: !Word32,
    connSyncType :: !Word8,
    connSyncExtVer :: !Word8,
    connSyncExtEid :: !EngineId,
    connSyncId :: !Word32
} deriving (Show,Eq)

data ConnSyncPkt = ConnSyncPkt {
    connSyncPktHeader :: ConnSync,
    connSyncPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier ConnSyncPkt where payloadCarried = connSyncPktPayload

data ConnSyncSeen = ConnSyncSeen {
    connSyncSeenPcid :: !Word32,
    connSyncSeenPeid :: !EngineId,
    connSyncSeenHasFsService :: !Word8,
    connSyncSeenCtype :: !Word8,
    connSyncSeenBaseService :: !Word32,
    connSyncSeenFsService :: !Word32
} deriving (Show,Eq)

data ConnSyncSeenPkt = ConnSyncSeenPkt {
    connSyncSeenPktHeader :: ConnSyncSeen,
    connSyncSeenPktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier ConnSyncSeenPkt where payloadCarried = connSyncSeenPktPayload

data ConnSyncIpv4 = ConnSyncIpv4 {
    connSyncIpv4Int :: !Word32,
    connSyncIpv4Ext :: !Word32,
    connSyncIpv4IntPort :: !Word16,
    connSyncIpv4ExtPort :: !Word16,
    connSyncIpv4Prot :: !Word32
} deriving (Show,Eq)

data ConnSyncIpv4Pkt = ConnSyncIpv4Pkt {
    connSyncIpv4PktHeader :: ConnSyncIpv4,
    connSyncIpv4PktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier ConnSyncIpv4Pkt where payloadCarried = connSyncIpv4PktPayload

data ConnSyncUpdate = ConnSyncUpdate {
    connSyncUpdateSeq :: !Word16,
    connSyncUpdateFlags :: !Word8,
    connSyncUpdateService :: !Word32,
    connSyncUpdateCid :: !Word32,
    connSyncUpdateEid :: !EngineId,
    connSyncUpdateIn :: !Word16,
    connSyncUpdateOut :: !Word16
} deriving (Show,Eq)

data ConnSyncUpdatePkt = ConnSyncUpdatePkt {
    connSyncUpdatePktHeader :: ConnSyncUpdate,
    connSyncUpdatePktPayload :: [Packet]
} deriving (Show,Eq)

instance PayloadCarrier ConnSyncUpdatePkt where payloadCarried = connSyncUpdatePktPayload

data Fragv6 = Fragv6 {
    fragv6Nh :: !Word8,
    fragv6Res :: !Word8,
    fragv6Off :: !Word16,
    fragv6Id :: !Word32
} deriving (Show,Eq)

data Fragv6Pkt = Fragv6Pkt {
    fragv6PktHeader :: Fragv6,
    fragv6PktPayload :: [Packet]
} deriving (Show,Eq)

defaultFragv6 :: Fragv6
defaultFragv6 = Fragv6 17 0 0 0
defaultFragv6Packet :: Fragv6Pkt
defaultFragv6Packet = Fragv6Pkt defaultFragv6 [PPayload $ Payload 0 0]

instance PayloadCarrier Fragv6Pkt where payloadCarried = fragv6PktPayload

data HopByHop = HopByHop {
    hopByHopNh :: !Word8,
    hopByHopLen :: !Word8
} deriving (Show,Eq)

data HopByHopPkt = HopByHopPkt {
    hopByHopPktHeader :: HopByHop,
    hopByHopPktPayload :: [Packet]
} deriving (Show,Eq)

defaultHopByHop :: HopByHop
defaultHopByHop = HopByHop 17 0
defaultHopByHopPacket :: HopByHopPkt
defaultHopByHopPacket = HopByHopPkt defaultHopByHop [PPayload $ Payload 0 0]

instance PayloadCarrier HopByHopPkt where payloadCarried = hopByHopPktPayload

data PadN = PadN {
    padNCode :: !Word8,
    padNLen :: !Word8
} deriving (Show,Eq)

data PadNPkt = PadNPkt {
    padNPktHeader :: PadN,
    padNPktPayload :: [Packet]
} deriving (Show,Eq)

defaultPadN :: PadN
defaultPadN = PadN 1 0
defaultPadNPacket :: PadNPkt
defaultPadNPacket = PadNPkt defaultPadN [PPayload $ Payload 0 0]

instance PayloadCarrier PadNPkt where payloadCarried = padNPktPayload

data Payload = Payload {
    payloadPattern :: Word32,
    payloadLength  :: Word16
} deriving (Show,Eq)

defaultPayload :: Payload
defaultPayload = Payload 0 64

data HexPayload = HexPayload {
    hexPayloadData :: [Word8]
} deriving (Show,Eq)

defaultHexPayload  :: HexPayload
defaultHexPayload = HexPayload (replicate 64 0)

data Packet =
    PEth  EthernetFrame
  | PIPv4 IPv4Pkt
  | PUdp UdpPkt
  | PPayload Payload
  | PHexPayload HexPayload
  | PGtp GtpPkt
  | PL2tp L2tpPkt
  | PPpp PppPkt
  | PIPv6 IPv6Pkt
  | PTcp TcpPkt
  | PTeredo TeredoPkt
  | PGre GrePkt
  | PIcmp IcmpPkt
  | PIcmpV6 IcmpV6Pkt
  | PFragv6 Fragv6Pkt
  | PHopByHop HopByHopPkt
  | PPadN PadNPkt
  deriving (Show,Eq)