Skip to content

Instantly share code, notes, and snippets.

@copy
Created November 22, 2018 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save copy/62a594a668b89a625340e01cbb345604 to your computer and use it in GitHub Desktop.
Save copy/62a594a668b89a625340e01cbb345604 to your computer and use it in GitHub Desktop.
diff --git a/src/tcpip_checksum/tcpip_checksum.ml b/src/tcpip_checksum/tcpip_checksum.ml
index 2b7abc87..5035ccaa 100644
--- a/src/tcpip_checksum/tcpip_checksum.ml
+++ b/src/tcpip_checksum/tcpip_checksum.ml
@@ -15,6 +15,30 @@
*)
(** One's complement checksum, RFC1071 *)
-external ones_complement: Cstruct.t -> int = "caml_tcpip_ones_complement_checksum"
+(* external ones_complement: Cstruct.t -> int = "caml_tcpip_ones_complement_checksum" *)
-external ones_complement_list: Cstruct.t list -> int = "caml_tcpip_ones_complement_checksum_list"
+(* external ones_complement_list: Cstruct.t list -> int = "caml_tcpip_ones_complement_checksum_list" *)
+
+let ones_complement (buffer: Cstruct.t) =
+ let len = Cstruct.len buffer in
+ let rec finalise_checksum cs =
+ assert (cs >= 0);
+ if cs < 0x10000 then
+ cs
+ else
+ finalise_checksum ((cs land 0xffff) + (cs lsr 16))
+ in
+ let rec do_checksum checksum offset =
+ if offset + 1 < len then (
+ let checksum = checksum + Cstruct.BE.get_uint16 buffer offset in
+ do_checksum checksum (offset + 2)
+ ) else if offset + 1 = len then (
+ let checksum = checksum + (Cstruct.get_uint8 buffer offset lsl 8) in
+ finalise_checksum checksum
+ ) else
+ finalise_checksum checksum
+ in
+ lnot (do_checksum 0 0) land 0xffff
+
+let ones_complement_list buffers =
+ ones_complement (Cstruct.concat buffers)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment