Skip to content

Verify checksums #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 10, 2023
Merged

Conversation

MarcusWichelmann
Copy link
Contributor

Thank you for forking google/gopacket and keeping it alive!

Originally submitted here: google/gopacket#1057
With a commit from: google/gopacket#883


This PR adds a LayerWithChecksum interface for layers that have a checksum with a function to verify it and implements this function for all layers that use the internet checksum from RFC1071 and where the checksum computation was implemented (for SerializeTo).

It also adds a way to verify the checksums of all layers of a packet and retrieve a list of all found mismatches.

To implement this, I refactored the internet checksum calculation code, deduplicated it and made it a little bit more modular. There are now two functions: ComputeChecksum and FoldChecksum.
These split-up functions make it possible to verify checksums without having to zero-out the checksum that's already set in the packet. Instead, the checksum of the whole packet (including the existing checksum) is computed and then the existing checksum is subtracted, before it is folded. This way we don't need to copy the packet buffer and zero-out the checksum field, just to verify it.

The refactoring and checksum-verification are split up into two commits to make this easier to review.

For the UDP layer, there is a special case, because the UDP checksum is optional. That's why this PR is based on google/gopacket#883 and extends it to make the checksum verification succeed, if the existing UDP checksum was unset.

arthurfabre and others added 3 commits July 19, 2023 12:37
RFC768 states:

    If the computed checksum is zero, it is transmitted as all ones (the
    equivalent in one's complement arithmetic). An all zero transmitted
    checksum  value means that the transmitter generated no checksum.

Updated the serialization logic to correctly handle this. It isn't a big
problem for IPv4 where checksums are optional, but affects IPv6 which
has mandatory UDP checksums.
This commit unifies the checksum computation for different layers and splits it into a computation and folding step to make it more flexible.
This commit adds functions to validate checksums of individual layers or all layers of a packet. It also implements this functionality for all layers that use the internet checksum and already have some kind of checksum calculation implemented.
@mosajjal mosajjal self-assigned this Jul 22, 2023
@mosajjal
Copy link
Contributor

looks good. need to do a bit more digging. originally wanted to suggest that we move the checksum to its own type rather than uint16 or uint32 but that needs another round of refactoring on top of this and might break existing code.

@mosajjal mosajjal merged commit f6e54f1 into gopacket:master Sep 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants