要解决的痛点:
(1)局域网内有需要通过网络访问的终端,但不知道其 IP 地址
(2)局域网内需要通过网络访问的终端,其 IP 通过动态主机配置协议 DHCP 配置,启动后发生了变化,但不知道变化后的 IP。
本工具的作用:
扫描所在局域网内所有可以 ping 通的 IP,缩小连接试探范围。
本工具依赖:
Python 3.8以上。更低的 Python 版本未经过测试,不保证可以工作。
只依赖 Python3 的内置包。
适用于 Windows 和 Linux。
本工具特性:
自动获取本机 IPv4 地址,并根据所获取的本机 IPv4 地址,扫描前三段相同的可以 ping 通的 IP 地址(如有其它需求,请自行修改)。
本机可以有多个 IPv4 地址,处于相同网段的 IPv4 地址在扫描过程中会自动合并。
扫描过程启用了多线程,几秒钟可以出结果。
*** 避免在 Windows 下用 IDLE 运行本工具,这种方式运行将弹出非常多的命令行终端,速度非常慢 ***
本工具使用方法:
复制下面的脚本内容,存储到名为 LanScan.py 的文件中。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LAN Fast Scanner
Created on Tue Aug 6 16:13:26 2019
@author: farman
"""
import os
import sys
import threading
import subprocess
def get_local_ipv4_linux():
out_bytes = subprocess.check_output(['ifconfig'])
local_ip = []
for line in out_bytes.decode().split('\n'):
if line.find('inet6') == -1 \
and line.find('inet') > -1 \
and line.find('127.0.0.1') == -1:
line = line[:line.find('netmask')]
line = line.strip().split()[1]
local_ip.append(line)
return local_ip
def get_local_ipv4_windows():
out_bytes = subprocess.check_output(['ipconfig'])
local_ip = []
for line in out_bytes.decode("GB2312").split('\n'):
if line.count('IPv4'):
line = line[line.find(':') + 1 :]
line = line.strip().rstrip()
local_ip.append(line)
return local_ip
def get_local_ipv4():
return get_local_ipv4_linux() if sys.platform == "linux" else get_local_ipv4_windows()
if 0:
x = get_local_ipv4()
print(x)
def merge_ip_list(ip_list):
merged_ip_list = []
for ip in ip_list:
ip = ip[: ip.rfind('.')]
if ip not in merged_ip_list:
merged_ip_list.append(ip)
return merged_ip_list
if 0:
x = get_local_ipv4()
y = merge_ip_list(x)
print(y)
def my_ping_linux(a, b, c, d):
'''
Ping a given ip, and return the result.
The IP address to be pinged is "a.b.c.d".
'''
ip = '%s.%s.%s.%s'%(a, b, c, d)
command = 'ping %s -c 1 -W 1'%ip
return ip if not os.system(command) else None
def my_ping_windows(a, b, c, d):
'''
Ping a given ip, and return the result.
The IP address to be pinged is "a.b.c.d".
'''
ip = '%s.%s.%s.%s'%(a, b, c, d)
command = 'ping %s -n 1 -w 1'%ip
return ip if not os.system(command) else None
def my_ping(a, b, c, d):
return my_ping_linux(a, b, c, d) if sys.platform == 'linux' else my_ping_windows(a, b, c, d)
if 0:
x = my_ping(192, 168, 4, 1)
print(x)
x = my_ping(192, 168, 3, 1)
print(x)
'''
Module "threading" of python3 is used to accelerate the scan operation.
'''
class MyThread(threading.Thread):
"""
This Class is just for result fetching of threaded function.
"""
def __init__(self, function, args):
threading.Thread.__init__(self)
self.function = function
self.args = args
def run(self):
self.result = self.function(*self.args)
def get_result(self):
return self.result
def scan_lan(a, b, c, d_begin=1, d_end=255):
'''
Scan LAN neighbours by ping command
in range from "a.b.c.d_begin" to "a.b.c.d_end"
with threading method to reduce time consumption of scanning.
input:
The IP address to be pinged is "a.b.c.d".
outpur:
list of IP address of active neighbours.
'''
threads = [MyThread(my_ping, (a, b, c, d)) for d in range(d_begin, d_end)]
for n in range(len(threads)):
threads[n].start()
for n in range(len(threads)):
threads[n].join()
valid_ip = []
for n in range(len(threads)):
ip = threads[n].get_result()
if ip != None:
valid_ip.append(ip)
return valid_ip
if 0:
x = scan_lan(192, 168, 3)
print(scan_lan(192, 168, 3))
def auto_scan():
'''
Auto scan LAN neighbours, return their IP addresses.
Calling this function directly is the right manner to
get IP addresses of LAN neighbouts
because it's convinient and so comfort:)
'''
local_ip_list = get_local_ipv4()
valid_ip_list = []
if len(local_ip_list):
local_ip_list_of_former_3_segments = merge_ip_list(local_ip_list)
for ip in local_ip_list_of_former_3_segments:
[a, b, c] = ip.split('.')
valid_ip_list += scan_lan(a, b, c)
return local_ip_list, valid_ip_list
def show_result(local_ip_list, valid_ip_list):
os.system("clear" if sys.platform == 'linux' else 'cls')
print('\n\nLAN IP Address Scanner')
print('-'*40)
print(' '*22, 'Farman@2023.05.23\n')
print('Valid Network Address%s found : %s'%(
'' if len(valid_ip_list)< 2 else 'es',
len(valid_ip_list)))
print('-'*40)
count = 0
for valid_ip in valid_ip_list:
a, b, c, d = valid_ip.split('.')
ip_segments = ['0' * (3 - len(seg)) + seg for seg in valid_ip.split('.')]
print(' No.%03d - %s %s'%(count+1, '.'.join(ip_segments), '[LOCAL]' if valid_ip in local_ip_list else ''))
count += 1
input("\nPress 'Enter' to exit ...")
return
#------------------------------------------------------------------------------
if __name__ == '__main__':
local_ip_list, valid_ip_list = auto_scan()
show_result(local_ip_list, valid_ip_list)
Windows 命令行调用
python LanScan.py
Linux 终端调用
python3 LanScan.py
Enjoy it!