From 9684383a98536040b7899440763925591045d1fc Mon Sep 17 00:00:00 2001 From: Denis Tereshkin Date: Fri, 13 Oct 2023 17:14:31 +0700 Subject: [PATCH] Add MacAddress --- src/Main.hs | 5 --- src/Packets/L2.hs | 10 +++++ src/Packets/MacAddress.hs | 20 +++++++++ src/Packets/{Packet.hs => Serializable.hs} | 4 +- test/Test.hs | 14 +++++++ test/Test/Packets/MacAddress.hs | 48 ++++++++++++++++++++++ theta.cabal | 18 +++++++- 7 files changed, 111 insertions(+), 8 deletions(-) delete mode 100644 src/Main.hs create mode 100644 src/Packets/L2.hs create mode 100644 src/Packets/MacAddress.hs rename src/Packets/{Packet.hs => Serializable.hs} (77%) create mode 100644 test/Test.hs create mode 100644 test/Test/Packets/MacAddress.hs diff --git a/src/Main.hs b/src/Main.hs deleted file mode 100644 index 32c6734..0000000 --- a/src/Main.hs +++ /dev/null @@ -1,5 +0,0 @@ -module Main (main) where - -main :: IO () -main = do - putStrLn "hello world" diff --git a/src/Packets/L2.hs b/src/Packets/L2.hs new file mode 100644 index 0000000..d77415d --- /dev/null +++ b/src/Packets/L2.hs @@ -0,0 +1,10 @@ + +module Packets.L2 + ( + ) where + +import Packets.Packet (Serializable (..)) + + +data L2Header + diff --git a/src/Packets/MacAddress.hs b/src/Packets/MacAddress.hs new file mode 100644 index 0000000..7d0e3d5 --- /dev/null +++ b/src/Packets/MacAddress.hs @@ -0,0 +1,20 @@ + +module Packets.MacAddress + ( + MacAddress(..) + , broadcastMac + ) where + +import qualified Data.ByteString as B +import Data.Word (Word8) +import Packets.Serializable (Serializable (..)) + +data MacAddress = + MacAddress Word8 Word8 Word8 Word8 Word8 Word8 + deriving (Show, Eq) + +instance Serializable MacAddress where + serialize (MacAddress b1 b2 b3 b4 b5 b6) = B.pack [b1, b2, b3, b4, b5, b6] + +broadcastMac :: MacAddress +broadcastMac = MacAddress 0xff 0xff 0xff 0xff 0xff 0xff diff --git a/src/Packets/Packet.hs b/src/Packets/Serializable.hs similarity index 77% rename from src/Packets/Packet.hs rename to src/Packets/Serializable.hs index 072a210..578cd07 100644 --- a/src/Packets/Packet.hs +++ b/src/Packets/Serializable.hs @@ -1,8 +1,8 @@ -module Packets.Packet +module Packets.Serializable ( Serializable(..) - ) where +) where import qualified Data.ByteString as B diff --git a/test/Test.hs b/test/Test.hs new file mode 100644 index 0000000..ac4e498 --- /dev/null +++ b/test/Test.hs @@ -0,0 +1,14 @@ + +module Main + ( + main + ) where + +import qualified Test.Packets.MacAddress +import Test.Tasty + +main = defaultMain tests + +tests :: TestTree +tests = testGroup "Tests" [ Test.Packets.MacAddress.tests ] + diff --git a/test/Test/Packets/MacAddress.hs b/test/Test/Packets/MacAddress.hs new file mode 100644 index 0000000..259d987 --- /dev/null +++ b/test/Test/Packets/MacAddress.hs @@ -0,0 +1,48 @@ + +module Test.Packets.MacAddress + ( + tests + ) where + +import qualified Data.ByteString as B +import Data.Word (Word8 (..)) +import Hedgehog (MonadGen (..), forAll, property, (===)) +import Hedgehog.Gen +import qualified Hedgehog.Range as Range +import Packets.MacAddress +import Packets.Serializable +import Test.Tasty +import Test.Tasty.Hedgehog +import Test.Tasty.HUnit + +tests :: TestTree +tests = testGroup "MacAddress" [ unitTests, properties ] + +unitTests :: TestTree +unitTests = testGroup "Unit tests" [ testSerialization ] + +testSerialization :: TestTree +testSerialization = testCase "serialization" $ do + let mac = MacAddress 0x01 0x00 0x5e 0x01 0x02 0x03 + let bs = serialize mac + bs @?= B.pack [0x01, 0x00, 0x5e, 0x01, 0x02, 0x03] + + +genMac :: (MonadGen m) => Range.Range Word8 -> m MacAddress +genMac range = do + b1 <- word8 range + b2 <- word8 range + b3 <- word8 range + b4 <- word8 range + b5 <- word8 range + b6 <- word8 range + return $ MacAddress b1 b2 b3 b4 b5 b6 + +properties :: TestTree +properties = testGroup "Properties" [ propMacAddressLength ] + +propMacAddressLength :: TestTree +propMacAddressLength = testProperty "Serialized MAC address length always equal to 6" $ + property $ do + mac <- forAll $ genMac (Range.constantBounded) + (B.length . serialize) mac === 6 diff --git a/theta.cabal b/theta.cabal index 1fa63c8..42c7d5e 100644 --- a/theta.cabal +++ b/theta.cabal @@ -16,9 +16,12 @@ extra-source-files: README.md library theta-lib hs-source-dirs: src - modules: Packets.Packet + modules: Packets.Serializable + , Packets.L2 + , Packets.MacAddress default-language: Haskell2010 build-depends: base >= 4.7 && < 5 + , bytestring ghc-options: -Wall -Wcompat -Widentities @@ -28,3 +31,16 @@ library theta-lib -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + +Test-Suite test-theta + type: exitcode-stdio-1.0 + hs-source-dirs: src test + main-is: Test.hs + other-modules: Test.Packets.MacAddress + build-depends: base + , theta-lib + , tasty + , tasty-hunit + , tasty-hedgehog + , hedgehog + , bytestring