局域网IP扫描器

Home PDF Audio

局域网IP扫描器

这个Python脚本扫描本地网络以查找活动的IP地址。它使用ping命令检查主机是否可达,并使用多线程来加快扫描过程。信号量限制并发线程的数量,以避免压垮系统。脚本接受网络地址(例如,“192.168.1.0/24”)作为输入,并打印网络中每个IP地址的状态(在线或离线)。

这个脚本通过扫描活动IP地址来帮助识别网络上的设备,例如在有线桥接模式下运行的TP-LINK网状路由器。

import subprocess
import ipaddress
import threading
import os
import socket
import argparse

MAX_THREADS = 50  # 最大线程数

def is_host_up(host, port=None):
    """
    使用ping或telnet检查主机是否在线。
    如果指定了端口,则使用telnet检查端口是否打开。
    否则,使用ping。
    如果主机在线则返回True,否则返回False。
    """
    if port:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            result = sock.connect_ex((host, port))
            if result == 0:
                return True
            else:
                return False
        except socket.error as e:
            return False
        finally:
            sock.close()
    else:
        try:
            # -c 1: 只发送1个数据包
            # -W 1: 等待1秒响应
            subprocess.check_output(["ping", "-c", "1", "-W", "1", host], timeout=1)
            return True
        except subprocess.CalledProcessError:
            return False
        except subprocess.TimeoutExpired:
            return False

def scan_ip(ip_str, up_ips, port=None):
    """
    扫描单个IP地址并打印其状态。
    """
    if is_host_up(ip_str, port):
        print(f"{ip_str} is up")
        up_ips.append(ip_str)
    else:
        print(f"{ip_str} is down")

def scan_network(network, port=None):
    """
    使用线程扫描网络以查找活动主机,限制并发线程的数量。
    """
    print(f"Scanning network: {network}")
    threads = []
    semaphore = threading.Semaphore(MAX_THREADS)  # 限制并发线程数
    up_ips = []

    def scan_ip_with_semaphore(ip_str):
        semaphore.acquire()
        try:
            scan_ip(ip_str, up_ips, port)
        finally:
            semaphore.release()

    for ip in ipaddress.IPv4Network(network):
        ip_str = str(ip)
        thread = threading.Thread(target=scan_ip_with_semaphore, args=(ip_str,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()
    
    return up_ips

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="扫描网络以查找活动主机。")
    parser.add_argument("network", nargs='?', default="192.168.1.0/24", help="要扫描的网络(例如,192.168.1.0/24)")
    parser.add_argument("-p", "--port", type=int, help="要检查的端口(可选)")
    args = parser.parse_args()

    network_to_scan = args.network
    port_to_scan = args.port

    up_ips = scan_network(network_to_scan, port_to_scan)
    print("\n活动IP:")
    for ip in up_ips:
        print(ip)


跳过本地IP

脚本识别活动IP地址。为了确保正确的网络通信,请验证是否已配置代理设置以跳过这些本地IP。

192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,127.0.0.1,localhost,*.local,timestamp.apple.com,sequoia.apple.com,seed-sequoia.siri.apple.com, 192.168.1.0/16

子网掩码

我的第二台机器通常位于192.168.1.16。

因此,使用下面的命令可以正常工作。

python scripts/ip_scan.py 192.168.1.0/27 -p 22

因为32 - 27 = 5,2^5 = 32,所以它将尝试从192.168.1.0192.168.1.31

但是,使用192.168.1.0/28时它无法正常工作,因为2^4 = 16,所以它将尝试从192.168.1.0192.168.1.15,这并不包含192.168.1.16


Back 2025.02.22 Donate