2017-06-29 2 views
2

Ich kämpfe die ICMP-Prüfsumme insgesamt zu verstehen, warum (vor ergänzt werden) die Gesamt + ist nach rechts verschoben 16 Bits insgesamt in this line of code:warum ist ICMP-Prüfsumme verschoben 16 Bit

checksum bs = let bs' = (if (BL.length bs) `mod` 2 == 0 then bs else BL.snoc bs 0) 
        ws = runGet listOfWord16 bs' 
        total = sum (map fromIntegral ws) :: Word32 
       in complement (fromIntegral total + fromIntegral (total `shiftR` 16)) 

RFC 792 hat dies zu sagen über die Prüfsumme Berechnung:

Checksum

die Prüfsumme ist die 16-Bit-Einsen-Komplement des eigenen Ergänzen Sie die Summe der ICMP-Nachricht, beginnend mit dem ICMP-Typ. Zum Berechnen der Prüfsumme sollte das Prüfsummenfeld Null sein. Wenn die Gesamtlänge ungerade ist, werden die empfangenen Daten mit einem Oktett von Nullen aufgefüllt, um die Prüfsumme zu berechnen. Diese Prüfsumme kann zukünftig ersetzt werden.

I verstehen, warum bs' berechnet wird, wie durch required „Wenn die Gesamtlänge ungerade ist, werden die empfangenen Daten mit einem Oktett von Nullen aufgefüllt, die Prüfsumme zu berechnen.“

Ich kann auch verstehen, die Summe der 16-Bit-Worte Summieren in dieser Zeile des Codes getan total = sum (map fromIntegral ws) :: Word32

Ich kann einfach nicht verstehen, warum in dieser Codezeile:

complement (fromIntegral total + fromIntegral (total `shiftR` 16)) 

dass + fromIntegral (total `shiftR` 16) sollte überhaupt enthalten sein.

HINWEIS: Ich habe mit wireshark verifiziert, dass die Prüfsumme nur korrekt ist, wenn ich die total + total `shiftR` 16 wie in der verknüpften Codezeile ergänzt. Also ich weiß es ist richtig, ich verstehe einfach nicht warum.

+0

Vielleicht aber Ihre Erklärung viel klarer (zumindest für mich) ist . Außerdem habe ich eine Weile gegoogelt, als ich versuchte, diese Antwort zu finden. Es scheint jetzt offensichtlich, dass ich den Link sehe, aber vielleicht wird jemand anders auf dieselbe Weise suchen wie ich und das wird hilfreich sein? –

+1

Das ist OK, [geschlossene Duplikate werden nicht gelöscht] (https: // meta.staplexchange.com/a/10844/229359), so dass jemand anders es genauso finden kann. – Cactus

Antwort

4

RFC 1071 im Detail beschreibt die Prüfsumme Definition, einschließlich dieser wichtigen Teil:

On-Komplement Maschine 2, die Ergänzung Summe 1 muss mit Hilfe eines „Ende herumtragen“, dh jeder berechnet werden Überläufe von den höchstwertigen Bits werden zu den wenigsten signifikanten Bits hinzugefügt.

In Code,

total = sum (map fromIntegral ws) :: Word32 

die Summe 32-Bit ist, das heißt seinen niedrigen 16 Bits ist die Summe ohne trägt, und die hohen 16 Bits wird die Summe der Überträge enthalten. Durch die Verwendung der Tatsache, dass fromIntegral :: Word32 -> Word16 Abschneiden der Fall ist, haben wir

low = fromIntegral total :: Word16 
high = fromIntegral $ total `shiftR` 16 :: Word16 

und so können wir berechnen, das „Ende herumtragen“, wie

eac = low + high 
+0

Antworten in der verknüpften Frage legen nahe, dass Sie dies zweimal tun müssen, um sicherzustellen, dass die hohen Bits auf Null gehen. – dfeuer

Verwandte Themen