You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
26 lines
743 B
26 lines
743 B
|
1 year ago
|
|
||
|
|
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
|
||
|
|
_ -> []
|