module Packets.Checksum ( ipChecksum ) where import Data.Bits (shiftR, (.&.)) import qualified Data.ByteString as B import Data.Word (Word16) import Prelude hiding (words) ipChecksum :: B.ByteString -> Word16 ipChecksum bytes = 0xffff - (fromIntegral . adjustedSum . sum . words) bytes where adjustedSum x = if x > 0xffff then adjustedSum $ x .&. 0xffff + x `shiftR` 16 else x words :: B.ByteString -> [Int] words bs = let (h, t) = B.splitAt 2 bs in case (B.unpack . B.take 2) h of [x1, x2] -> (fromIntegral x1 * 0x100 + fromIntegral x2) : words t [x1] -> (fromIntegral x1 * 0x100) : words t _ -> []