python网络编程——实现ARP协议

主要思路:

1.通过python psutil模块,并对网卡名称进行筛选得到对应网卡的IP地址和MAC地址

2.使用scapy库中的srp()函数发送二层数据包并获得返回值

3.使用type()函数分析返回值类型,查询对应的类中的方法,来提取关键信息

发送包的属性可以在scapy中查询,如:

python网络编程——实现ARP协议_第1张图片

查询本机对应网卡,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)

测试:

python网络编程——实现ARP协议_第2张图片

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一下

python网络编程——实现ARP协议_第3张图片

抓包分析:

广播发包:

python网络编程——实现ARP协议_第4张图片

单播回包:

python网络编程——实现ARP协议_第5张图片

你可能感兴趣的:(python)