在公司内网中,有一台主机(windows server2016)因为测试需要,在里面安装了九台centos7虚拟机,主机只在第一次安装系统时候链接显示器,之后就没有链接显示器,需要使用远程链接,但是因为windows主机不是固定ip,因此经常存在远程链接主机时ip地址变更导致远程链接失败的问题,开始时候是找一个显示器临时插上找到ip然后再链接,但是每次操作都很麻烦,因此查看并记录下主机的mac地址,使用下面四条ping命令将内网地址全部ping一一遍(会在C:\Users\用户名目录中生成Ping0.txt等文件):

for /L %i in (255,-1,1) do ping -n 1 -a 172.17.0.%i>>Ping0.txt
for /L %i in (255,-1,1) do ping -n 1 -a 172.17.1.%i>>Ping1.txt
for /L %i in (255,-1,1) do ping -n 1 -a 172.17.2.%i>>Ping2.txt
for /L %i in (255,-1,1) do ping -n 1 -a 172.17.3.%i>>Ping3.txt

然后再使用:

arp -a

命令列出全部ip和mac地址的对应关系列表,再自己一个一个找到mac地址,查看对应ip再链接。

在ip地址范围小的时候这样做是比较好的,很快就能找到对应的ip,但是如果ip范围大就比较耗费时间了,还是不方便,就想到能不能写一个“脚本”来获取mac对应的ip地址,因为自己对bat脚本实在不熟悉,只会一些简单的显示和命令,不晓得能不能循环判断什么的,因此就想到了使用java来实现这个功能,经过搜索,发现java可以执行dos命令,然后根据搜集的资料,经过修改得到下面简单的示例代码。

代码很简单一看就懂的那种,就简单说一下思路,先使用ping命令验证主机是否存在,如果存在则使用arp -a命令获取其mac地址,再跟目标mac地址比较判断是不是目标主机,如果是,则输出ip并退出,如果不是则继续。直到验证完整个目标网段。

下面是示例代码GetMacByIp.java(复制的缩进好像有点小瑕疵,不过不影响):

import java.util.*;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 通过ping ip然后使用arp -a ip获取局域网主机mac地址对应ip
 * @author CR
 * @date 2018年9月25日
 */
public class GetMacByIp{
    
    /**
     * 执行单条指令
     * @param cmd 命令
     * @return 执行结果
     * @throws Exception
     */
    public static String command(String cmd) throws Exception{
        Process process = Runtime.getRuntime().exec(cmd);
        process.waitFor();
        InputStream in = process.getInputStream();
        StringBuilder result = new StringBuilder();
        byte[] data = new byte[256];
        while(in.read(data) != -1){
            String encoding = System.getProperty("sun.jnu.encoding");
            result.append(new String(data,encoding));
        }
        return result.toString();
    }
   
  
    /**
     * 获取指定mac地址与对应ip地址
     * @param ip
     * @return
     * @throws Exception 
     */
    public static String getMacAddress(int ipOne, int ipTwo, int ipThreeStart, int ipThreeEnd, int ipFourStart, int ipFourEnd, String macAddr) throws Exception{
        // 判断地址是否合理
		if(ipOne > 255 || ipTwo > 255 || ipThreeStart > 255 || ipThreeEnd > 255 || ipFourStart > 255 || ipFourEnd> 255) {
			return "ip地址有误";
		}
		if(ipOne < 0 || ipTwo < 0 || ipThreeStart < 0 || ipThreeEnd < 0 || ipFourStart < 0 || ipFourEnd < 0) {
			return "ip地址有误";
		}
		// 判断地址开始结束是否有序
		if(ipThreeStart > ipThreeEnd) {
			int num = ipThreeStart;
			ipThreeStart = ipThreeEnd;
			ipThreeEnd = num;
		}
		if(ipFourStart > ipFourEnd) {
			int num = ipFourStart;
			ipFourStart = ipFourEnd;
			ipFourEnd = num;
		}
				
		for(int i = ipThreeStart; i <= ipThreeEnd; i++) {
			for(int j = ipFourStart; j <= ipFourEnd; j++) {
				String ip = ipOne + "." + ipTwo + "." + i + "." + j;
				System.out.printf("ping %-6s    ", ip);
				String result = command("ping " + ip + " -n 1");
				if(result.contains("TTL")){
					result = command("arp -a " + ip);
					String regExp = "([0-9A-Fa-f]{2})([-:][0-9A-Fa-f]{2}){5}";
					Pattern pattern = Pattern.compile(regExp);
					Matcher matcher = pattern.matcher(result);
					StringBuilder mac = new StringBuilder();
					while (matcher.find()) {
						String temp = matcher.group();
						mac.append(temp);
					}
					System.out.println(mac.toString());
					System.out.println();
					if((mac.toString()).equalsIgnoreCase(macAddr)) {
						System.out.println("\n目标主机ip及mac地址为:");
						return ip + " —— " + mac.toString();
					}
				}else {
					System.out.println("无法访问目标主机");
					System.out.println();
				}
			}
		}
		return "没有找到相应mac";
    }
	
	public static void main(String[] args) throws Exception {
		if(args.length == 7) {
			// 使用命令行传递的参数
			System.out.println(getMacAddress(Integer.valueOf(args[0]), Integer.valueOf(args[1]), Integer.valueOf(args[2]), 
			Integer.valueOf(args[3]), Integer.valueOf(args[4]), Integer.valueOf(args[5]), args[6]));
		}else {
			System.out.println("\n参数数量不正确,期望参数数量为7,因此使用默认参数(默认参数可在源码中修改)");
			System.out.println(getMacAddress(172, 17, 0, 4, 1, 254, "14-dd-a9-d5-11-ca"));
		}
        //System.out.println(command("arp -a 172.17.3.207"));
    }
 
}

将上面的java文件保存在本地某个文件夹,win + r打开运行输入CMD打开命令窗口切换到文件目录或者直接在该文件存放目录中按住shift点右键,在菜单中选择“在此处打开命令窗口”(注意:win10中应该是windows powershell,我自己电脑修改过因此是命令窗口),编译:

javac GetMacByIp.java

运行即可。运行有两种方式,如下:

java GetMacByIp

java GetMacByIp 172 17 0 4 1 255 14-dd-a9-d5-11-ca

一种是使用代码中写好的参数,一种是在运行代码时传递参数进去。

传递参数的方式一共需要七个参数,按前后顺序分别是:

  1. ip地址第一段

  2. ip地址第二段

  3. ip地址第三段开始

  4. ip地址第三段结束

  5. ip地址第四段开始

  6. ip地址第四段结束

  7. 目标主机mac地址

以上面的172 17 0 4 1 255 14-dd-a9-d5-11-ca为例,就是在172.17.0.1-172.17.4.255的ip范围内,查找mac地址为14-dd-a9-d5-11-ca的主机对应的ip地址。

下面是几个运行截图:

 

PS:也就是今天,运维的哥哥拔走了我这台主机里面的【影驰980 TI 名人堂】然后给我绑定了一个ip,这样我以后就不用再找ip了,,,,,,emmmm,,,,亏不亏,


END 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐