Guest User

Untitled

a guest
Jun 17th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.26 KB | None | 0 0
  1. {-# LANGUAGE OverloadedStrings #-}
  2.  
  3. module Netcrawl.ArpDiff
  4. ( doArpDiff
  5. ) where
  6.  
  7. import Colonnade (Colonnade, Headed)
  8. import qualified Colonnade as C
  9. import qualified Data.Aeson as AE
  10. import qualified Data.ByteString.Char8 as CS
  11. import Data.ByteString.Lazy.Char8 (ByteString)
  12. import qualified Data.ByteString.Lazy.Char8 as CL
  13. import qualified Data.Map as M
  14. import qualified Data.Map.Merge.Strict as MS
  15. import Data.Map.Strict (Map)
  16. import Data.Maybe (fromMaybe)
  17. import Data.Monoid (mconcat, (<>))
  18. import Data.Profunctor (lmap)
  19. import Data.Text (Text)
  20. import qualified Data.Text as T
  21. import qualified Data.Text.Lazy.Builder as LB
  22. import qualified Data.Text.Lazy.Builder as TB
  23. import qualified Data.Text.Lazy.IO as LTIO
  24. import qualified Net.Mac as Mac
  25. import Netcrawl.Prelude
  26. import Netcrawl.Types (ArpDelta (..), DeltaMac (..),
  27. Device (..), InterfaceIndex (..))
  28. import Siphon (Siphon)
  29. import qualified Siphon as S
  30. import qualified Net.IPv4 as IP
  31.  
  32. arpDiff ::
  33. Map IPv4 Mac
  34. -> Map IPv4 Mac
  35. -> Map IPv4 ArpDelta
  36. arpDiff m1 m2 =
  37. MS.merge
  38. (MS.mapMissing (\_ x -> ArpOld x)) -- preserve keys found in m1 but not m2
  39. (MS.mapMissing (\_ x -> ArpNew x)) -- preserve keys found in m2 but not m1
  40. (MS.zipWithMaybeMatched (\_ v1 v2 -> if v1 == v2 then Nothing else Just (ArpDelta (DeltaMac v1 v2)))) -- Apply f when keys in both m1 and m2
  41. m1
  42. m2
  43.  
  44. decodeDevice :: ByteString -> Maybe Device
  45. decodeDevice b = case AE.decode b of
  46. Nothing -> Nothing
  47. Just x -> Just x
  48.  
  49. decodeArp :: ByteString -> Maybe (Map IPv4 Mac)
  50. decodeArp b = case decodeDevice b of
  51. Nothing -> Nothing
  52. Just x -> Just (deviceArp x)
  53.  
  54. data ArpThing = ArpThing
  55. { ip :: IPv4
  56. , old :: Maybe Mac
  57. , new :: Maybe Mac }
  58.  
  59. deltaToThing :: IPv4 -> ArpDelta -> ArpThing
  60. deltaToThing i (ArpDelta (DeltaMac m1 m2)) = ArpThing i (Just m1) (Just m2)
  61. deltaToThing i (ArpOld m1) = ArpThing i (Just m1) Nothing
  62. deltaToThing i (ArpNew m2) = ArpThing i Nothing (Just m2)
  63.  
  64. data Newness = Old | New
  65.  
  66. thingToText :: Newness -> ArpThing -> Text
  67.  
  68. thingToText Old a = case old a of
  69. Nothing -> ""
  70. Just x -> Mac.encode x
  71. thingToText New a = case new a of
  72. Nothing -> ""
  73. Just x -> Mac.encode x
  74.  
  75. doArpDiff :: FilePath -> FilePath -> IO ()
  76. doArpDiff x y = do
  77. xContents <- CL.readFile x
  78. yContents <- CL.readFile y
  79.  
  80. let arp1 = decodeArp xContents
  81. arp2 = decodeArp yContents
  82. diff = arpDiff (fromMaybe M.empty arp1) (fromMaybe M.empty arp2)
  83. diffList = M.toList diff
  84. print diffList
  85.  
  86. --putStrLn "\n"
  87. --CL.putStrLn (CL.append (CL.pack "ip,old,new\n") (CSV.encode diffList'))
  88.  
  89. -- replace csv encoder with siphon to unhell yourself
  90.  
  91. let colArp :: Colonnade Headed ArpThing Text
  92. colArp = mconcat
  93. [ C.headed "IP" (IP.encode . ip )
  94. , C.headed "Old" (thingToText Old)
  95. , C.headed "New" (thingToText New)
  96. ]
  97.  
  98.  
  99. --LTIO.putStr (TB.toLazyText (S.encodeCsv colArp diffList))
  100.  
  101.  
  102. print "meow"
Add Comment
Please, Sign In to add comment