diff --git a/lib/ipaddr.ml b/lib/ipaddr.ml index e9e0409..9558641 100644 --- a/lib/ipaddr.ml +++ b/lib/ipaddr.ml @@ -357,7 +357,9 @@ module V4 = struct to_address_buffer b subnet addr; Buffer.contents b - let mem ip (pre,sz) = let host = 32 - sz in (ip >|> host) = (pre >|> host) + let mem ip (pre,sz) = + let m = mask sz in + (ip &&& m) = (pre &&& m) let subset ~subnet:(pre1,sz1) ~network:(pre2,sz2) = sz1 >= sz2 && mem pre1 (pre2,sz2) diff --git a/lib_test/test_ipaddr.ml b/lib_test/test_ipaddr.ml index 24f5921..e2697b5 100644 --- a/lib_test/test_ipaddr.ml +++ b/lib_test/test_ipaddr.ml @@ -305,6 +305,26 @@ module Test_v4 = struct (fun () -> Ipaddr_cstruct.V4.of_cstruct_exn (Cstruct.of_string addr)) ) addrs + let test_prefix_mem () = + let ip = V4.of_string_exn in + let prefix = V4.Prefix.of_string_exn in + let ships = [ + ip "10.0.0.7", prefix "10.0.0.0/29", true; + ip "172.16.255.254", prefix "172.16.255.254/31", true; + ip "192.168.0.1", prefix "0.0.0.0/0", true; + ip "192.168.0.1", V4.Prefix.private_192, true; + ip "255.255.255.255", prefix "255.255.255.255/32", true; + ip "192.0.2.1", prefix "192.0.2.0/32", false; + ip "192.0.2.1", prefix "192.0.0.0/23", false; + ip "255.255.255.255", prefix "0.0.0.0/1", false; + ] in + List.iter (fun (addr,subnet,is_mem) -> + let msg = Printf.sprintf "%s is%s in %s" + (V4.to_string addr) (if is_mem then "" else " not") (V4.Prefix.to_string subnet) + in + assert_equal ~msg (V4.Prefix.mem addr subnet) is_mem + ) ships + let suite = "Test V4" >::: [ "string_rt" >:: test_string_rt; "string_rt_bad" >:: test_string_rt_bad; @@ -328,6 +348,7 @@ module Test_v4 = struct "special_addr" >:: test_special_addr; "multicast_mac" >:: test_multicast_mac; "domain_name" >:: test_domain_name; + "prefix_mem" >:: test_prefix_mem; ] end