@@ -23,158 +23,8 @@ module String = String_base
2323(* ****************************************************************************)
2424
2525module Ip_address = struct
26-
27- type t =
28- | IPv4 of int32
29- | IPv6 of int64 * int64
30-
31- exception Invalid_ipaddress of string
32-
33- let parse s =
34- let s = String. lowercase s in
35- let n = String. length s in
36- let is6 = String. contains s ':' in
37- let failwith fmt = Printf. ksprintf (fun s -> raise (Invalid_ipaddress s)) fmt in
38-
39- let rec parse_hex i accu =
40- match (if i < n then s.[i] else ':' ) with
41- | '0' ..'9' as c -> parse_hex (i+ 1 ) (16 * accu+ (int_of_char c)- 48 )
42- | 'a' ..'f' as c -> parse_hex (i+ 1 ) (16 * accu+ (int_of_char c)- 87 )
43- | _ -> (i, accu)
44- in
45- let rec parse_dec i accu =
46- match (if i < n then s.[i] else '.' ) with
47- | '0' ..'9' as c -> parse_dec (i+ 1 ) (10 * accu+ (int_of_char c)- 48 )
48- | _ -> (i, accu)
49- in
50- let rec next_is_dec i =
51- if i < n then
52- match s.[i] with
53- | ':' -> false
54- | '.' -> true
55- | _ -> next_is_dec (i+ 1 )
56- else false
57- in
58- let rec parse_component i accu nb =
59- if i < n then
60- if next_is_dec i then
61- let (i1, a) = parse_dec i 0 in
62- if i1 = i || (i1 < n && s.[i1] <> '.' ) then failwith " invalid dot notation in %s (1)" s;
63- let (i2, b) = parse_dec (i1+ 1 ) 0 in
64- if i2 = i1 then failwith " invalid dot notation in %s (2)" s;
65- let component =
66- if a < 0 || a > 255 || b < 0 || b > 255 then
67- failwith " invalid dot notation in %s (3)" s
68- else (a lsl 8 ) lor b
69- in
70- if i2 < n-1 && (s.[i2] = ':' || s.[i2] = '.' ) then
71- parse_component (i2+ 1 ) (component::accu) (nb+ 1 )
72- else
73- (i2, component::accu, nb+ 1 )
74- else if s.[i] = ':' then
75- parse_component (i+ 1 ) ((- 1 )::accu) nb
76- else
77- let (i1, a) = parse_hex i 0 in
78- if a < 0 || a > 0xffff then failwith " invalid colon notation in %s" s;
79- if i1 = i then
80- (i, accu, nb)
81- else if i1 < n-1 && s.[i1] = ':' then
82- parse_component (i1+ 1 ) (a::accu) (nb+ 1 )
83- else
84- (i1, a::accu, nb+ 1 )
85- else
86- (i, accu, nb)
87- in
88-
89- let (i, addr_list, size_list) =
90- if 1 < n && s.[0 ] = ':' && s.[1 ] = ':' then
91- parse_component 2 [- 1 ] 0
92- else
93- parse_component 0 [] 0
94- in
95-
96- if size_list > 8 then failwith " too many components in %s" s;
97-
98- let maybe_mask =
99- if i < n && s.[i] = '/' then
100- let (i1, m) = parse_dec (i+ 1 ) 0 in
101- if i1 = i+ 1 || i1 < n || m < 0 || m > (if is6 then 128 else 32 ) then
102- failwith " invalid /n suffix in %s" s
103- else
104- Some m
105- else if i < n then
106- failwith " invalid suffix in %s (from index %i)" s i
107- else
108- None
109- in
110-
111- if is6 then
112- let (++) a b = Int64. logor (Int64. shift_left a 16 ) (Int64. of_int b) in
113- let normalized =
114- let rec aux_add n accu =
115- if n = 0 then accu else aux_add (n-1 ) (0 ::accu)
116- in
117- let rec aux_rev accu = function
118- | [] -> accu
119- | (-1 )::q -> aux_rev (aux_add (8 - size_list) accu) q
120- | a ::q -> aux_rev (a::accu) q
121- in
122- aux_rev [] addr_list
123- in
124- let maybe_mask = match maybe_mask with
125- | Some n when n > 64 ->
126- Some (IPv6 (Int64. minus_one, Int64. shift_left Int64. minus_one (128 - n)))
127- | Some n ->
128- Some (IPv6 (Int64. shift_left Int64. minus_one (64 - n), Int64. zero))
129- | None -> None
130- in
131- match normalized with
132- | [a; b; c; d; e; f; g; h] ->
133- IPv6 (Int64. zero ++ a ++ b ++ c ++ d,
134- Int64. zero ++ e ++ f ++ g ++ h), maybe_mask
135- | _ -> failwith " invalid IPv6 address: %s (%d components)" s (List. length normalized)
136- else
137- let (++) a b = Int32. logor (Int32. shift_left a 16 ) (Int32. of_int b) in
138- let maybe_mask = match maybe_mask with
139- | Some n ->
140- Some (IPv4 (Int32. shift_left Int32. minus_one (32 - n)))
141- | None -> None
142- in
143- match addr_list with
144- | [b; a] ->
145- IPv4 (Int32. zero ++ a ++ b), maybe_mask
146- | _ -> failwith " invalid IPv4 address: %s" s
147-
148-
149- let match_ip (base , mask ) ip =
150- match ip, base, mask with
151- | IPv4 a , IPv4 b , Some (IPv4 m ) -> Int32. logand a m = Int32. logand b m
152- | IPv4 a , IPv4 b , None -> a = b
153- | IPv6 (a1 ,a2 ), IPv6 (b1 ,b2 ), Some (IPv6 (m1 ,m2 )) ->
154- Int64. logand a1 m1 = Int64. logand b1 m1 &&
155- Int64. logand a2 m2 = Int64. logand b2 m2
156- | IPv6 (a1 ,a2 ), IPv6 (b1 ,b2 ), None -> a1 = b1 && a2 = b2
157- | IPv6 (a1,a2), IPv4 b, c
158- when a1 = 0L && Int64. logand a2 0xffffffff00000000L = 0xffff00000000L ->
159- (* might be insecure, cf
160- http://tools.ietf.org/internet-drafts/draft-itojun-v6ops-v4mapped-harmful-02.txt *)
161- let a = Int64. to_int32 a2 in
162- begin match c with
163- | Some (IPv4 m ) -> Int32. logand a m = Int32. logand b m
164- | Some (IPv6 _ ) -> invalid_arg " match_ip"
165- | None -> a = b
166- end
167- | _ -> false
168-
169- let network_of_ip ip mask4 (mask61 , mask62 ) = match ip with
170- | IPv4 a -> IPv4 (Int32. logand a mask4)
171- | IPv6 (a , b ) -> IPv6 (Int64. logand a mask61, Int64. logand b mask62)
172-
17326 exception No_such_host
17427
175- let inet6_addr_loopback =
176- fst (parse (Unix. string_of_inet_addr Unix. inet6_addr_loopback))
177-
17828 let get_inet_addr ?(v6 =false ) host =
17929 let rec aux = function
18030 | [] -> Lwt. fail No_such_host
@@ -186,22 +36,6 @@ module Ip_address = struct
18636 (Lwt_unix. getaddrinfo host " " options)
18737 aux
18838
189- (*
190- let getnameinfo ia p =
191- try
192- Lwt_unix.getnameinfo (Unix.ADDR_INET (ia, p)) [Unix.NI_NAMEREQD] >>= fun r ->
193- Lwt.return r.Unix.ni_hostname
194- with
195- | Not_found ->
196- let hs = Unix.string_of_inet_addr ia in
197- Lwt.return
198- (if String.length hs > 7 && String.sub hs 0 7 = "::ffff:"
199- then String.sub hs 7 (String.length hs - 7)
200- else if String.contains hs ':'
201- then "["^hs^"]"
202- else hs)
203-
204- *)
20539end
20640
20741(* ****************************************************************************)
0 commit comments