source: 3thparty/jmessenger/src/nu/fw/jeti/plugins/filetransfer/socks5/jsocks/InetRange.java @ 3952

Revision 3952, 13.2 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1710 - Adicao do codigo fonte java do componente jmessenger(jabberit_messenger)

  • Property svn:executable set to *
Line 
1package nu.fw.jeti.plugins.filetransfer.socks5.jsocks;
2import java.net.InetAddress;
3import java.net.UnknownHostException;
4import java.util.*;
5
6/**
7 * Class InetRange provides the means of defining the range of inetaddresses.
8 * It's used by Proxy class to store and look up addresses of machines, that
9 * should be contacted directly rather then through the proxy.
10 * <P>
11 * InetRange provides several methods to add either standalone addresses, or
12 * ranges (e.g. 100.200.300.0:100.200.300.255, which covers all addresses
13 * on on someones local network). It also provides methods for checking wether
14 * given address is in this range. Any number of ranges and standalone
15 * addresses can be added to the range.
16 */
17public class InetRange implements Cloneable{
18
19    Hashtable host_names;
20    Vector all;
21    Vector end_names;
22
23    boolean useSeparateThread = true;
24
25    /**
26     * Creates the empty range.
27     */
28    public InetRange(){
29      all = new Vector();
30      host_names = new Hashtable();
31      end_names = new Vector();
32    }
33
34    /**
35     *  Adds another host or range to this range.
36        The String can be one of those:
37        <UL>
38        <li> Host name. eg.(Athena.myhost.com or 45.54.56.65)
39       
40        <li> Range in the form .myhost.net.au <BR>
41             In which case anything that ends with .myhost.net.au will
42             be considered in the range.
43
44        <li> Range in the form ddd.ddd.ddd. <BR>
45             This will be treated as range ddd.ddd.ddd.0 to ddd.ddd.ddd.255.
46             It is not necessary to specify 3 first bytes you can use just
47             one or two. For example 130. will cover address between 130.0.0.0
48             and 13.255.255.255.
49
50        <li> Range in the form host_from[: \t\n\r\f]host_to. <br>
51             That is two hostnames or ips separated by either whitespace
52             or colon.
53        </UL>
54     */
55    public synchronized boolean add(String s){
56      if(s == null) return false;
57
58      s = s.trim();
59      if(s.length() == 0) return false;
60
61      Object[] entry;
62
63      if(s.charAt(s.length()-1) == '.'){
64         //thing like: 111.222.33.
65         //it is being treated as range 111.222.33.000 - 111.222.33.255
66
67         int[] addr = ip2intarray(s);
68         long from,to;
69         from = to = 0;
70
71         if(addr == null) return false;
72         for(int i = 0; i< 4;++i){
73            if(addr[i]>=0)
74              from += (((long)addr[i]) << 8*(3-i));
75            else{
76              to = from;
77              while(i<4)
78                to += 255l << 8*(3-i++);
79              break;
80            }
81         }
82         entry = new Object[] {s,null,new Long(from),new Long(to)};
83         all.addElement(entry);
84
85      }else if(s.charAt(0) == '.'){
86         //Thing like: .myhost.com
87
88         end_names.addElement(s);
89         all.addElement(new Object[]{s,null,null,null});
90      }else{
91         StringTokenizer tokens = new StringTokenizer(s," \t\r\n\f:");
92         if(tokens.countTokens() > 1){
93           entry = new Object[] {s,null,null,null};
94           resolve(entry,tokens.nextToken(),tokens.nextToken());
95           all.addElement(entry);
96         }else{
97           entry = new Object[] {s,null,null,null};
98           all.addElement(entry);
99           host_names.put(s,entry);
100           resolve(entry);
101         }
102
103      }
104
105      return true;
106    }
107
108    /**
109     *  Adds another ip for this range.
110        @param ip IP os the host which should be added to this range.
111     */
112    public synchronized void add(InetAddress ip){
113       long from, to;
114       from = to = ip2long(ip);
115       all.addElement(new Object[]{ip.getHostName(),ip,new Long(from),
116                                                       new Long(to)});
117    }
118
119    /**
120     *  Adds another range of ips for this range.Any host with ip address
121        greater than or equal to the address of from and smaller than or equal
122        to the address of to will be included in the range.
123        @param from IP from where range starts(including).
124        @param to   IP where range ends(including).
125     */
126    public synchronized void add(InetAddress from,InetAddress to){
127       all.addElement(new Object[]{from.getHostAddress()+":"+to.getHostAddress()
128                            ,null,new Long(ip2long(from)),
129                                  new Long(ip2long(to))});
130    }
131
132    /**
133     * Checks wether the givan host is in the range. Attempts to resolve
134       host name if required.
135       @param host Host name to check.
136       @return true If host is in the range, false otherwise.
137     * @see InetRange#contains(String,boolean)
138     */
139    public synchronized boolean contains(String host){
140       return contains(host,true);
141    }
142
143    /**
144     *  Checks wether the given host is in the range.
145     *  <P>
146     *  Algorithm: <BR>
147     *  <ol>
148     *  <li>Look up if the hostname is in the range (in the Hashtable).
149     *  <li>Check if it ends with one of the speciefied endings.
150     *  <li>Check if it is ip(eg.130.220.35.98). If it is check if it is
151     *      in the range.
152     *  <li>If attemptResolve is true, host is name, rather than ip, and
153     *      all previous attempts failed, try to resolve the hostname, and
154     *      check wether the ip associated with the host is in the range.It
155     *      also repeats all previos steps with the hostname obtained from
156     *      InetAddress, but the name is not allways the full name,it is
157     *      quite likely to be the same. Well it was on my machine.
158     *  </ol>
159       @param host Host name to check.
160       @param attemptResolve Wether to lookup ip address which corresponds
161       to the host,if required.
162       @return true If host is in the range, false otherwise.
163     */
164    public synchronized boolean contains(String host,boolean attemptResolve){
165       if(all.size() ==0) return false; //Empty range
166
167       host = host.trim();
168       if(host.length() == 0) return false;
169
170       if(checkHost(host)) return true;
171       if(checkHostEnding(host)) return true;
172
173       long l = host2long(host);
174       if(l >=0) return contains(l);
175
176       if(!attemptResolve) return false;
177
178       try{
179          InetAddress ip = InetAddress.getByName(host);
180          return contains(ip);
181       }catch(UnknownHostException uhe){
182
183       }
184
185       return false;
186    }
187
188    /**
189     * Checks wether the given ip is in the range.
190       @param ip Address of the host to check.
191       @return true If host is in the range, false otherwise.
192     */
193    public synchronized boolean contains(InetAddress ip){
194       if(checkHostEnding(ip.getHostName())) return true;
195       if(checkHost(ip.getHostName())) return true;
196       return contains(ip2long(ip));
197    }
198    /**
199       Get all entries in the range as strings. <BR>
200       These strings can be used to delete entries from the range
201       with remove function.
202       @return Array of entries as strings.
203       @see InetRange#remove(String)
204     */
205    public synchronized String[] getAll(){
206       int size = all.size();
207       Object entry[];
208       String all_names[] = new String[size];
209
210       for(int i=0;i<size;++i){
211          entry = (Object[]) all.elementAt(i);
212          all_names[i] = (String) entry[0];
213       }
214       return all_names;
215    }
216    /**
217      Removes an entry from this range.<BR>
218      @param s Entry to remove.
219      @return true if successfull.
220     */
221    public synchronized boolean remove(String s){
222      Enumeration e = all.elements();
223      while(e.hasMoreElements()){
224        Object[] entry = (Object[]) e.nextElement();
225        if(s.equals(entry[0])){
226          all.removeElement(entry);
227          end_names.removeElement(s);
228          host_names.remove(s);
229          return true;
230        }
231      }
232      return false;
233    }
234
235    /** Get string representaion of this Range.*/
236    public String toString(){
237       String all[] = getAll();
238       if(all.length == 0) return "";
239
240       String s = all[0];
241       for(int i=1;i<all.length;++i)
242          s += "; "+all[i];
243       return s;
244    }
245
246    /** Creates a clone of this Object*/
247    public Object clone(){
248      InetRange new_range = new InetRange();
249      new_range.all = (Vector)all.clone();
250      new_range.end_names = (Vector) end_names.clone();
251      new_range.host_names = (Hashtable)host_names.clone();
252      return new_range;
253    }
254
255
256//Private methods
257/////////////////
258    /**
259     * Same as previous but used internally, to avoid
260     * unnecessary convertion of IPs, when checking subranges
261     */
262    private synchronized boolean contains(long ip){
263       Enumeration e = all.elements();
264       while(e.hasMoreElements()){
265         Object[] obj = (Object[]) e.nextElement();
266         Long from = obj[2]==null?null:(Long)obj[2];
267         Long to   = obj[3]==null?null:(Long)obj[3];
268         if(from != null && from.longValue()<= ip
269                         && to.longValue() >= ip) return true;
270
271       }
272       return false;
273    }
274
275    private boolean checkHost(String host){
276       return host_names.containsKey(host);
277    }
278    private boolean checkHostEnding(String host){
279       Enumeration e = end_names.elements();
280       while(e.hasMoreElements()){
281          if(host.endsWith((String) e.nextElement())) return true;
282       }
283       return false;
284    }
285    private void resolve(Object[] entry){
286       //First check if it's in the form ddd.ddd.ddd.ddd.
287       long ip = host2long((String) entry[0]);
288       if(ip >= 0){
289         entry[2] = entry[3] = new Long(ip);
290       }else{
291         InetRangeResolver res = new InetRangeResolver(entry);
292         res.resolve(useSeparateThread);
293       }
294    }
295    private void resolve(Object[] entry,String from,String to){
296       long f,t;
297       if((f=host2long(from))>= 0 && (t=host2long(to)) >= 0){
298         entry[2] = new Long(f);
299         entry[3] = new Long(t);
300       }else{
301         InetRangeResolver res = new InetRangeResolver(entry,from,to);
302         res.resolve(useSeparateThread);
303       }
304    }
305
306
307
308//Class methods
309///////////////
310
311    //Converts ipv4 to long value(unsigned int)
312    ///////////////////////////////////////////
313    static long ip2long(InetAddress ip){
314        long l=0;
315        byte[] addr = ip.getAddress();
316
317        if(addr.length ==4){ //IPV4
318          for(int i=0;i<4;++i)
319             l += (((long)addr[i] &0xFF) << 8*(3-i));
320        }else{ //IPV6
321          return 0;  //Have no idea how to deal with those
322        }
323        return l;
324    }
325
326
327    long host2long(String host){
328      long ip=0;
329
330      //check if it's ddd.ddd.ddd.ddd
331      if(!Character.isDigit(host.charAt(0))) return -1;
332
333      int[] addr = ip2intarray(host);
334      if(addr == null) return -1;
335
336      for(int i=0;i<addr.length;++i)
337          ip += ((long)(addr[i]>=0 ? addr[i] : 0)) << 8*(3-i);
338
339      return ip;
340    }
341
342    static int[] ip2intarray(String host){
343       int[] address = {-1,-1,-1,-1};
344       int i=0;
345       StringTokenizer tokens = new StringTokenizer(host,".");
346       if(tokens.countTokens() > 4) return null;
347       while(tokens.hasMoreTokens()){
348         try{
349           address[i++] = Integer.parseInt(tokens.nextToken()) & 0xFF;
350         }catch(NumberFormatException nfe){
351            return null;
352         }
353
354       }
355       return address;
356    }
357
358
359/*
360//* This was the test main function
361//**********************************
362 
363    public static void main(String args[])throws UnknownHostException{
364       int i;
365
366       InetRange ir = new InetRange();
367
368
369       for(i=0;i<args.length;++i){
370         System.out.println("Adding:" + args[i]);
371         ir.add(args[i]);
372       }
373
374       String host;
375       java.io.DataInputStream din = new java.io.DataInputStream(System.in);
376       try{
377          host = din.readLine();
378          while(host!=null){
379            if(ir.contains(host)){
380              System.out.println("Range contains ip:"+host);
381            }else{
382              System.out.println(host+" is not in the range");
383            }
384            host = din.readLine();
385          }
386       }catch(java.io.IOException io_ex){
387          io_ex.printStackTrace();
388       }
389    }
390********************/
391
392    class InetRangeResolver implements Runnable{
393
394        Object[] entry;
395
396        String from, to;
397
398        InetRangeResolver(Object[] entry){
399            this.entry = entry;
400            from = to = null;
401        }
402        InetRangeResolver(Object[] entry,String from,String to){
403            this.entry = entry;
404            this.from  = from;
405            this.to    = to;
406        }
407        public final void resolve(){
408            resolve(true);
409        }
410        public final void resolve(boolean inSeparateThread){
411            if(inSeparateThread){
412                Thread t = new Thread(this);
413                t.start();
414            }else
415                run();
416
417        }
418        public void run(){
419            try{
420                if(from == null){
421                    InetAddress ip = InetAddress.getByName((String) entry[0]);
422                    entry[1] = ip;
423                    Long l = new Long(InetRange.ip2long(ip));
424                    entry[2] = entry[3] = l;
425                }else{
426                    InetAddress f = InetAddress.getByName(from);
427                    InetAddress t = InetAddress.getByName(to);
428                    entry[2] = new Long(InetRange.ip2long(f));
429                    entry[3] = new Long(InetRange.ip2long(t));
430
431                }
432            }catch(UnknownHostException uhe){
433                //System.err.println("Resolve failed for "+from+','+to+','+entry[0]);
434            }
435        }
436
437    }
438}
439
440
Note: See TracBrowser for help on using the repository browser.