python实现arp扫描

局域网扫描,局域网存货ip快速扫描

安装:

pip install scapy

 

1、以前的写法:单线程(不推荐)

from scapy.all import *
import sys, getopt, socket


def get_local_net():
    # 获取网段。如:192.168.50
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        # 获取本机ip。如:192.168.50.110
        ip = s.getsockname()[0]
        ippre_list = ip.split(r".")
        ippre_list.pop()
        # 获取网段字串。如:192.168.50
        ipnet = '.'.join(ippre_list)
    except Exception:
        ipnet = False
    finally:
        s.close()

    return ipnet


def get_vlan_ip_and_mac(locnet, start_num=1, end_num=255):
    # 通过arp协议扫描,发现本网段存活ip和mac
    result = []
    localnet = locnet
    scansum = int(end_num) - int(start_num) + 1

    print("%s.%s - %s.%s 共计 %s 个被扫描ip" % (localnet, start_num, localnet, end_num, scansum))
    print()
    counter = 1

    # 如果无法识别本网段,则退出扫描
    if not localnet:
        print("扫描终止:无法识别本网段。")
        return result

    for ipFix in range(start_num, end_num + 1):
        # 构造本网段的ip。如:192.168.50.20
        ip = localnet + "." + str(ipFix)

        # 组合协议包
        # 通过 '/' 可叠加多个协议层(左底层到右上层),如Ether()/IP()/UDP()/DNS()
        arpPkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip)
        # 发送arp请求,并获取响应结果。设置1s超时。
        res = srp1(arpPkt, timeout=1, verbose=0)

        # 如果ip存活
        if res:
            print("%3d --> %s  %s" % (counter, ip, res.hwsrc))
            result.append({"localIP": res.psrc, "mac": res.hwsrc})
            counter += 1
        # 如果ip不存活
        else:
            print("%3d --> %s" % (counter, ip))
            counter += 1

    return result


if __name__ == '__main__':
    locnet = get_local_net()
    print("一、开始扫描本网段(%s.xx)活动的ip" % locnet)
    # 扫描ip起始和终止范围
    start_num = 126
    end_num = 135
    # 开始扫描
    result = get_vlan_ip_and_mac(locnet, start_num, end_num)

    print()
    print("二、Mac表汇总清单(活动ip共计 %s个):" % len(result))
    for dic in result:
        print(dic)

  

2、推荐的写法:多线程(推荐)

from scapy.all import *
import threading

ip_list = []
mac_list = []


def ScanIp(ip):
    pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip)
    try:
        res = srp1(pkt, timeout=10, verbose=0)
        if res.psrc == ip:
            # print('IP             MAC')
            print('%-14s %s' % (res.psrc, res.hwsrc))
            ip_list.append(res.psrc)
            mac_list.append(res.hwsrc)
            # my_thread_id = threading.current_thread().ident  # 获取当前线程id
            print("{0}{1} 子线程结束".format(' ' * 60, threading.current_thread().ident))
    except:
        pass


if __name__ == '__main__':
    # ARP().show()

    # 自动获取当前网段
    tip = ARP().psrc
    tip = tip[:(len(tip) - tip[::-1].find('.'))]  # 192.168.50.
    print(tip)

    # ScanIp("192.168.50.12")
    thread_list = []
    for i in range(1, 256):
        ip = tip + str(i)
        Go = threading.Thread(target=ScanIp, args=(ip,))
        thread_list.append(Go)
        Go.start()

    # 在这里统一执行线程等待的方法
    for Go in thread_list:
        Go.join()

    print('=' * 100)
    # 将存活的ip清单,按照最后一位数字排序
    ip_sort_list = sorted(ip_list, key=lambda ip: int(ip.rpartition('.')[-1]))
    print('存活ip个数:%s' % len(ip_sort_list))
    for ip in ip_sort_list:
        print(ip)

  

方法2

https://www.cnblogs.com/andy9468/p/8418649.html

posted @ 2020-10-29 19:16  安迪9468  阅读(580)  评论(0编辑  收藏  举报