主要思路:
1.通过python psutil模块,并对网卡名称进行筛选得到对应网卡的IP地址和MAC地址
2.使用scapy库中的srp()函数发送二层数据包并获得返回值
3.使用type()函数分析返回值类型,查询对应的类中的方法,来提取关键信息
发送包的属性可以在scapy中查询,如:
查询本机对应网卡,IP,MAC 代码:
import psutil
def get_local(ifname):
dic = psutil.net_if_addrs()
for adapter in dic:
if adapter == ifname:
snicList = dic[adapter]
mac = '无 mac 地址'
ipv4 = '无 ipv4 地址'
ipv6 = '无 ipv6 地址'
for snic in snicList:
if snic.family.name in {'AF_LINK', 'AF_PACKET'}:
mac = snic.address
elif snic.family.name == 'AF_INET':
ipv4 = snic.address
elif snic.family.name == 'AF_INET6':
ipv6 = snic.address
return (adapter,ipv4,mac)
测试:
ARP协议代码:
import sys
import logging
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)#不显示报错
from scapy.all import *
from get_local_ip import get_local
def get_arp(destip,ifname='以太网'):
resnet = get_local(ifname)
localmac = resnet[2].replace('-',':')
localip = resnet[1]
ifname = resnet[0]
result_raw = srp(Ether(src=localmac,dst='FF:FF:FF:FF:FF:FF')/ARP(op=1,hwsrc=localmac,psrc=localip,hwdst='00:00:00:00:00:00',pdst=destip),iface=ifname,verbose=False)
return result_raw[0].res[0][1].getlayer(ARP).fields
if __name__ == "__main__":
if len(sys.argv) > 1:#一个参数的时候参数为IP,网卡默认为以太网
ipaddress = sys.argv[1]
result = get_arp(ipaddress)
print('ip : ' + ipaddress)
print('mac : ' + result['hwsrc'])
if len(sys.argv) > 2:#两个参数的时候,第一个参数为IP,第二个参数为网卡
ipaddress = sys.argv[1]
ifname = sys.argv[2]
result = get_arp(ipaddress,ifname)
print('ip : ' + ipaddress)
print('mac : ' + result['hwsrc'])
测试:
首先在命令行arp -a一下
抓包分析:
广播发包:
单播回包:
作者:whiteinblack