安卓查询连接wifi的终端型号功能实现(查看蹭网)

xiaoxiao2021-02-28  15

    功能如题所述,查询出连接了相同wifi的手机的品牌信息,可以使用作为检测蹭网功能的核心功能。

    首先介绍一下实现原理,安卓系统采用ARP协议,ARP协议即地址解析协议,是一种根据IP地址获取物理地址(MAC地址)的协议。主机发送报文信息到指定的IP地址病获得返回信息后写入到本地的ARP缓存,结果信息在本地ARP文件中保存一定时间。查询品牌功能的实现基于arp协议。当对于局域网中一个IP发送报文后,安卓会将返回的信息写入本地的ARP文件中,而返回的信息中包括了设备的mac地址信息。由于mac地址的前六位都是唯一对应厂商的,所以根据IEEE提供的mac地址文档即可查找出对应的厂商信息,做好中文适配即可。

    代码实现分为以下步骤:

    1.读取手机当前IP地址

    2.读取当前子网掩码

    3.根据子网掩码和IP地址即可计算当前wifi的有效IP地址集合

    4.对生成的IP集合中的每一个IP发送udp报文

    5.读取本地ARP表格获取有效的mac地址信息

    6.根据mac地址信息查找对应厂商信息

    给出各个步骤关键代码实现,后续会给出demo以供下载。

    1.读取手机当前IP地址

/** * 获取本机ip地址 * * @return */ public static String getLocalIPAddress() { String ip = ""; try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { ip = inetAddress.getHostAddress(); break; } } if (!TextUtils.isEmpty(ip)) break; } } catch (Exception e) { ip = ""; } return ip; }     2.读取当前子网掩码

/** * 获取本机子网掩码 * * @return */ public static String getNetMask() { try { Enumeration<NetworkInterface> eni = NetworkInterface .getNetworkInterfaces(); while (eni.hasMoreElements()) { NetworkInterface networkCard = eni.nextElement(); List<InterfaceAddress> ncAddrList = networkCard .getInterfaceAddresses(); for (InterfaceAddress networkCardAddress : ncAddrList) { InetAddress address = networkCardAddress.getAddress(); if (!address.isLoopbackAddress()) { String hostAddress = address.getHostAddress(); if (hostAddress.indexOf(":") <= 0) { return calcMaskByPrefixLength(networkCardAddress.getNetworkPrefixLength()); } } } } } catch (Exception e) { e.printStackTrace(); } return "not found"; }     3.根据子网掩码和IP地址即可计算当前wifi的有效IP地址集合

public static List<String> parseIpMaskRange(String ip, String MASK) { String mask = getNetMask(MASK) + ""; Log.i("scanner", mask); List<String> list = new ArrayList<String>(); if ("32".equals(mask)) { list.add(ip); } else { String startIp = getBeginIpStr(ip, mask); String endIp = getEndIpStr(ip, mask); if (!"31".equals(mask)) { String subStart = startIp.split("\\.")[0] + "." + startIp.split("\\.")[1] + "." + startIp.split("\\.")[2] + "."; String subEnd = endIp.split("\\.")[0] + "." + endIp.split("\\.")[1] + "." + endIp.split("\\.")[2] + "."; startIp = subStart + (Integer.valueOf(startIp.split("\\.")[3]) + 1); endIp = subEnd + (Integer.valueOf(endIp.split("\\.")[3]) - 1); } list = parseIpRange(startIp, endIp); } return list; } public static List<String> parseIpRange(String ipfrom, String ipto) { List<String> ips = new ArrayList<String>(); String[] ipfromd = ipfrom.split("\\."); String[] iptod = ipto.split("\\."); int[] int_ipf = new int[4]; int[] int_ipt = new int[4]; for (int i = 0; i < 4; i++) { int_ipf[i] = Integer.parseInt(ipfromd[i]); int_ipt[i] = Integer.parseInt(iptod[i]); } for (int A = int_ipf[0]; A <= int_ipt[0]; A++) { for (int B = (A == int_ipf[0] ? int_ipf[1] : 0); B <= (A == int_ipt[0] ? int_ipt[1] : 255); B++) { for (int C = (B == int_ipf[1] ? int_ipf[2] : 0); C <= (B == int_ipt[1] ? int_ipt[2] : 255); C++) { for (int D = (C == int_ipf[2] ? int_ipf[3] : 0); D <= (C == int_ipt[2] ? int_ipt[3] : 255); D++) { ips.add(new String(A + "." + B + "." + C + "." + D)); } } } } return ips; }

4.对生成的IP集合中的每一个IP发送udp报文 private class UDPThread extends Thread { private String target_ip = ""; final byte[] NBREQ = {(byte) 0x82, (byte) 0x28, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x20, (byte) 0x43, (byte) 0x4B, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x0, (byte) 0x0, (byte) 0x21, (byte) 0x0, (byte) 0x1}; static final short NBUDPP = 137; UDPThread(String target_ip) { this.target_ip = target_ip; } @Override public synchronized void run() { if (target_ip == null || target_ip.equals("")) return; DatagramSocket socket = null; InetAddress address = null; DatagramPacket packet = null; try { address = InetAddress.getByName(target_ip); packet = new DatagramPacket(NBREQ, NBREQ.length, address, NBUDPP); socket = new DatagramSocket(); socket.setSoTimeout(200); socket.send(packet); socket.close(); } catch (Exception se) { se.printStackTrace(); } finally { if (socket != null) { socket.close(); } } } } 5.读取本地ARP表格获取有效的mac地址信息 /** * 读取arp信息 */ private void readArp() { macListFromRead = new ArrayList<TerminalBean>(); try { BufferedReader br = new BufferedReader( new FileReader("/proc/net/arp")); String line = ""; String ip = ""; String flag = ""; String mac = ""; String gateWay = new WifiInfoUtil(getApplicationContext()).getGateWay(); Log.i("wangguan", "网关" + gateWay); while ((line = br.readLine()) != null) { try { line = line.trim(); Log.i("scanner", line); if (line.length() < 63) continue; if (line.toUpperCase(Locale.US).contains("IP")) continue; ip = line.substring(0, 17).trim(); flag = line.substring(29, 32).trim(); mac = line.substring(41, 63).trim(); if (mac.contains("00:00:00:00:00:00")) continue; if (gateWay.equals(ip)) continue;//过滤网关 Log.i("scanner", "readArp: mac= " + mac + " ; ip= " + ip + " ;flag= " + flag); TerminalBean terminalBean = new TerminalBean(); terminalBean.setMac(mac); terminalBean.setIp(ip); macListFromRead.add(terminalBean);//读出的所有mac地址信息保存 } catch (Exception e) { e.printStackTrace(); } } br.close(); } catch (Exception e) { e.printStackTrace(); } Log.i("scanner", "end"); } 6.根据mac地址信息查找对应厂商信息/** * 根据mac地址从txt文件中查询品牌信息 * * @param mac mac地址 * @return 品牌信息 */ private static String findCompanyFromTxt(Context context, String mac, int id) { InputStream inputStream = context.getResources().openRawResource(id); InputStreamReader inputStreamReader = null; inputStreamReader = new InputStreamReader(inputStream); BufferedReader reader = null; reader = new BufferedReader(inputStreamReader); String line; try { while ((line = reader.readLine()) != null) { if (line.contains(mac)) { return line;//获取到型号行 } } } catch (IOException e) { e.printStackTrace(); } return null; } 后续给出实现demo。效果如下:

转载请注明原文地址: https://www.6miu.com/read-1250304.html

最新回复(0)