This is an automated email from the git hooks/post-receive script.

mehdi pushed a commit to branch master
in repository ocaml-ipaddr.

commit eb53d6d62dac460c903fa8d48f98f9cc50c7fc7c
Author: Mehdi Dogguy <me...@debian.org>
Date:   Mon Jan 18 00:11:46 2016 +0100

    Imported Upstream version 2.6.0
---
 .travis-ci.sh           |  30 ---------
 .travis.yml             |   9 +--
 CHANGES                 |  10 +++
 _oasis                  |   4 +-
 _tags                   |   5 +-
 lib/META                |   8 +--
 lib/ipaddr.ml           | 165 +++++++++++++++++++++++++++++++++++++++++-------
 lib/ipaddr.mli          |  93 +++++++++++++++++++++------
 lib/macaddr.ml          |  26 ++++----
 lib_test/Makefile       |  27 ++++++--
 lib_test/test_ipaddr.ml |  52 ++++++++++++++-
 opam                    |  37 +++++++++++
 setup.ml                |   9 +--
 13 files changed, 367 insertions(+), 108 deletions(-)

diff --git a/.travis-ci.sh b/.travis-ci.sh
deleted file mode 100755
index c02ce2b..0000000
--- a/.travis-ci.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-OPAM_DEPENDS="ocamlfind ounit sexplib"
-
-case "$OCAML_VERSION,$OPAM_VERSION" in
-3.12.1,1.0.0) ppa=avsm/ocaml312+opam10 ;;
-3.12.1,1.1.0) ppa=avsm/ocaml312+opam11 ;;
-4.00.1,1.0.0) ppa=avsm/ocaml40+opam10 ;;
-4.00.1,1.1.0) ppa=avsm/ocaml40+opam11 ;;
-4.01.0,1.0.0) ppa=avsm/ocaml41+opam10 ;;
-4.01.0,1.1.0) ppa=avsm/ocaml41+opam11 ;;
-*) echo Unknown $OCAML_VERSION,$OPAM_VERSION; exit 1 ;;
-esac
-
-echo "yes" | sudo add-apt-repository ppa:$ppa
-sudo apt-get update -qq
-sudo apt-get install -qq ocaml ocaml-native-compilers ocaml-compiler-libs 
camlp4-extra opam
-export OPAMYES=1
-export OPAMVERBOSE=1
-echo OCaml version
-ocaml -version
-echo OPAM versions
-opam --version
-opam --git-version
-
-opam init 
-
-opam install ${OPAM_DEPENDS}
-
-eval `opam config env`
-make
-cd lib_test && make
diff --git a/.travis.yml b/.travis.yml
index 164cce2..5f9a693 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,7 @@
 language: c
-script: bash -ex .travis-ci.sh
+install: wget 
https://raw.githubusercontent.com/ocaml/ocaml-travisci-skeleton/master/.travis-opam.sh
+script: bash -ex .travis-opam.sh
 env:
-  - OCAML_VERSION=4.01.0 OPAM_VERSION=1.1.0
-  - OCAML_VERSION=4.00.1 OPAM_VERSION=1.1.0
-  - OCAML_VERSION=3.12.1 OPAM_VERSION=1.1.0
+  - OCAML_VERSION=3.12   PACKAGE=ipaddr FORK_USER=dsheets
+  - OCAML_VERSION=4.01   PACKAGE=ipaddr FORK_USER=dsheets
+  - OCAML_VERSION=latest PACKAGE=ipaddr FORK_USER=dsheets
diff --git a/CHANGES b/CHANGES
index cf1372c..1ae1543 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+2.6.0 (2015-02-19):
+* Change IPv6 link-local address prefix from fe80::/10 to fe80::/64. (#39)
+* Remove type bytes = string alias (potentially breaking)
+* Turn on -safe-string (#41)
+* {V4,V6}.to_bytes_raw now uses Bytes.t rather than string (potentially 
breaking)
+* 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)
 
diff --git a/_oasis b/_oasis
index c18ba5f..c7f6b61 100644
--- a/_oasis
+++ b/_oasis
@@ -1,6 +1,6 @@
 OASISFormat: 0.3
 Name:        ipaddr
-Version:     2.5.0
+Version:     2.6.0
 Synopsis:    A library for manipulation of IP (and MAC) address representations
 Authors:     David Sheets, Anil Madhavapeddy, Hugo Heuzard
 License:     ISC
@@ -18,7 +18,7 @@ Flag top
 Library ipaddr
   Path: lib
   Findlibname: ipaddr
-  BuildDepends: sexplib, sexplib.syntax
+  BuildDepends: bytes, sexplib, sexplib.syntax
   XMETARequires: sexplib
   Modules: Ipaddr, Macaddr
   NativeOpt: -w @f@p@u@s@40
diff --git a/_tags b/_tags
index 739cedf..0131ff0 100644
--- a/_tags
+++ b/_tags
@@ -1,5 +1,5 @@
 # OASIS_START
-# DO NOT EDIT (digest: f9f16d223cb17e92bb389adad5387e15)
+# DO NOT EDIT (digest: ca6d0ca33b49d735e479caedbeb4ec59)
 # Ignore VCS directories, you can use the same kind of rule outside
 # OASIS_START/STOP if you want to exclude directories that contains
 # useless stuff for the build process
@@ -21,6 +21,7 @@
 <lib/*.ml{,i}>: oasis_library_ipaddr_native
 # Library ipaddr_unix
 "lib/ipaddr_unix.cmxs": use_ipaddr_unix
+<lib/*.ml{,i}>: pkg_bytes
 <lib/*.ml{,i}>: pkg_sexplib
 <lib/*.ml{,i}>: pkg_sexplib.syntax
 <lib/*.ml{,i}>: pkg_unix
@@ -28,5 +29,5 @@
 # Library ipaddr_top
 "top/ipaddr_top.cmxs": use_ipaddr_top
 # OASIS_STOP
-true: debug, annot, bin_annot, principal
+true: debug, annot, bin_annot, principal, safe_string
 <top/*.ml>: I(+compiler-libs)
diff --git a/lib/META b/lib/META
index 0a68d2d..79ba072 100644
--- a/lib/META
+++ b/lib/META
@@ -1,6 +1,6 @@
 # OASIS_START
-# DO NOT EDIT (digest: 4d54b77b02bee6839206a4b1e1a2a4ad)
-version = "2.5.0"
+# DO NOT EDIT (digest: d5c519d8529acf059fe6af7cb646920b)
+version = "2.6.0"
 description =
 "A library for manipulation of IP (and MAC) address representations"
 requires = "sexplib"
@@ -10,7 +10,7 @@ archive(native) = "ipaddr.cmxa"
 archive(native, plugin) = "ipaddr.cmxs"
 exists_if = "ipaddr.cma"
 package "unix" (
- version = "2.5.0"
+ version = "2.6.0"
  description =
  "A library for manipulation of IP (and MAC) address representations"
  requires = "unix ipaddr"
@@ -22,7 +22,7 @@ package "unix" (
 )
 
 package "top" (
- version = "2.5.0"
+ version = "2.6.0"
  description = "Toplevel printers for IP addresses"
  requires = "ipaddr"
  archive(byte) = "ipaddr_top.cma"
diff --git a/lib/ipaddr.ml b/lib/ipaddr.ml
index 4ffd17d..064c2d4 100644
--- a/lib/ipaddr.ml
+++ b/lib/ipaddr.ml
@@ -1,5 +1,5 @@
 (*
- * Copyright (c) 2013-2014 David Sheets <she...@alum.mit.edu>
+ * Copyright (c) 2013-2015 David Sheets <she...@alum.mit.edu>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,6 @@ open Sexplib.Std
 
 exception Parse_error of string * string with sexp
 
-type bytes = string
 type scope =
 | Point
 | Interface
@@ -87,6 +86,27 @@ let expect_end s i =
   then ()
   else raise (bad_char !i s)
 
+let hex_char_of_int = function
+  |  0 -> '0'
+  |  1 -> '1'
+  |  2 -> '2'
+  |  3 -> '3'
+  |  4 -> '4'
+  |  5 -> '5'
+  |  6 -> '6'
+  |  7 -> '7'
+  |  8 -> '8'
+  |  9 -> '9'
+  | 10 -> 'a'
+  | 11 -> 'b'
+  | 12 -> 'c'
+  | 13 -> 'd'
+  | 14 -> 'e'
+  | 15 -> 'f'
+  |  _ -> raise (Invalid_argument "not a hex int")
+
+let hex_string_of_int32 i = String.make 1 (hex_char_of_int (Int32.to_int i))
+
 module V4 = struct
   type t = int32
 
@@ -166,15 +186,15 @@ module V4 = struct
   let of_bytes bs = try Some (of_bytes_exn bs) with _ -> None
 
   let to_bytes_raw i b o =
-    b.[0 + o] <- Char.chr ((|~) (i >! 24));
-    b.[1 + o] <- Char.chr ((|~) (i >! 16));
-    b.[2 + o] <- Char.chr ((|~) (i >!  8));
-    b.[3 + o] <- Char.chr ((|~) (i >!  0))
+    Bytes.set b (0 + o) (Char.chr ((|~) (i >! 24)));
+    Bytes.set b (1 + o) (Char.chr ((|~) (i >! 16)));
+    Bytes.set b (2 + o) (Char.chr ((|~) (i >!  8)));
+    Bytes.set b (3 + o) (Char.chr ((|~) (i >!  0)))
 
   let to_bytes i =
-    let b = String.create 4 in
+    let b = Bytes.create 4 in
     to_bytes_raw i b 0;
-    b
+    Bytes.to_string b
 
   (* Int32*)
   let of_int32 i = i
@@ -184,6 +204,29 @@ module V4 = struct
   let of_int16 (a,b) = (~| a <|< 16) ||| (~| b)
   let to_int16 a = ((|~) (a >|> 16), (|~) (a &&& 0xFF_FF_l))
 
+  (** MAC *)
+  (** {{:http://tools.ietf.org/html/rfc1112#section-6.2}RFC 1112}. *)
+  let multicast_to_mac i =
+    let macb = Bytes.create 6 in
+    Bytes.set macb 0 (Char.chr 0x01);
+    Bytes.set macb 1 (Char.chr 0x00);
+    Bytes.set macb 2 (Char.chr 0x5E);
+    Bytes.set macb 3 (Char.chr ((|~) (i >|> 16 &&& 0x7F_l)));
+    Bytes.set macb 4 (Char.chr ((|~) (i >! 8)));
+    Bytes.set macb 5 (Char.chr ((|~) (i >! 0)));
+    Macaddr.of_bytes_exn (Bytes.to_string macb)
+
+  (* Host *)
+  let to_domain_name i = [
+    Int32.to_string (i >!  0);
+    Int32.to_string (i >!  8);
+    Int32.to_string (i >! 16);
+    Int32.to_string (i >! 24);
+    "in-addr";
+    "arpa";
+    "";
+  ]
+
   (* constant *)
 
   let any         = make   0   0   0   0
@@ -460,7 +503,7 @@ module V6 = struct
     else if res_len = 0
     then raise (need_more s)
     else
-      let a = Array.create 8 0 in
+      let a = Array.make 8 0 in
       let missing =
         if !compressed
         then 8 - (res_len - 1)
@@ -578,17 +621,71 @@ module V6 = struct
 
   let of_bytes bs = try Some (of_bytes_exn bs) with _ -> None
   let to_bytes i =
-    let bs = String.create 16 in
+    let bs = Bytes.create 16 in
     to_bytes_raw i bs 0;
-    bs
+    Bytes.to_string bs
+
+  (** MAC *)
+  (** {{:https://tools.ietf.org/html/rfc2464#section-7}RFC 2464}. *)
+  let multicast_to_mac i =
+    let (_,_,_,i) = to_int32 i in
+    let macb = Bytes.create 6 in
+    Bytes.set macb 0 (Char.chr 0x33);
+    Bytes.set macb 1 (Char.chr 0x33);
+    Bytes.set macb 2 (Char.chr ((|~) (i >! 24)));
+    Bytes.set macb 3 (Char.chr ((|~) (i >! 16)));
+    Bytes.set macb 4 (Char.chr ((|~) (i >! 8)));
+    Bytes.set macb 5 (Char.chr ((|~) (i >! 0)));
+    Macaddr.of_bytes_exn (Bytes.to_string macb)
+
+  (* Host *)
+  let to_domain_name (a,b,c,d) = Printf.([
+    hex_string_of_int32 ((d >|>  0) &&& 0xF_l);
+    hex_string_of_int32 ((d >|>  4) &&& 0xF_l);
+    hex_string_of_int32 ((d >|>  8) &&& 0xF_l);
+    hex_string_of_int32 ((d >|> 12) &&& 0xF_l);
+    hex_string_of_int32 ((d >|> 16) &&& 0xF_l);
+    hex_string_of_int32 ((d >|> 20) &&& 0xF_l);
+    hex_string_of_int32 ((d >|> 24) &&& 0xF_l);
+    hex_string_of_int32 ((d >|> 28) &&& 0xF_l);
+    hex_string_of_int32 ((c >|>  0) &&& 0xF_l);
+    hex_string_of_int32 ((c >|>  4) &&& 0xF_l);
+    hex_string_of_int32 ((c >|>  8) &&& 0xF_l);
+    hex_string_of_int32 ((c >|> 12) &&& 0xF_l);
+    hex_string_of_int32 ((c >|> 16) &&& 0xF_l);
+    hex_string_of_int32 ((c >|> 20) &&& 0xF_l);
+    hex_string_of_int32 ((c >|> 24) &&& 0xF_l);
+    hex_string_of_int32 ((c >|> 28) &&& 0xF_l);
+    hex_string_of_int32 ((b >|>  0) &&& 0xF_l);
+    hex_string_of_int32 ((b >|>  4) &&& 0xF_l);
+    hex_string_of_int32 ((b >|>  8) &&& 0xF_l);
+    hex_string_of_int32 ((b >|> 12) &&& 0xF_l);
+    hex_string_of_int32 ((b >|> 16) &&& 0xF_l);
+    hex_string_of_int32 ((b >|> 20) &&& 0xF_l);
+    hex_string_of_int32 ((b >|> 24) &&& 0xF_l);
+    hex_string_of_int32 ((b >|> 28) &&& 0xF_l);
+    hex_string_of_int32 ((a >|>  0) &&& 0xF_l);
+    hex_string_of_int32 ((a >|>  4) &&& 0xF_l);
+    hex_string_of_int32 ((a >|>  8) &&& 0xF_l);
+    hex_string_of_int32 ((a >|> 12) &&& 0xF_l);
+    hex_string_of_int32 ((a >|> 16) &&& 0xF_l);
+    hex_string_of_int32 ((a >|> 20) &&& 0xF_l);
+    hex_string_of_int32 ((a >|> 24) &&& 0xF_l);
+    hex_string_of_int32 ((a >|> 28) &&& 0xF_l);
+    "ip6";
+    "arpa";
+    "";
+  ])
 
- (* constant *)
+  (* constant *)
 
-  let unspecified     = make      0 0 0 0 0 0 0 0
-  let localhost       = make      0 0 0 0 0 0 0 1
-  let interface_nodes = make 0xff01 0 0 0 0 0 0 1
-  let link_nodes      = make 0xff02 0 0 0 0 0 0 1
-  let link_routers    = make 0xff02 0 0 0 0 0 0 2
+  let unspecified       = make      0 0 0 0 0 0 0 0
+  let localhost         = make      0 0 0 0 0 0 0 1
+  let interface_nodes   = make 0xff01 0 0 0 0 0 0 1
+  let link_nodes        = make 0xff02 0 0 0 0 0 0 1
+  let interface_routers = make 0xff01 0 0 0 0 0 0 2
+  let link_routers      = make 0xff02 0 0 0 0 0 0 2
+  let site_routers      = make 0xff05 0 0 0 0 0 0 2
 
   module Prefix = struct
     type addr = t with sexp
@@ -677,12 +774,13 @@ module V6 = struct
 
     let of_addr ip = make 128 ip
 
-    let global_unicast_001  = make  3 (ip 0x2000 0 0 0 0 0 0 0)
-    let link                = make 10 (ip 0xfe80 0 0 0 0 0 0 0)
-    let unique_local        = make  7 (ip 0xfc00 0 0 0 0 0 0 0)
-    let multicast           = make  8 (ip 0xff00 0 0 0 0 0 0 0)
-    let ipv4_mapped         = make 96 (ip 0 0 0 0 0 0xffff 0 0)
-    let noneui64_interface  = make  3 (ip 0x0000 0 0 0 0 0 0 0)
+    let global_unicast_001  = make   3 (ip 0x2000 0 0 0 0 0 0 0)
+    let link                = make  64 (ip 0xfe80 0 0 0 0 0 0 0)
+    let unique_local        = make   7 (ip 0xfc00 0 0 0 0 0 0 0)
+    let multicast           = make   8 (ip 0xff00 0 0 0 0 0 0 0)
+    let ipv4_mapped         = make  96 (ip 0 0 0 0 0 0xffff 0 0)
+    let noneui64_interface  = make   3 (ip 0x0000 0 0 0 0 0 0 0)
+    let solicited_node      = make 104 (ip 0xff02 0 0 0 0 1 0xff00 0)
 
     let network (pre,sz) = pre
     let bits (pre,sz) = sz
@@ -713,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
@@ -785,6 +896,14 @@ let is_private = function
   | V4 v4 -> V4.is_private v4
   | V6 v6 -> V6.is_private v6
 
+let multicast_to_mac = function
+  | V4 v4 -> V4.multicast_to_mac v4
+  | V6 v6 -> V6.multicast_to_mac v6
+
+let to_domain_name = function
+  | V4 v4 -> V4.to_domain_name v4
+  | V6 v6 -> V6.to_domain_name v6
+
 module Prefix = struct
   module Addr = struct
     let to_v6 = to_v6
diff --git a/lib/ipaddr.mli b/lib/ipaddr.mli
index 005361d..339dcf4 100644
--- a/lib/ipaddr.mli
+++ b/lib/ipaddr.mli
@@ -1,5 +1,5 @@
 (*
- * Copyright (c) 2013-2014 David Sheets <she...@alum.mit.edu>
+ * Copyright (c) 2013-2015 David Sheets <she...@alum.mit.edu>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,8 +20,6 @@
 (** Raised when parsing of IP address syntax fails. *)
 exception Parse_error of string * string with sexp
 
-type bytes = string
-
 (** Type of ordered address scope classifications *)
 type scope =
 | Point
@@ -42,7 +40,7 @@ module V4 : sig
   (** Converts the low bytes of four int values into an abstract {! V4.t }. *)
   val make : int -> int -> int -> int -> t
 
-  (** Text string conversion *)
+  (** {3 Text string conversion} *)
 
   (** [of_string_exn ipv4_string] is the address represented
       by [ipv4_string]. Raises [Parse_error] if [ipv4_string] is not a
@@ -69,29 +67,29 @@ module V4 : sig
       the formatter [f]. *)
   val pp_hum : Format.formatter -> t -> unit
 
-  (** Bytestring conversion *)
+  (** {3 Bytestring conversion} *)
 
   (** [of_bytes_exn ipv4_octets] is the address represented
       by [ipv4_octets]. Raises [Parse_error] if [ipv4_octets] is not a
       valid representation of an IPv4 address. *)
-  val of_bytes_exn : bytes -> t
+  val of_bytes_exn : string -> t
 
   (** Same as [of_bytes_exn] but returns an option type instead of raising
       an exception. *)
-  val of_bytes : bytes -> t option
+  val of_bytes : string -> t option
 
   (** Same as [of_bytes_exn] but take an extra paramenter, the offset into
       the bytes for reading. *)
-  val of_bytes_raw : bytes -> int -> t
+  val of_bytes_raw : string -> int -> t
 
   (** [to_bytes ipv4] is a string of length 4 encoding [ipv4]. *)
-  val to_bytes : t -> bytes
+  val to_bytes : t -> string
 
   (** [to_bytes_raw ipv4 bytes offset] writes the 4 byte encoding of [ipv4]
       into [bytes] at offset [offset]. *)
-  val to_bytes_raw : t -> bytes -> int -> unit
+  val to_bytes_raw : t -> Bytes.t -> int -> unit
 
-  (** Int conversion *)
+  (** {3 Int conversion} *)
 
   (** [of_int32 ipv4_packed] is the address represented by
       [ipv4_packed]. *)
@@ -107,6 +105,21 @@ module V4 : sig
   (** [to_int16 ipv4] is the 16-bit packed encoding of [ipv4]. *)
   val to_int16 : t -> int * int
 
+  (** {3 MAC conversion} *)
+
+  (** [multicast_to_mac ipv4] is the MAC address corresponding to the
+      multicast address [ipv4]. Described by
+      {{:http://tools.ietf.org/html/rfc1112#section-6.2}RFC 1112}. *)
+  val multicast_to_mac : t -> Macaddr.t
+
+  (** {3 Host conversion} *)
+
+  (** [to_domain_name ipv4] is the domain name label list for reverse
+      lookups of [ipv4]. This includes the [.in-addr.arpa.] suffix. *)
+  val to_domain_name : t -> string list
+
+  (** {3 Common addresses} *)
+
   (** [any] is 0.0.0.0. *)
   val any : t
 
@@ -271,7 +284,7 @@ module V6 : sig
       {! V6.t }. *)
   val make : int -> int -> int -> int -> int -> int -> int -> int -> t
 
-  (** Text string conversion *)
+  (** {3 Text string conversion} *)
 
   (** [of_string_exn ipv6_string] is the address represented
       by [ipv6_string]. Raises [Parse_error] if [ipv6_string] is not a
@@ -298,29 +311,29 @@ module V6 : sig
       the formatter [f]. *)
   val pp_hum : Format.formatter -> t -> unit
 
-  (** Bytestring conversion *)
+  (** {3 Bytestring conversion} *)
 
   (** [of_bytes_exn ipv6_octets] is the address represented
       by [ipv6_octets]. Raises [Parse_error] if [ipv6_octets] is not a
       valid representation of an IPv6 address. *)
-  val of_bytes_exn : bytes -> t
+  val of_bytes_exn : string -> t
 
   (** Same as [of_bytes_exn] but returns an option type instead of raising
       an exception. *)
-  val of_bytes : bytes -> t option
+  val of_bytes : string -> t option
 
   (** Same as [of_bytes_exn] but takes an extra paramenter, the offset into
       the bytes for reading. *)
-  val of_bytes_raw : bytes -> int -> t
+  val of_bytes_raw : string -> int -> t
 
   (** [to_bytes ipv6] is a string of length 16 encoding [ipv6]. *)
-  val to_bytes : t -> bytes
+  val to_bytes : t -> string
 
   (** [to_bytes_raw ipv6 bytes offset] writes the 16 bytes encoding of [ipv6]
       into [bytes] at offset [offset]. *)
-  val to_bytes_raw : t -> bytes -> int -> unit
+  val to_bytes_raw : t -> Bytes.t -> int -> unit
 
-  (** Int conversion *)
+  (** {3 Int conversion} *)
 
   (** [of_int64 (ho, lo)] is the IPv6 address represented by two int64. *)
   val of_int64 : int64 * int64 -> t
@@ -338,6 +351,21 @@ module V6 : sig
   (** [to_int16 ipv6] is the 128-bit packed encoding of [ipv6]. *)
   val to_int16 : t -> int * int * int * int * int * int * int * int
 
+  (** {3 MAC conversion} *)
+
+  (** [multicast_to_mac ipv6] is the MAC address corresponding to the
+      multicast address [ipv6]. Described by
+      {{:https://tools.ietf.org/html/rfc2464#section-7}RFC 2464}. *)
+  val multicast_to_mac : t -> Macaddr.t
+
+  (** {3 Host conversion} *)
+
+  (** [to_domain_name ipv6] is the domain name label list for reverse
+      lookups of [ipv6]. This includes the [.ip6.arpa.] suffix. *)
+  val to_domain_name : t -> string list
+
+  (** {3 Common addresses} *)
+
   (** [unspecified] is ::. *)
   val unspecified : t
 
@@ -350,9 +378,15 @@ module V6 : sig
   (** [link_nodes] is ff02::01. *)
   val link_nodes : t
 
+  (** [interface_routers] is ff01::02. *)
+  val interface_routers : t
+
   (** [link_routers] is ff02::02. *)
   val link_routers : t
 
+  (** [site_routers] is ff05::02. *)
+  val site_routers : t
+
   (** A module for manipulating IPv6 network prefixes. *)
   module Prefix : sig
     type addr = t with sexp
@@ -432,7 +466,7 @@ module V6 : sig
     (** The Unique Local Unicast (ULA), fc00::/7. *)
     val unique_local       : t
 
-    (** Link-Local Unicast, fe80::/10. *)
+    (** Link-Local Unicast, fe80::/64. *)
     val link               : t
 
     (** The multicast network, ff00::/8. *)
@@ -445,6 +479,9 @@ module V6 : sig
         identifiers, ::/3. *)
     val noneui64_interface : t
 
+    (** Solicited-Node multicast addresses *)
+    val solicited_node : t
+
     (** [network subnet] is the address for [subnet]. *)
     val network : t -> addr
 
@@ -461,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
@@ -537,6 +581,15 @@ val is_multicast : t -> bool
     addresses a node. *)
 val is_private : t -> bool
 
+(** [multicast_to_mac addr] is the MAC address corresponding to the
+    multicast address [addr]. See {!V4.multicast_to_mac} and
+    {!V6.multicast_to_mac}.*)
+val multicast_to_mac : t -> Macaddr.t
+
+(** [to_domain_name addr] is the domain name label list for reverse
+    lookups of [addr]. This includes the [.arpa.] suffix. *)
+val to_domain_name : t -> string list
+
 module Prefix : sig
   type addr = t with sexp
 
diff --git a/lib/macaddr.ml b/lib/macaddr.ml
index 0f55350..6c3ca14 100644
--- a/lib/macaddr.ml
+++ b/lib/macaddr.ml
@@ -21,15 +21,15 @@ exception Parse_error of string * string with sexp
 
 let need_more x = Parse_error ("not enough data", x)
 
-type t = string (* length 6 only *)
+type t = Bytes.t (* length 6 only *)
 
-let compare = String.compare
+let compare = Bytes.compare
 
 (* Raw MAC address off the wire (network endian) *)
 let of_bytes_exn x =
   if String.length x <> 6
   then raise (Parse_error ("MAC is exactly 6 bytes", x))
-  else x
+  else Bytes.of_string x
 
 let of_bytes x = try Some (of_bytes_exn x) with _ -> None
 
@@ -68,10 +68,10 @@ let parse_hex_int term s i =
   else raise (need_more s)
 
 let parse_sextuple s i =
-  let m = String.create 6 in
+  let m = Bytes.create 6 in
   try
     let p = !i in
-    m.[0] <- Char.chr (parse_hex_int [':';'-'] s i);
+    Bytes.set m 0 (Char.chr (parse_hex_int [':';'-'] s i));
     if !i >= String.length s
     then raise (need_more s)
     else
@@ -80,12 +80,12 @@ let parse_sextuple s i =
       incr i;
       for k=1 to 4 do
         let p = !i in
-        m.[k] <- Char.chr (parse_hex_int sep s i);
+        Bytes.set m k (Char.chr (parse_hex_int sep s i));
         (if !i - p <> 2 then raise (Parse_error ("hex pairs required",s)));
         incr i;
       done;
       let p = !i in
-      m.[5] <- Char.chr (parse_hex_int [] s i);
+      Bytes.set m 5 (Char.chr (parse_hex_int [] s i));
       (if !i - p <> 2 then raise (Parse_error ("hex pairs required",s)));
       m
   with Invalid_argument "Char.chr" ->
@@ -96,7 +96,7 @@ let of_string_exn x = parse_sextuple x (ref 0)
 
 let of_string x = try Some (of_string_exn x) with _ -> None
 
-let chri x i = Char.code x.[i]
+let chri x i = Char.code (Bytes.get x i)
 
 let to_string ?(sep=':') x =
   Printf.sprintf "%02x%c%02x%c%02x%c%02x%c%02x%c%02x"
@@ -107,7 +107,7 @@ let to_string ?(sep=':') x =
     (chri x 4) sep
     (chri x 5)
 
-let to_bytes x = x
+let to_bytes x = Bytes.to_string x
 
 let sexp_of_t m = Sexplib.Sexp.Atom (to_string m)
 
@@ -116,13 +116,13 @@ let t_of_sexp m =
   | Sexplib.Sexp.Atom m -> of_string_exn m
   | _ -> raise (Failure "Macaddr.t: Unexpected non-atom in sexp")
 
-let broadcast = String.make 6 '\255'
+let broadcast = Bytes.make 6 '\255'
 
 let make_local bytegenf =
-  let x = String.create 6 in
+  let x = Bytes.create 6 in
   (* set locally administered and unicast bits *)
-  x.[0] <- Char.chr ((((bytegenf 0) lor 2) lsr 1) lsl 1);
-  for i = 1 to 5 do x.[i] <- Char.chr (bytegenf i) done;
+  Bytes.set x 0 (Char.chr ((((bytegenf 0) lor 2) lsr 1) lsl 1));
+  for i = 1 to 5 do Bytes.set x i (Char.chr (bytegenf i)) done;
   x
 
 let get_oui x =
diff --git a/lib_test/Makefile b/lib_test/Makefile
index e3956f4..5a60be3 100644
--- a/lib_test/Makefile
+++ b/lib_test/Makefile
@@ -1,15 +1,32 @@
-.PHONY: all
+.PHONY: all clean
 
-FLAGS=-package oUnit -package sexplib -g
+OCAML_VERSION=$(shell ocaml -version | sed -n "s/.*version \(.*\)$$/\1/p")
+
+ifneq      (,$(findstring 3.12.,$(OCAML_VERSION)))
+SAFE_STRING=
+else ifneq (,$(findstring 4.00.,$(OCAML_VERSION)))
+SAFE_STRING=
+else ifneq (,$(findstring 4.01.,$(OCAML_VERSION)))
+SAFE_STRING=
+else
+SAFE_STRING=-safe-string
+endif
+
+FLAGS=-package oUnit,sexplib,bytes -g $(SAFE_STRING) -principal
 
 all: test_ipaddr.ml test_macaddr.ml
+       @echo Detected OCaml $(OCAML_VERSION)
        ocamlfind ocamlc -o test_ipaddr $(FLAGS) -I ../_build/lib \
-               ../_build/lib/ipaddr.cmo -linkpkg test_ipaddr.ml
+               ../_build/lib/macaddr.cmo ../_build/lib/ipaddr.cmo \
+               -linkpkg test_ipaddr.ml
        ocamlfind ocamlc -o test_macaddr $(FLAGS) -I ../_build/lib \
                ../_build/lib/macaddr.cmo -linkpkg test_macaddr.ml
        ./test_ipaddr
        @echo
        ./test_macaddr
        @echo
-       @rm test_ipaddr.cmi test_ipaddr.cmo test_ipaddr
-       @rm test_macaddr.cmi test_macaddr.cmo test_macaddr
+       $(MAKE) clean
+
+clean:
+       rm -f test_ipaddr.cmi test_ipaddr.cmo test_ipaddr
+       rm -f test_macaddr.cmi test_macaddr.cmo test_macaddr
diff --git a/lib_test/test_ipaddr.ml b/lib_test/test_ipaddr.ml
index 1f629e9..91bcd0d 100644
--- a/lib_test/test_ipaddr.ml
+++ b/lib_test/test_ipaddr.ml
@@ -272,6 +272,23 @@ module Test_v4 = struct
     assert_equal ~msg:"any"       V4.any       V4.Prefix.(network global);
     assert_equal ~msg:"localhost" true V4.(Prefix.(mem localhost loopback))
 
+  let test_multicast_mac () =
+    let ip = V4.of_bytes_exn "\xff\xbf\x9f\x8f" in
+    let multicast = V4.Prefix.(network_address multicast ip) in
+    let unicast_mac_str   = Macaddr.to_string (V4.multicast_to_mac ip) in
+    let multicast_mac_str = Macaddr.to_string (V4.multicast_to_mac multicast) 
in
+    let mac_str = "01:00:5e:3f:9f:8f" in
+    assert_equal ~msg:("unicast_mac "^unicast_mac_str^" <> "^mac_str)
+      unicast_mac_str   mac_str;
+    assert_equal ~msg:("multicast_mac "^multicast_mac_str^" <> "^mac_str)
+      multicast_mac_str mac_str
+
+  let test_domain_name () =
+    let ip = V4.of_string_exn "128.64.32.16" in
+    let name = "16.32.64.128.in-addr.arpa." in
+    assert_equal ~msg:"domain_name"
+      (String.concat "." (V4.to_domain_name ip)) name
+
   let suite = "Test V4" >::: [
     "string_rt"            >:: test_string_rt;
     "string_rt_bad"        >:: test_string_rt_bad;
@@ -291,6 +308,8 @@ module Test_v4 = struct
     "map"                  >:: test_map;
     "prefix_map"           >:: test_prefix_map;
     "special_addr"         >:: test_special_addr;
+    "multicast_mac"        >:: test_multicast_mac;
+    "domain_name"          >:: test_domain_name;
   ]
 end
 
@@ -453,7 +472,7 @@ module Test_v6 = struct
   let test_prefix_bits () =
     let pairs = V6.Prefix.([
       global_unicast_001, 3;
-      link,              10;
+      link,              64;
       unique_local,       7;
       multicast,          8;
       ipv4_mapped,       96;
@@ -566,6 +585,34 @@ module Test_v6 = struct
     assert_equal ~msg:"third"
       (M.find (V6.Prefix.of_string_exn "::ffff:128.0.0.0/1") m) "high-bitters"
 
+  let test_multicast_mac () =
+    let on = 0xFFFF in
+    let ip = V6.make on on on on on 0xFFFF 0xFEFE 0xFDFD in
+    let unicast   = V6.Prefix.(network_address global_unicast_001 ip) in
+    let multicast = V6.Prefix.(network_address multicast ip) in
+    let unicast_mac_str   = Macaddr.to_string (V6.multicast_to_mac unicast) in
+    let multicast_mac_str = Macaddr.to_string (V6.multicast_to_mac multicast) 
in
+    let mac_str = "33:33:fe:fe:fd:fd" in
+    assert_equal ~msg:("unicast_mac "^unicast_mac_str^" <> "^mac_str)
+      unicast_mac_str   mac_str;
+    assert_equal ~msg:("multicast_mac "^multicast_mac_str^" <> "^mac_str)
+      multicast_mac_str mac_str
+
+  let test_domain_name () =
+    let ip = V6.of_string_exn "2a00:1450:4009:800::200e" in
+    let name =
+      
"e.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.0.9.0.0.4.0.5.4.1.0.0.a.2.ip6.arpa."
+    in
+    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;
@@ -583,6 +630,9 @@ module Test_v6 = struct
     "scope"                >:: test_scope;
     "map"                  >:: test_map;
     "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
 
diff --git a/opam b/opam
new file mode 100644
index 0000000..0ee6905
--- /dev/null
+++ b/opam
@@ -0,0 +1,37 @@
+opam-version: "1.2"
+maintainer:   "she...@alum.mit.edu"
+authors: [
+              "David Sheets"
+              "Anil Madhavapeddy"
+              "Hugo Heuzard"
+]
+license:      "ISC"
+homepage:     "https://github.com/mirage/ocaml-ipaddr";
+bug-reports:  "https://github.com/mirage/ocaml-ipaddr/issues";
+dev-repo:     "https://github.com/mirage/ocaml-ipaddr.git";
+
+tags: [
+  "org:mirage"
+  "org:xapi-project"
+]
+
+build: [
+  ["ocaml" "setup.ml" "-configure" "--prefix" prefix 
"--%{ounit:enable}%-tests"]
+  [make "build"]
+]
+build-test: [
+  [make "test"]
+]
+install: [
+  [make "install"]
+]
+remove: [
+  ["ocamlfind" "remove" "ipaddr"]
+]
+depends: [
+  "ocamlfind" {build}
+  "base-bytes"
+  "sexplib"
+  "type_conv"
+  "ounit" {test}
+]
diff --git a/setup.ml b/setup.ml
index a2a7065..47f0e05 100644
--- a/setup.ml
+++ b/setup.ml
@@ -1,7 +1,7 @@
 (* setup.ml generated for the first time by OASIS v0.4.1 *)
 
 (* OASIS_START *)
-(* DO NOT EDIT (digest: 8ec35ea28792cf2fc60fcb42bac9ec41) *)
+(* DO NOT EDIT (digest: 2fbdd337da5b6f4d5fab124a689fa8bb) *)
 (*
    Regenerated by OASIS v0.4.4
    Visit http://oasis.forge.ocamlcore.org for more information and
@@ -6816,7 +6816,7 @@ let setup_t =
           alpha_features = [];
           beta_features = [];
           name = "ipaddr";
-          version = "2.5.0";
+          version = "2.6.0";
           license =
             OASISLicense.DEP5License
               (OASISLicense.DEP5Unit
@@ -6903,6 +6903,7 @@ let setup_t =
                       bs_compiled_object = Best;
                       bs_build_depends =
                         [
+                           FindlibPackage ("bytes", None);
                            FindlibPackage ("sexplib", None);
                            FindlibPackage ("sexplib.syntax", None)
                         ];
@@ -7029,7 +7030,7 @@ let setup_t =
        };
      oasis_fn = Some "_oasis";
      oasis_version = "0.4.4";
-     oasis_digest = Some "ҩ\142�P�\030�z�\r7��\006g";
+     oasis_digest = Some "\197k\244P\254\181\140\254\170Y\173\165\195xTr";
      oasis_exec = None;
      oasis_setup_args = [];
      setup_update = false
@@ -7037,6 +7038,6 @@ let setup_t =
 
 let setup () = BaseSetup.setup setup_t;;
 
-# 7041 "setup.ml"
+# 7042 "setup.ml"
 (* OASIS_STOP *)
 let () = setup ();;

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-ocaml-maint/packages/ocaml-ipaddr.git

_______________________________________________
Pkg-ocaml-maint-commits mailing list
Pkg-ocaml-maint-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ocaml-maint-commits

Reply via email to