Skip to content

Commit

Permalink
Add V6.link_address_of_mac from RFC 2464. Partially addresses #10.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsheets committed Feb 19, 2015
1 parent 5a5e1ca commit 8332f53
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Add multicast MAC conversions from RFC 1112 and RFC 2464
* Add to_domain_name conversions to DNS label lists (in-addr.arpa and ip6.arpa)
* Add V6.interface_routers, V6.site_routers, and V6.Prefix.solicited_node
* Add V6.link_address_of_mac to convert a MAC into a link local IP address

2.5.0 (2014-05-27):
* Add `with sexp` (de)serializers to all of the Ipaddr and Macaddr types. (#31)
Expand Down
13 changes: 13 additions & 0 deletions lib/ipaddr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,19 @@ module V6 = struct
else if i = unspecified then Point
else Global

let link_address_of_mac =
let c b i = Char.code (String.get b i) in
fun mac ->
let bmac = Macaddr.to_bytes mac in
let c_0 = c bmac 0 lxor 2 in
let addr = make 0 0 0 0
(c_0 lsl 8 + c bmac 1)
(c bmac 2 lsl 8 + 0xff )
(0xfe00 + c bmac 3)
(c bmac 4 lsl 8 + c bmac 5)
in
Prefix.(network_address link addr)

let is_global i = (scope i) = Global
let is_multicast i = Prefix.(mem i multicast)
let is_private i = (scope i) <> Global
Expand Down
7 changes: 7 additions & 0 deletions lib/ipaddr.mli
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,13 @@ module V6 : sig
hierarchy. *)
val scope : t -> scope

(** [link_address_of_mac mac] is the link-local address for an
Ethernet interface derived by the IEEE MAC -> EUI-64 map with
the Universal/Local bit complemented for IPv6.
@see <https://tools.ietf.org/html/rfc2464#section-4> RFC 2464
*)
val link_address_of_mac : Macaddr.t -> t

(** [is_global ipv6] is a predicate indicating whether [ipv6] globally
addresses a node. *)
val is_global : t -> bool
Expand Down
8 changes: 8 additions & 0 deletions lib_test/test_ipaddr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,13 @@ module Test_v6 = struct
assert_equal ~msg:"domain_name"
(String.concat "." (V6.to_domain_name ip)) name

let test_link_address_of_mac () =
let mac = Macaddr.of_string_exn "34-56-78-9A-BC-DE" in
let ip_str = V6.(to_string (link_address_of_mac mac)) in
let expected = "fe80::3656:78ff:fe9a:bcde" in
assert_equal ~msg:("link_address_of_mac "^ip_str^" <> "^expected)
ip_str expected

let suite = "Test V6" >::: [
"string_rt" >:: test_string_rt;
"string_rt_bad" >:: test_string_rt_bad;
Expand All @@ -625,6 +632,7 @@ module Test_v6 = struct
"prefix_map" >:: test_prefix_map;
"multicast_mac" >:: test_multicast_mac;
"domain_name" >:: test_domain_name;
"link_address_of_mac" >:: test_link_address_of_mac;
]
end

Expand Down

0 comments on commit 8332f53

Please sign in to comment.