summaryrefslogtreecommitdiff
path: root/sid.ml
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2018-10-27 22:17:16 +0200
committerPhilipp Gesang <phg@phi-gamma.net>2018-10-30 01:15:03 +0100
commita626ab534224cc244d58259e622b9a59703223f6 (patch)
tree09252abc2abf4c0fa9993ee0c7faab059fe83af0 /sid.ml
parent4175ecde16ddbb0637cfafd3a41254d995d8bab7 (diff)
downloadocaml-sid-a626ab534224cc244d58259e622b9a59703223f6.tar.gz
sid: optionally handle big endian in packet format codec
Oddly enough this only has an effect on the sub_auths since the 48 bits of “identifier authority” are always handled in big endian.
Diffstat (limited to 'sid.ml')
-rw-r--r--sid.ml68
1 files changed, 36 insertions, 32 deletions
diff --git a/sid.ml b/sid.ml
index 9f1e591..ddfb8e1 100644
--- a/sid.ml
+++ b/sid.ml
@@ -80,10 +80,9 @@ module StringFmt = struct
let decode s =
let n = String.length s in
if n <= 4 then
- raise
- (Invalid_argument
- (Printf.sprintf
- "Invalid SID: ‘%s’ too short to be a SID in string format" s))
+ Error
+ (Printf.sprintf
+ "Invalid SID: ‘%s’ too short to be a SID in string format" s)
else
expect_char s 'S' 0;
expect_char s '-' 1;
@@ -98,15 +97,9 @@ module StringFmt = struct
sa := d :: !sa;
p' := np
done;
- { sid_ident_auth = ia
- ; sid_sub_auths = Array.of_list (List.rev !sa)
- }
-
- let from_string_res s =
- try Ok (decode s) with Invalid_argument msg -> Error msg
-
- let from_string_opt s =
- try Some (decode s) with Invalid_argument _ -> None
+ Ok { sid_ident_auth = ia
+ ; sid_sub_auths = Array.of_list (List.rev !sa)
+ }
let fmt_ident_auth b ia =
Buffer.add_string b (U64.to_string ia)
@@ -129,17 +122,24 @@ end (* [module StringFmt] *)
module PacketRep = struct (* [MS-DTYP] 2.4.22 *)
- (* XXX configurable endianness *)
+ type endian = Big | Little
- let encode s =
+ let wordlen = 4 (* sizeof int *)
+ let min_pktrep_len = 1 + 1 + sizeof_ident_auth
+ let max_pktrep_len = 1 + 1
+ + sizeof_ident_auth
+ + max_subauth_count * sizeof_sub_auth
+ let pktrep_sa_off = min_pktrep_len
+
+ let encode ?(endian=Little) s =
let nsa = Array.length s.sid_sub_auths in
let l = 8 + nsa * sizeof_sub_auth in
- let b = Buffer.create l in
+ let b = Bytes.create l in
+ let o = ref 0 in
+ let pushbyte c = char_of_int c |> Bytes.set b !o; incr o in
assert (0 <= nsa && nsa <= 15);
- let pushbyte c = char_of_int c |> Buffer.add_char b in
-
pushbyte 1;
pushbyte nsa;
@@ -148,20 +148,19 @@ module PacketRep = struct (* [MS-DTYP] 2.4.22 *)
in (* big endian!, cf. [MS-DTYP] 2.4.1.1 *)
getia 5; getia 4; getia 3; getia 2; getia 1; getia 0;
- let getsa sa n = pushbyte (U32.to_int (U32.shift_right sa n) land 0xff) in
- Array.iter
- (fun sa -> getsa sa 0; getsa sa 1; getsa sa 2; getsa sa 3)
+ let write_u32 =
+ match endian with
+ | Big -> U32.to_bytes_big_endian
+ | Little -> U32.to_bytes_little_endian
+ in
+ Array.iteri
+ (fun i sa ->
+ let o' = !o + i * wordlen in
+ write_u32 sa b o')
s.sid_sub_auths;
- Bytes.unsafe_of_string (Buffer.contents b)
+ b
- let wordlen = 4 (* sizeof int *)
- let min_pktrep_len = 1 + 1 + sizeof_ident_auth
- let max_pktrep_len = 1 + 1
- + sizeof_ident_auth
- + max_subauth_count * sizeof_sub_auth
- let pktrep_sa_off = min_pktrep_len
-
- let decode b =
+ let decode ?(endian=Little) b =
let l = Bytes.length b in
if l < min_pktrep_len || max_pktrep_len < l then
Error (Printf.sprintf
@@ -188,10 +187,15 @@ module PacketRep = struct (* [MS-DTYP] 2.4.22 *)
let ia = U64.zero
|> getbyte 2 |> getbyte 3 |> getbyte 4
|> getbyte 5 |> getbyte 6 |> getbyte 7 in
- let sas = Array.make nsa (U32.zero) in
+ let sas = Array.make nsa (U32.zero)
+ and read_u32 =
+ match endian with
+ | Big -> U32.of_bytes_big_endian
+ | Little -> U32.of_bytes_little_endian
+ in
for i = 0 to (nsa - 1) do
let off = pktrep_sa_off + i * sizeof_sub_auth in
- sas.(i) <- U32.of_bytes_little_endian b off
+ sas.(i) <- read_u32 b off
done;
Ok { sid_ident_auth = ia
; sid_sub_auths = sas