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 006package fc.net; 007 008import java.io.*; 009import java.util.*; 010import java.util.regex.*; 011import java.nio.*; 012import java.nio.channels.*; 013import java.net.*; 014 015import fc.io.*; 016import fc.util.*; 017 018/** 019Network Interface Card related utility methods. Many of these 020methods are specific to ethernet type nic's. 021 022@author hursh jain 023**/ 024public class NIC 025{ 026//for internal debugging 027private static boolean dbg = false; 028static String linesep = IOUtil.LINE_SEP; 029 030/** 031Returns a Map containing an IP address as the key and 032a {@link NIC.NICInfo} object as the value. Returns <tt>null</tt> if 033the platform type is not supported. 034<p> 035<b>Note 1:</b> Requires a NT based system (NT, 2000, XP or later) if 036running on windows. (this call will not work for lesser versions of 037windows).<br> 038<b>Note 2:</b> An english locale is needed for this method to work 039properly (because we parse for certain english words to extract the 040results). 041**/ 042public 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 063private 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 104private 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 148private 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 201public 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/** 223Contains information about IP addresses and the associated 224interface names and MAC address. More than one IP address 225can be associated with the same interface. 226**/ 227public static class NICInfo 228{ 229String interfaceName; 230String mac; 231 232NICInfo(String interfaceName, String mac) { 233 this.interfaceName = interfaceName; 234 this.mac = mac; 235 } 236/** 237returns the name of the interface. This name may not 238be the same as the name returned by {@link NetworkInterface#getName} 239(especially on windows). 240**/ 241public String getInterfaceName() { return interfaceName; } 242 243/** returns the MAC address of the interface **/ 244public String getMACAddress() { return mac; } 245 246public String toString() { 247 return "[NICInfo: name=" + interfaceName + "; MAC=" + mac + "]"; 248 } 249} //~class NICInfo 250 251 252} //~class NIC