diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/common/commonOptions.ml ./src/daemon/common/commonOptions.ml
--- ./src/daemon/common/commonOptions.ml	2006-07-24 22:16:07.000000000 +0200
+++ ./src/daemon/common/commonOptions.ml	2006-07-27 23:37:39.000000000 +0200
@@ -296,6 +296,8 @@
 
 let ip_list_option = list_option Ip.option
 
+let ip_range_list_option = list_option Ip.range_option
+
 let int_list_option = list_option int_option
 
 let country_list_option = list_option string_option
@@ -326,6 +328,18 @@
       let list = String2.tokens s in
       List.map (fun ip -> Ip.of_string ip) list
   );
+
+  Options.set_string_wrappers ip_range_list_option
+    (fun list ->
+      List.fold_left (fun s ip ->
+	  Printf.sprintf "%s %s" (Ip.string_of_range ip) s
+      ) "" list
+  )
+  (fun s ->
+      let list = String2.tokens s in
+      List.map (fun ip -> Ip.range_of_string ip) list
+  );
+
   Options.set_string_wrappers int_list_option
     (fun list ->
       List.fold_left (fun s i ->
@@ -418,11 +432,40 @@
     ~desc: "Allowed IPs"
   "list of IP address allowed to connect to the core via telnet/GUI/WEB
 for internal command set: list separated by spaces
-example for internal command: set allowed_ips \"127.0.0.1 192.168.1.2\"
+example for internal command: set allowed_ips \"127.0.0.0/8 192.168.1.2\"
 or for editing the ini-file: list separated by semi-colon
-example for ini-file: allowed_ips = [ \"127.0.0.1\"; \"192.168.1.2\";]
-wildcard=255 ie: use 192.168.0.255 for 192.168.0.*"
-    ip_list_option [Ip.localhost]
+example for ini-file: allowed_ips = [ \"127.0.0.0/8\"; \"192.168.1.2\";]
+CIDR and range notations are supported: ie use 192.168.0.0/24 or 192.168.0.0-192.168.0.255 for 192.168.0.*"
+    ip_range_list_option [ Ip.RangeSingleIp Ip.localhost ]
+
+let allowed_ips_set = ref Ip_set.BL_Empty
+
+let _ =
+  option_hook allowed_ips (fun _ ->
+    let new_list = ref [] in
+    List.iter (fun i ->
+	let new_range =
+	  match i with
+	  | Ip.RangeSingleIp ip ->
+	    (let a, b, c, d = Ip.to_ints ip in
+	      match a = 255, b = 255, c = 255, d = 255 with
+	      |  true,  true,  true,  true -> Ip.RangeCIDR (Ip.null, 0)
+	      | false,  true,  true,  true -> Ip.RangeCIDR ((Ip.of_string (Printf.sprintf "%d.0.0.0" a)), 8)
+	      | false, false,  true,  true -> Ip.RangeCIDR ((Ip.of_string (Printf.sprintf "%d.%d.0.0" a b)), 16)
+	      | false, false, false,  true -> Ip.RangeCIDR ((Ip.of_string (Printf.sprintf "%d.%d.%d.0" a b c)), 24)
+	      | false, false, false, false -> i
+	      | _ -> i)
+	  | Ip.RangeRange (ip1, ip2) -> i
+	  | Ip.RangeCIDR (ip, shift) -> i
+	in
+	if i <> new_range then
+	  lprintf_nl "allowed_ips: converted %s to %s" (Ip.string_of_range i) (Ip.string_of_range new_range);
+	new_list := new_range :: !new_list
+    ) !!allowed_ips;
+    new_list := if !new_list = [] then [ Ip.localhost_range ] else List.rev !new_list;
+    if !new_list <> !!allowed_ips then allowed_ips =:= !new_list;
+    allowed_ips_set := (Ip_set.of_list !!allowed_ips))
+
 
 let gui_port =
   define_option current_section ["gui_port"]
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/driver/driverControlers.ml ./src/daemon/driver/driverControlers.ml
--- ./src/daemon/driver/driverControlers.ml	2006-07-21 21:56:24.000000000 +0200
+++ ./src/daemon/driver/driverControlers.ml	2006-07-27 23:36:00.000000000 +0200
@@ -591,7 +591,8 @@
             conn_width = 80;
             conn_height = 0;
           } in
-      if Ip.matches from_ip !!allowed_ips then begin
+	(match Ip_set.match_ip !allowed_ips_set from_ip with
+	| Some br -> 
         TcpBufferedSocket.prevent_close sock;
         TcpBufferedSocket.set_max_output_buffer sock !!interface_buffer;
         TcpBufferedSocket.set_reader sock (user_reader o telnet);
@@ -611,8 +612,8 @@
             "$cWelcome on mldonkey command-line$n\n\nUse $r?$n for help\n\n");
 
         after_telnet_output o sock
-	end
-      else begin
+
+	| None ->
         before_telnet_output o sock;
 	let reject_message =
 	  Printf.sprintf "Telnet connection from %s rejected (see allowed_ips setting)\n"
@@ -621,8 +622,7 @@
 	TcpBufferedSocket.write_string sock (dollar_escape o false reject_message);
 	shutdown sock Closed_connect_failed;
         if not !verbose_no_login then lprintf_n "%s" reject_message;
-	Unix.close s
-      end
+	Unix.close s)
 
   | _ -> ()
 
@@ -1523,12 +1523,13 @@
       bind_addr = Ip.to_inet_addr !!http_bind_addr ;
       port = !!http_port;
       requests = [];
-      addrs = !!allowed_ips;
+      addrs = Ip_set.of_list !!allowed_ips;
       use_ip_block_list = false;
       base_ref = "";
       default = http_handler http_options;
     } in
-  option_hook allowed_ips (fun _ -> config.addrs <- !!allowed_ips);
+  option_hook allowed_ips (fun _ ->
+    config.addrs <- Ip_set.of_list !!allowed_ips);
   ignore(find_port "http server" !!http_bind_addr http_port
       (Http_server.handler config));
   config.port <- !!http_port
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/daemon/driver/driverInterface.ml ./src/daemon/driver/driverInterface.ml
--- ./src/daemon/driver/driverInterface.ml	2006-07-20 17:30:21.000000000 +0200
+++ ./src/daemon/driver/driverInterface.ml	2006-07-27 23:36:00.000000000 +0200
@@ -1177,7 +1177,8 @@
     TcpServerSocket.CONNECTION (s, Unix.ADDR_INET (from_ip, from_port)) ->
       let from_ip = Ip.of_inet_addr from_ip in
       if not !verbose_no_login then lprintf_nl "GUI connection from %s" (Ip.to_string from_ip);
-      if Ip.matches from_ip !!allowed_ips then 
+      (match Ip_set.match_ip !allowed_ips_set from_ip with
+      |	Some br ->
         
         let module P = GuiProto in
         let token = create_token unlimited_connection_manager in
@@ -1204,11 +1205,10 @@
             close sock Closed_for_overflow);
         (* sort GUIs in increasing order of their num *)
         
-      else begin
+      | None ->
           if not !verbose_no_login then lprintf_nl "GUI connection from %s rejected (see allowed_ips setting)"
             (Ip.to_string from_ip);
-          Unix.close s
-        end
+          Unix.close s)
   | _ -> ()
         
 let gift_handler t event = 
@@ -1216,7 +1216,8 @@
     TcpServerSocket.CONNECTION (s, Unix.ADDR_INET (from_ip, from_port)) ->
       let from_ip = Ip.of_inet_addr from_ip in
       lprintf "Gift: Connection from %s\n" (Ip.to_string from_ip);
-      if Ip.matches from_ip !!allowed_ips then 
+      (match Ip_set.match_ip !allowed_ips_set from_ip with
+      | Some br ->
         
         let module P = GuiProto in
         let token = create_token unlimited_connection_manager in
@@ -1242,11 +1243,10 @@
             close sock Closed_for_overflow);
         (* sort GUIs in increasing order of their num *)
         
-      else begin
+      | None ->
           lprintf "Connection from IP %s not allowed\n"
             (Ip.to_string from_ip);
-          Unix.close s
-        end
+          Unix.close s)
   | _ -> ()
 
       
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/networks/bittorrent/bTTracker.ml ./src/networks/bittorrent/bTTracker.ml
--- ./src/networks/bittorrent/bTTracker.ml	2006-07-21 21:56:24.000000000 +0200
+++ ./src/networks/bittorrent/bTTracker.ml	2006-07-27 23:36:00.000000000 +0200
@@ -555,7 +555,7 @@
           bind_addr = if !!force_client_ip then Ip.to_inet_addr !!set_client_ip else Unix.inet_addr_any ;
           port = !!tracker_port;
           requests = [];
-          addrs = [ Ip.of_string "255.255.255.255" ];
+          addrs = Ip_set.of_list [ Ip.RangeCIDR (Ip.null, 0) ];
           base_ref = "";
 	  use_ip_block_list = true;
           default = http_handler;
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/net/http_server.ml ./src/utils/net/http_server.ml
--- ./src/utils/net/http_server.ml	2006-07-21 21:56:24.000000000 +0200
+++ ./src/utils/net/http_server.ml	2006-07-27 23:36:00.000000000 +0200
@@ -147,7 +147,7 @@
     bind_addr : Unix.inet_addr;
     mutable port : int;
     requests : (string * handler) list;
-    mutable addrs : Ip.t list;
+    mutable addrs : Ip_set.blocking_list;
     use_ip_block_list : bool;
     base_ref : string;
     default : handler;
@@ -830,7 +830,11 @@
     TcpServerSocket.CONNECTION (s, Unix.ADDR_INET(from_ip, from_port)) ->
     (* check here if ip is OK *)
       let from_ip = Ip.of_inet_addr from_ip in
-      let ip_is_allowed from_ip = Ip.matches from_ip config.addrs in
+      let ip_is_allowed from_ip =
+	match Ip_set.match_ip config.addrs from_ip with
+	| Some br -> true
+	| None -> false
+      in
       let ip_is_blocked from_ip =
 	if config.use_ip_block_list then
 	  match !Ip.banned from_ip with
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/net/http_server.mli ./src/utils/net/http_server.mli
--- ./src/utils/net/http_server.mli	2006-07-21 21:56:24.000000000 +0200
+++ ./src/utils/net/http_server.mli	2006-07-27 23:36:00.000000000 +0200
@@ -60,7 +60,7 @@
     bind_addr : Unix.inet_addr;
     mutable port : int;
     requests : (string * handler) list;
-    mutable addrs : Ip.t list;
+    mutable addrs : Ip_set.blocking_list;
     use_ip_block_list : bool;
     base_ref : string;
     default : handler;
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/net/ip.ml ./src/utils/net/ip.ml
--- ./src/utils/net/ip.ml	2006-07-14 15:24:24.000000000 +0200
+++ ./src/utils/net/ip.ml	2006-07-27 23:36:00.000000000 +0200
@@ -146,6 +146,15 @@
 
 let localhost = of_string "127.0.0.1"
 
+let mask_of_shift shift =
+  of_int64 (Int64.logand 0xffffffffL (Int64.shift_left 0xffffffffL (32 - shift)))
+
+let network_address ip mask =
+  of_int64 (Int64.logand (to_int64 ip) (to_int64 mask))
+
+let broadcast_address ip mask =
+  of_int64 (Int64.logor (to_int64 ip) (Int64.logand 0xffffffffL (Int64.lognot (to_int64 mask))))
+
 let to_sockaddr ip port =
   Unix.ADDR_INET (to_inet_addr ip, port)
 
@@ -378,3 +387,35 @@
 let addr_to_value ip = string_to_value (string_of_addr ip)
 
 let addr_option = define_option_class "Addr" value_to_addr addr_to_value
+
+type ip_range = 
+| RangeSingleIp of t
+| RangeRange of t * t
+| RangeCIDR of t * int 
+
+let localhost_range = RangeCIDR ((of_string "127.0.0.1"), 8)
+
+let single_ip = "\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)"
+let single_ip_regexp = Str.regexp ("^" ^ single_ip ^ "$")
+let range_regexp = Str.regexp ("^" ^ single_ip ^ "-" ^ single_ip ^ "$")
+let cidr_regexp = Str.regexp ("^" ^ single_ip ^ "/" ^ "\\([0-9]+\\)$")
+
+let string_of_range ip =
+  match ip with
+  | RangeSingleIp ip -> to_string ip
+  | RangeRange (ip1, ip2) -> Printf.sprintf "%s-%s" (to_string ip1) (to_string ip2)
+  | RangeCIDR (ip, shift) -> Printf.sprintf "%s/%d" (to_string ip) shift
+
+let range_of_string s =
+  if Str.string_match single_ip_regexp s 0 then
+    RangeSingleIp (of_string (Str.matched_group 1 s))
+  else if Str.string_match range_regexp s 0 then
+    RangeRange (of_string (Str.matched_group 1 s), of_string (Str.matched_group 2 s))
+  else if Str.string_match cidr_regexp s 0 then
+    RangeCIDR (of_string (Str.matched_group 1 s), int_of_string (Str.matched_group 2 s))
+  else failwith (Printf.sprintf "Unknown IP range syntax: %s" s)
+
+let value_to_iprange v = range_of_string (value_to_string v)
+let iprange_to_value ip = string_to_value (string_of_range ip)
+
+let range_option = define_option_class "Range" value_to_iprange iprange_to_value
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/net/ip.mli ./src/utils/net/ip.mli
--- ./src/utils/net/ip.mli	2006-03-29 17:41:33.000000000 +0200
+++ ./src/utils/net/ip.mli	2006-07-27 23:36:00.000000000 +0200
@@ -41,6 +41,11 @@
 val pred : t -> t
   
 val localhost : t
+
+val mask_of_shift : int -> t
+val network_address : t -> t -> t
+val broadcast_address : t -> t -> t
+
 val to_sockaddr : t -> int -> Unix.sockaddr
 
 val from_name : string -> t
@@ -76,3 +81,14 @@
   
 val allow_local_network : bool ref
   
+type ip_range =
+  RangeSingleIp of t | RangeRange of t * t | RangeCIDR of t * int 
+
+val localhost_range : ip_range
+
+val range_option : ip_range Options.option_class
+val value_to_iprange : Options.option_value -> ip_range
+val iprange_to_value : ip_range -> Options.option_value
+
+val range_of_string : string -> ip_range
+val string_of_range : ip_range -> string
diff -a -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -N -r -u ./src/utils/net/ip_set.ml ./src/utils/net/ip_set.ml
--- ./src/utils/net/ip_set.ml	2006-07-14 15:24:24.000000000 +0200
+++ ./src/utils/net/ip_set.ml	2006-07-27 23:36:00.000000000 +0200
@@ -50,6 +50,12 @@
   mutable blocking_hits: int
 }
 
+let dummy_range = {
+  blocking_description = unknown_description;
+  blocking_begin = Ip.null;
+  blocking_end = Ip.null;
+  blocking_hits = 0 }
+
 let store_blocking_descriptions = ref true
 
 (* Red-Black tree *)
@@ -290,39 +296,25 @@
     end
 
 let of_list l =
-  let rec of_list_aux l bl =
-    match l with
-	[] -> bl
-      | h :: q ->
-	  let range = match Ip.to_ints h with
-(* only the most standard usages of the old syntax are supported *)
-	      255, 255, 255, 255 -> 
-		{ blocking_description = unknown_description;
-		  blocking_begin = Ip.of_ints (0, 0, 0, 0);
-		  blocking_end = Ip.of_ints (255, 255, 255, 255);
-		  blocking_hits = 0 }
-	    | a, 255, 255, 255 -> 
-		{ blocking_description = unknown_description;
-		  blocking_begin = Ip.of_ints (a, 0, 0, 0);
-		  blocking_end = Ip.of_ints (a, 255, 255, 255);
-		  blocking_hits = 0 }
-	    | a, b, 255, 255 -> 
-		{ blocking_description = unknown_description;
-		  blocking_begin = Ip.of_ints (a, b, 0, 0);
-		  blocking_end = Ip.of_ints (a, b, 255,255);
-		  blocking_hits = 0 }
-	    | a, b, c, 255 -> 
-		{ blocking_description = unknown_description;
-		  blocking_begin = Ip.of_ints (a, b, c, 0);
-		  blocking_end = Ip.of_ints (a, b, c, 255);
-		  blocking_hits = 0 }
-	    | _ -> 
-		{ blocking_description = unknown_description;
-		  blocking_begin = h;
-		  blocking_end = h;
-		  blocking_hits = 0 } in
-	  of_list_aux q (add_range bl range) in
-  of_list_aux l BL_Empty
+  List.fold_left (fun acc r ->
+    let range =
+      match r with
+      | Ip.RangeSingleIp ip -> {
+	  dummy_range with
+	  blocking_begin = ip;
+	  blocking_end = ip }
+      | Ip.RangeRange (ip1, ip2) -> {
+	  dummy_range with
+	  blocking_begin = ip1;
+	  blocking_end = ip2 }
+      | Ip.RangeCIDR (ip, shift) ->
+	let mask = Ip.mask_of_shift shift in
+	{ dummy_range with
+	  blocking_begin = Ip.network_address ip mask;
+	  blocking_end = Ip.broadcast_address ip mask }
+    in 
+    add_range acc range
+  ) BL_Empty l
 
 let print_list buf bl =
   let rec print_list_aux bl =
