001 // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org)
002 // The Molly framework is freely distributable under the terms of an
003 // MIT-style license. For details, see the molly pages web site at:
004 // http://www.mollypages.org/. Use, modify, have fun !
005
006 package fc.net;
007
008 import java.io.*;
009 import java.util.*;
010 import java.util.regex.*;
011 import java.nio.*;
012 import java.nio.channels.*;
013 import java.net.*;
014
015 import fc.io.*;
016 import fc.util.*;
017
018 /**
019 Network Interface Card related utility methods. Many of these
020 methods are specific to ethernet type nic's.
021
022 @author hursh jain
023 **/
024 public class NIC
025 {
026 //for internal debugging
027 private static boolean dbg = false;
028 static String linesep = IOUtil.LINE_SEP;
029
030 /**
031 Returns a Map containing an IP address as the key and
032 a {@link NIC.NICInfo} object as the value. Returns <tt>null</tt> if
033 the platform type is not supported.
034 <p>
035 <b>Note 1:</b> Requires a NT based system (NT, 2000, XP or later) if
036 running on windows. (this call will not work for lesser versions of
037 windows).<br>
038 <b>Note 2:</b> An english locale is needed for this method to work
039 properly (because we parse for certain english words to extract the
040 results).
041 **/
042 public static Map getMAC()
043 {
044 Platform p = Platform.getPlatform();
045 try {
046 if (p == p.WINDOWS) return getWindowsMA();
047 else if (p == p.LINUX) return getLinuxMA();
048 else if (p == p.OSX) return getOSXMA();
049
050 //we presume that linux stype ifconfig works identically
051 //on other plaforms. This of course is dicey at best.
052 //But I don't have no steeenkin bsd etc to test on.
053
054 else if (p == p.FREEBSD) return getLinuxMA();
055 else if (p == p.OPENBSD) return getLinuxMA();
056 }
057 catch (IOException e) {
058 e.printStackTrace();
059 }
060 return null;
061 }
062
063 private static Map getWindowsMA() throws IOException
064 {
065 Map macs = new HashMap();
066 Process p = Runtime.getRuntime().exec("ipconfig /all");
067 InputStream in = p.getInputStream();
068 try {
069 String result = IOUtil.inputStreamToString(in, true);
070 if (dbg) System.out.println("getWindowsMA(): " + linesep + "--------------- result ------------ " + linesep + result + linesep + "--------------------------------");
071
072 //for some reason ^$ does not work properly (for blank lines)
073 //even when multiline mode is chosen
074
075 Pattern pat = Pattern.compile(
076 "(?i)(?m)(?s)Ethernet\\s+adapter\\s+(.*?):.*?" +
077 "Physical\\s+Address.*?:\\s*([a-zA-Z0-9\\-]*).*?" +
078 "NetBIOS.*?:\\s*\\w*"
079 );
080
081 Pattern ip_pat = Pattern.compile(
082 "(?i)(?m)IP\\s+Address.*?:\\s+(.+?)$"
083 );
084 Matcher matcher = pat.matcher(result);
085 while (matcher.find()) {
086 if (dbg) System.out.println("getWindowsMA(): found: " + matcher.group(0));
087 String name = matcher.group(1);
088 String mac = matcher.group(2);
089 Matcher ipmatcher = ip_pat.matcher(matcher.group(0));
090 while (ipmatcher.find()) {
091 String ip = ipmatcher.group(1);
092 if (dbg) System.out.println("ip=" + ip + "; mac=" + mac + "; name=" + name);
093 NICInfo nicinfo = new NICInfo(name, mac);
094 macs.put(ip, nicinfo);
095 }
096 }
097 }
098 finally {
099 if ( in != null ) in.close();
100 }
101 return macs;
102 }
103
104 private static Map getLinuxMA() throws IOException
105 {
106 Map macs = new HashMap();
107 Process p = Runtime.getRuntime().exec("ifconfig");
108 InputStream in = p.getInputStream();
109 try {
110 /*
111 //this should give us the entire input size but does NOT
112 //- instead returns 0 !
113 int resultlen = in.available();
114 if (dbg) System.out.println("resultlen=" + resultlen);
115 ReadableByteChannel bytechan = Channels.newChannel(in);
116 ByteBuffer bytebuf = ByteBuffer.allocate(resultlen);
117 bytechan.read(bytebuf);
118 bytebuf.rewind();
119 if (dbg) System.out.println("ByteBuffer=" + bytebuf);
120 CharBuffer cbuf = bytebuf.asCharBuffer();
121 if (dbg) System.out.println("CharBuffer=" + cbuf);
122 */
123
124 String result = IOUtil.inputStreamToString(in, true);
125
126 String pat =
127 "(?s)(?m)(?i)(eth.*?)\\s+.+?HWaddr\\s([a-zA-Z0-9:\\-]*).*?addr:(.+?)\\s";
128
129 Pattern linux_ifconfig_1_42 = Pattern.compile(pat);
130 Matcher matcher = linux_ifconfig_1_42.matcher(result);
131 while (matcher.find()) {
132 String name = matcher.group(1);
133 String mac = matcher.group(2);
134 String ip = matcher.group(3);
135 if (dbg) System.out.println("getLinuxMA(): found: " + matcher.group(0));
136 if (dbg) System.out.println("ip=" + ip + "; mac=" + mac + "; name=" + name);
137 NICInfo nicinfo = new NICInfo(name, mac);
138 macs.put(ip, nicinfo);
139 }
140 }
141 finally {
142 if ( in != null ) in.close();
143 }
144 return macs;
145 }
146
147
148 private static Map getOSXMA() throws IOException
149 {
150 Map macs = new HashMap();
151 Process p = Runtime.getRuntime().exec("ifconfig");
152 InputStream in = p.getInputStream();
153 try {
154 String result = IOUtil.inputStreamToString(in, true);
155 String pat = "(?s)(?m)(?i)(en\\d+):.+?.*?status.*?$";
156
157 Pattern osx = Pattern.compile(pat);
158 Matcher matcher = osx.matcher(result);
159
160 Pattern ip_pat = Pattern.compile( "(?i)inet\\s+([0-9.]+)\\s*" );
161 Pattern eth_pat = Pattern.compile( "(?i)ether\\s+([a-zA-Z0-9:\\-]*)\\s*" );
162
163 while (matcher.find())
164 {
165 String name = matcher.group(1);
166
167 if (dbg) {
168 System.out.println("\n\n=========found: group[0]===========");
169 System.out.println(matcher.group(0));
170 System.out.println("\n==================");
171 }
172
173 String mac = null;
174 String ip = null;
175
176 Matcher ip_matcher = ip_pat.matcher(matcher.group(0));
177 Matcher eth_matcher = eth_pat.matcher(matcher.group(0));
178
179 if (ip_matcher.find()) {
180 ip = ip_matcher.group(1);
181 }
182
183 if (eth_matcher.find()) {
184 mac = eth_matcher.group(1);
185 }
186
187 if (dbg) System.out.println("ip=" + ip + "; mac=" + mac + "; name=" + name);
188
189 if (ip != null && mac != null) {
190 NICInfo nicinfo = new NICInfo(name, mac);
191 macs.put(ip, nicinfo);
192 }
193 }
194 }
195 finally {
196 if ( in != null ) in.close();
197 }
198 return macs;
199 }
200
201 public static void main(String[] args) throws Exception
202 {
203 Args myargs = new Args(args);
204 if (myargs.flagExists("debug")) {
205 dbg = true;
206 }
207 System.out.println("[1] Mac Addresses: " + getMAC());
208
209 System.out.println("\n[2] Using java networkinterface methods");
210 Enumeration<NetworkInterface> infs = NetworkInterface.getNetworkInterfaces();
211 List list = Collections.list(infs);
212 for (int n = 0; n < list.size(); n++) {
213 NetworkInterface inf = (NetworkInterface) list.get(n);
214 System.out.println(
215 "name="+inf.getName()
216 +";ip="+Collections.list(inf.getInetAddresses())
217 +";hw="+inf.getHardwareAddress()
218 +";up="+inf.isUp());
219 }
220 }
221
222 /**
223 Contains information about IP addresses and the associated
224 interface names and MAC address. More than one IP address
225 can be associated with the same interface.
226 **/
227 public static class NICInfo
228 {
229 String interfaceName;
230 String mac;
231
232 NICInfo(String interfaceName, String mac) {
233 this.interfaceName = interfaceName;
234 this.mac = mac;
235 }
236 /**
237 returns the name of the interface. This name may not
238 be the same as the name returned by {@link NetworkInterface#getName}
239 (especially on windows).
240 **/
241 public String getInterfaceName() { return interfaceName; }
242
243 /** returns the MAC address of the interface **/
244 public String getMACAddress() { return mac; }
245
246 public String toString() {
247 return "[NICInfo: name=" + interfaceName + "; MAC=" + mac + "]";
248 }
249 } //~class NICInfo
250
251
252 } //~class NIC