通过二层和三层查询空闲IP
2026-02-10
运维
00
请注意,本文编写于 53 天前,最后修改于 5 天前,其中某些信息可能已经过时。

目录

一、网络分层基础(OSI 与 TCP/IP)
二、ARP 协议深度解析(二层探测)
2.1 ARP 工作流程
2.2 ARP 帧结构(Ethernet II)
2.3 ARP 探测的边界
三、ICMP/IP 协议深度解析(三层探测)
3.1 ICMP Echo (Ping) 流程
3.2 ICMP 与 ARP 的关键差异
八、 附录
8.1 Windows 通过 ping 查找存活的IP
8.2 Linux 通过 ping 查找存活的IP

一、网络分层基础(OSI 与 TCP/IP)

OSI 层TCP/IP 层核心设备关键协议地址类型广播域
7 应用层应用层终端软件HTTP/SSH/DNS
4 传输层传输层防火墙TCP/UDP端口号
3 网络层网际层路由器IP/ICMP/OSPF/BGPIP 地址❌ 不广播
2 数据链路层网络接口层交换机ARP/Ethernet/VLANMAC 地址✅ 广播域
1 物理层网络接口层网线/光纤电信号/光信号

关键结论

  • 二层(交换机):同一 VLAN 内,MAC 地址通信,ARP 广播可达;
  • 三层(路由器):跨网段,IP 地址通信,ARP 广播被阻断,需路由表转发;
  • 广播域边界:交换机转发广播,路由器隔离广播。

二、ARP 协议深度解析(二层探测)

2.1 ARP 工作流程

展开代码
主机 A (192.168.1.10) 想访问 192.168.1.20 ↓ 查 ARP 缓存:无记录 ↓ 构造 ARP Request 广播帧: 发送方 MAC: AA:AA:AA:AA:AA:AA 发送方 IP: 192.168.1.10 目标 MAC: 00:00:00:00:00:00 (未知) 目标 IP: 192.168.1.20 以太网目标: FF:FF:FF:FF:FF:FF (广播) ↓ 交换机泛洪到同一 VLAN 所有端口 ↓ 192.168.1.20 收到 → 单播 ARP Reply: 目标 MAC: AA:AA:AA:AA:AA:AA 发送方 MAC: BB:BB:BB:BB:BB:BB 发送方 IP: 192.168.1.20 ↓ 主机 A 缓存 MAC,开始二层通信

2.2 ARP 帧结构(Ethernet II)

字段长度说明
目标 MAC6 bytesFF:FF:FF:FF:FF:FF = 广播
源 MAC6 bytes请求者 MAC
类型2 bytes0x0806 = ARP
硬件类型2 bytes0x0001 = Ethernet
协议类型2 bytes0x0800 = IPv4
操作码2 bytes0x0001 = Request, 0x0002 = Reply
发送方 MAC6 bytes
发送方 IP4 bytes
目标 MAC6 bytes请求时全 0
目标 IP4 bytes被查询的 IP

2.3 ARP 探测的边界

场景结果原因
同网段 192.168.1.0/24✅ 能扫到二层广播可达
跨网段 192.168.2.0/24❌ 扫不到路由器阻断广播
目标关机但 IP 在交换机 MAC 表⚠️ 可能误报交换机缓存未过期
目标开防火墙禁 ping✅ ARP 仍能通ARP 在防火墙之前

三、ICMP/IP 协议深度解析(三层探测)

3.1 ICMP Echo (Ping) 流程

展开代码
主机 A (192.168.1.10) ping 192.168.2.20 ↓ 判断:目标 IP 不在同一子网 ↓ 查路由表:走默认网关 192.168.1.1 ↓ ARP 解析网关 MAC → 封装 ICMP 包: IP 头:源 192.168.1.10,目标 192.168.2.20 以太网:目标 MAC = 网关 MAC ↓ 路由器 R1 收到 → 查路由表 → 转发到 R2 → ... → 目标网络 ↓ 192.168.2.20 收到 ICMP Echo Request ↓ 回复 ICMP Echo Reply(逆向路径) ↓ 主机 A 收到 → 显示存活

3.2 ICMP 与 ARP 的关键差异

特性ARPICMP (Ping)
OSI 层二层 (Data Link)三层 (Network)
依赖地址MAC 地址IP 地址
能否跨网段❌ 不能✅ 能
经过路由❌ 不经过✅ 经过
防火墙拦截很难拦截容易被禁
响应速度极快 (<1ms)较慢 (几 ms~几百 ms)
准确性高(直连)中(可能被过滤)

四、查找空闲 IP 的实战方案

4.1 工具对比

工具技术跨网段速度隐蔽性准确度
arp-scanARP 广播二层极快 (秒级/256IP)高(无日志)极高
arpingARP 单播二层慢 (逐 IP)极高
nmap -snICMP/ARP/TCP智能
nmap -PSTCP SYN三层低(有日志)
masscan自定义 TCP三层极快 (万级/秒)
fpingICMP 并行三层极快

4.2 二层探测:ARP 方案(同网段)

arp-scan(推荐,批量最快)

展开代码
# 安装 sudo apt install arp-scan # 自动识别本地网卡并扫描 sudo arp-scan -l # 指定网卡和网段 sudo arp-scan -I eth0 192.168.1.0/24 # 输出格式控制(只显示 IP+MAC) sudo arp-scan 192.168.1.0/24 | grep -E '^[0-9]' | awk '{print $1}'

输出解析

展开代码
Interface: eth0, type: EN10MB, MAC: xx:xx:xx:xx:xx:xx, IPv4: 192.168.1.10 Starting arp-scan 1.9.7 with 256 hosts 192.168.1.1 aa:bb:cc:dd:ee:ff Huawei Technologies 192.168.1.10 11:22:33:44:55:66 (Unknown: locally administered) 192.168.1.20 77:88:99:aa:bb:cc Apple, Inc. 3 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.9.7: 256 hosts scanned in 2.456 seconds. 3 responded

已用 IP:3 个(.1, .10, .20) 空闲 IP:256 - 3 = 253 个

Python + Scapy(自定义,无依赖)

展开代码
#!/usr/bin/env python3 """ arp_free_ip.py - 查找同网段空闲 IP 需要 root 权限 """ from scapy.all import ARP, Ether, srp, conf import sys import ipaddress from concurrent.futures import ThreadPoolExecutor conf.verb = 0 # 关闭 Scapy 冗余输出 def arp_ping(ip): """单 IP ARP 探测""" pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=str(ip)) ans, _ = srp(pkt, timeout=1, retry=0) return str(ip), len(ans) > 0 def scan_network(network, max_workers=50): """批量扫描网段""" net = ipaddress.ip_network(network, strict=False) hosts = list(net.hosts()) # 排除网络地址和广播地址 used = [] free = [] print(f"[*] 开始扫描 {network},共 {len(hosts)} 个主机...") with ThreadPoolExecutor(max_workers=max_workers) as executor: results = executor.map(arp_ping, hosts) for ip, is_alive in results: if is_alive: used.append(ip) print(f"[+] 存活: {ip}") else: free.append(ip) return used, free def main(): if len(sys.argv) != 2: print(f"用法: sudo python3 {sys.argv[0]} 192.168.1.0/24") sys.exit(1) network = sys.argv[1] used, free = scan_network(network) print(f"\n{'='*50}") print(f"扫描完成: {network}") print(f"已用 IP: {len(used)} 个") print(f"空闲 IP: {len(free)} 个") print(f"\n前 10 个空闲 IP:") for ip in free[:10]: print(f" - {ip}") # 保存到文件 with open("free_ips.txt", "w") as f: f.write(f"# 空闲 IP 列表 - {network}\n") f.write(f"# 生成时间: {__import__('datetime').datetime.now()}\n") for ip in free: f.write(f"{ip}\n") print(f"\n[+] 空闲 IP 已保存到 free_ips.txt") if __name__ == "__main__": main()

运行

展开代码
sudo pip3 install scapy sudo python3 arp_free_ip.py 192.168.1.0/24

4.3 三层探测:ICMP/TCP 方案(跨网段)

nmap 智能扫描(推荐,自动选最优协议)

展开代码
# 默认:同网段用 ARP,跨网段用 ICMP sudo nmap -sn 192.168.1.0/24 # 本地网段(实际走 ARP) sudo nmap -sn 192.168.2.0/24 # 跨网段(走 ICMP) # 强制只用 ICMP(防火墙可能禁 ping) sudo nmap -sn -PE 192.168.2.0/24 # 强制 TCP SYN(防火墙禁 ping 时用) sudo nmap -sn -PS22,80,443 192.168.2.0/24 # 强制 UDP(某些 Windows 主机只回 UDP) sudo nmap -sn -PU53,161 192.168.2.0/24

输出解析

展开代码
Starting Nmap 7.94 ( https://nmap.org ) Nmap scan report for 192.168.2.1 [host down] Nmap scan report for 192.168.2.10 Host is up (0.0023s latency). MAC Address: AA:BB:CC:DD:EE:FF (Huawei Technologies) ... Nmap done: 256 IP addresses (3 hosts up) scanned in 3.45 seconds

fping 高速并行 ping

展开代码
# 安装 sudo apt install fping # 扫描并分类输出 fping -a -g 192.168.2.0/24 2>/dev/null | tee alive_ips.txt fping -u -g 192.168.2.0/24 2>/dev/null | tee dead_ips.txt # -a = alive, -u = unreachable, -g = 生成网段

masscan 极速端口扫描(万级/秒)

展开代码
# 安装 sudo apt install masscan # 扫描存活(0 端口 = 只 ping) sudo masscan 192.168.2.0/24 -p0 --rate 10000 # 扫描常用端口(更快判断存活) sudo masscan 192.168.2.0/24 -p22,80,443,3389 --rate 10000

五、拓展技术

5.1 DHCP 租约表查询(比扫描更快)

展开代码
# 如果网络有 DHCP 服务器,直接查租约 cat /var/lib/dhcp/dhcpd.leases | grep "lease\|hardware\|client-hostname" # 或路由器 Web 界面导出

5.2 SNMP 交换机 MAC 表查询(企业网)

展开代码
# 查交换机 MAC 地址表,反推已用 IP snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.17.4.3.1.1 # OID: dot1dTpFdbAddress (MAC 表)

5.3 网络流量监听(被动发现)

展开代码
# tcpdump 抓 ARP 请求,被动记录存活主机 sudo tcpdump -i eth0 arp -w arp_traffic.pcap # 分析:tshark -r arp_traffic.pcap -T fields -e arp.src.proto_ipv4 | sort -u

5.4 IPv6 邻居发现(NDP)

展开代码
# IPv6 没有 ARP,用 NDP (Neighbor Discovery Protocol) sudo ip -6 neigh show # 查看邻居表 sudo ndisc6 -r 5 2001:db8::1 eth0 # 主动探测

六、技术选型总结

场景推荐工具理由
同网段找空闲 IParp-scan / Python Scapy二层最快,防火墙挡不住
跨网段找空闲 IPnmap -sn -PS智能 fallback,TCP 穿透防火墙
极速扫描(10万+ IP)masscan自定义协议栈,万级/秒
企业内网(有交换机权限)SNMP + MAC 表不发包,零影响
隐蔽探测(红队)tcpdump 被动监听不主动发包,无日志
自动化集成Python Scapy / Nmap XML结构化输出,易解析

七、一句话速记

同网段用 ARP(arp-scan),跨网段用 ICMP/TCP(nmap),极速用 masscan,隐蔽用被动监听,企业用 SNMP二层广播不路由,三层路由不广播——选错层,扫空网


八、 附录

8.1 Windows 通过 ping 查找存活的IP

展开代码
150..161 | ForEach-Object { ip = "10.73.2._" ok = Test-Connection -Count 1 -Delay 1 -Quiet -ComputerName ip if ($ok) { Write-Output "UP $ip" } else { Write-Output "DOWN $ip" } }

8.2 Linux 通过 ping 查找存活的IP

展开代码
#!/bin/bash # 探测 192.168.88.150-220 存活主机 MAX_JOB=30 LOG_T=$(date +%F_%H-%M) up_log="up_ip_${LOG_T}.log" down_log="down_ip_${LOG_T}.log" > "$up_log" > "$down_log" # 清空旧日志 for i in {150..220};do ip="192.168.88.$i" { if ping -c 2 -i 0.2 -w 1 "$ip" &>/dev/null;then echo "$ip 运行中~~~~~" else echo "$ip 挂了" >&2 fi } >> "$up_log" 2>>"$down_log" & # 控制并发 while [ $(jobs -r | wc -l) -ge $MAX_JOB ];do sleep 0.5;done done wait echo "扫描完成,结果已写入 $up_log $down_log"

本文作者:zzz

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!