KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > net > EphemeralPorts


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.net;
5
6 import com.tc.process.StreamCollector;
7 import com.tc.util.runtime.Os;
8
9 import java.io.BufferedReader JavaDoc;
10 import java.io.File JavaDoc;
11 import java.io.FileInputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InputStreamReader JavaDoc;
14 import java.io.StringBufferInputStream JavaDoc;
15 import java.io.StringReader JavaDoc;
16 import java.util.Properties JavaDoc;
17 import java.util.regex.Matcher JavaDoc;
18 import java.util.regex.Pattern JavaDoc;
19
20 // http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html can tell you alot about what this class is about
21

22 public class EphemeralPorts {
23
24   private static Range range = null;
25
26   public synchronized static Range getRange() {
27     if (range == null) {
28       range = findRange();
29     }
30     return range;
31   }
32
33   private static Range findRange() {
34     if (Os.isLinux()) { return new Linux().getRange(); }
35     if (Os.isSolaris()) { return new Solaris().getRange(); }
36     if (Os.isMac()) { return new Mac().getRange(); }
37     if (Os.isWindows()) { return new Windows().getRange(); }
38
39     throw new AssertionError JavaDoc("No support for this OS: " + Os.getOsName());
40   }
41
42   public static class Range {
43     private final int upper;
44     private final int lower;
45
46     private Range(int lower, int upper) {
47       this.lower = lower;
48       this.upper = upper;
49     }
50
51     public int getUpper() {
52       return upper;
53     }
54
55     public int getLower() {
56       return lower;
57     }
58
59     public String JavaDoc toString() {
60       return lower + " " + upper;
61     }
62
63   }
64
65   private interface RangeGetter {
66     Range getRange();
67   }
68
69   private static class Solaris implements RangeGetter {
70     public Range getRange() {
71       Exec exec = new Exec(new String JavaDoc[] { "/usr/sbin/ndd", "/dev/tcp", "tcp_smallest_anon_port" });
72       final String JavaDoc lower;
73       try {
74         lower = exec.execute(Exec.STDOUT);
75       } catch (Exception JavaDoc e) {
76         throw new RuntimeException JavaDoc(e);
77       }
78
79       exec = new Exec(new String JavaDoc[] { "/usr/sbin/ndd", "/dev/tcp", "tcp_largest_anon_port" });
80       final String JavaDoc upper;
81       try {
82         upper = exec.execute(Exec.STDOUT);
83       } catch (Exception JavaDoc e) {
84         throw new RuntimeException JavaDoc(e);
85       }
86
87       int low = Integer.parseInt(lower.replaceAll("\n", ""));
88       int high = Integer.parseInt(upper.replaceAll("\n", ""));
89
90       return new Range(low, high);
91     }
92   }
93
94   private static class Windows implements RangeGetter {
95     private static final int DEFAULT_LOWER = 1024;
96     private static final int DEFAULT_UPPER = 5000;
97
98     public Range getRange() {
99       try {
100         // use reg.exe if available to see if MaxUserPort is tweaked
101
String JavaDoc sysRoot = Os.findWindowsSystemRoot();
102         if (sysRoot != null) {
103           File JavaDoc regExe = new File JavaDoc(new File JavaDoc(sysRoot, "system32"), "reg.exe");
104           if (regExe.exists()) {
105             String JavaDoc[] cmd = new String JavaDoc[] { regExe.getAbsolutePath(), "query",
106                 "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "/v", "MaxUserPort" };
107             Exec exec = new Exec(cmd);
108             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new StringReader JavaDoc(exec.execute(Exec.STDOUT)));
109
110             Pattern JavaDoc pattern = Pattern.compile("^.*MaxUserPort\\s+REG_DWORD\\s+0x(\\p{XDigit}+)");
111             String JavaDoc line = null;
112             while ((line = reader.readLine()) != null) {
113               Matcher JavaDoc matcher = pattern.matcher(line);
114               if (matcher.matches()) {
115                 int val = Integer.parseInt(matcher.group(1), 16);
116                 return new Range(DEFAULT_LOWER, val);
117               }
118             }
119           }
120         }
121       } catch (Exception JavaDoc e) {
122         e.printStackTrace();
123       }
124
125       return new Range(DEFAULT_LOWER, DEFAULT_UPPER);
126     }
127   }
128
129   private static class Mac implements RangeGetter {
130     public Range getRange() {
131       Exec exec = new Exec(new String JavaDoc[] { "sysctl", "net.inet.ip.portrange" });
132       final String JavaDoc output;
133       try {
134         output = exec.execute(Exec.STDOUT);
135       } catch (Exception JavaDoc e) {
136         throw new RuntimeException JavaDoc(e);
137       }
138
139       Properties JavaDoc props = new Properties JavaDoc();
140       try {
141         props.load(new StringBufferInputStream JavaDoc(output));
142       } catch (IOException JavaDoc e) {
143         throw new RuntimeException JavaDoc(e);
144       }
145
146       int low = Integer.parseInt(props.getProperty("net.inet.ip.portrange.hifirst"));
147       int high = Integer.parseInt(props.getProperty("net.inet.ip.portrange.hilast"));
148
149       return new Range(low, high);
150     }
151   }
152
153   private static class Linux implements RangeGetter {
154     private static final String JavaDoc source = "/proc/sys/net/ipv4/ip_local_port_range";
155
156     public Range getRange() {
157       File JavaDoc src = new File JavaDoc(source);
158       if (!src.exists() || !src.canRead()) { throw new RuntimeException JavaDoc("Cannot access " + source); }
159
160       BufferedReader JavaDoc reader = null;
161       try {
162         reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(new FileInputStream JavaDoc(src)));
163         String JavaDoc data = reader.readLine();
164         String JavaDoc[] parts = data.split("[ \\t]");
165         if (parts.length != 2) { throw new RuntimeException JavaDoc("Wrong number of tokens (" + parts.length + ") in " + data); }
166
167         int low = Integer.parseInt(parts[0]);
168         int high = Integer.parseInt(parts[1]);
169
170         return new Range(low, high);
171       } catch (IOException JavaDoc ioe) {
172         throw new RuntimeException JavaDoc(ioe);
173       } finally {
174         if (reader != null) {
175           try {
176             reader.close();
177           } catch (IOException JavaDoc e) {
178             //
179
}
180         }
181       }
182     }
183   }
184
185   private static class Exec {
186     static final int STDOUT = 1;
187     static final int STDERR = 2;
188
189     private final String JavaDoc[] cmd;
190
191     Exec(String JavaDoc cmd[]) {
192       this.cmd = cmd;
193     }
194
195     String JavaDoc execute(int stream) throws IOException JavaDoc, InterruptedException JavaDoc {
196       if ((stream != STDOUT) && (stream != STDERR)) { throw new IllegalArgumentException JavaDoc("bad stream: " + stream); }
197
198       Process JavaDoc proc = Runtime.getRuntime().exec(cmd);
199       proc.getOutputStream().close();
200
201       StreamCollector out = new StreamCollector(proc.getInputStream());
202       StreamCollector err = new StreamCollector(proc.getErrorStream());
203       out.start();
204       err.start();
205
206       proc.waitFor(); // ignores process exit code
207

208       out.join();
209       err.join();
210
211       if (stream == STDOUT) { return out.toString(); }
212       return err.toString();
213     }
214
215   }
216
217 }
218
Popular Tags