1. 程式人生 > >Python Scapy ARP

Python Scapy ARP

scapy

參考手冊:https://fossies.org/dox/scapy-2.3.3/


當一臺主機把以太網數據幀發送到位於同一個局域網上的另一臺主機時,是根據48bit的以太網地址來確定目的接口的。

設備驅動程序從不檢查IP數據包中的目的IP地址。

地址解析為這兩種不同的地址形式提供映射:32bit的IP地址和數據鏈路曾使用的任何類型的地址。(FR環境)

ARP為IP地址到對應的硬件地址之間提供動態映射。我們之所以用動態這個詞是因為這個過程是自動完成的,一般應用程序用戶或系統管理員不必關心。


在ARP背後有有一個基本概念,那就是網絡接口有一個硬件地址(一個48bit的值,標識不同的以太網或令牌環網絡接口)。在硬件層次上進行的數據幀交換必須有正確的接口地址。但是TCP/IP有自己的地址:32bit的IP地址。知道主機的IP地址並不能讓內核發送一幀數據給主機。

內核(如以太網驅動程序)必須知道目的端的硬件地址才能發送數據。ARP的功能是在32bit的IP地址和采用不同網絡技術的硬件地址之間提供動態映射。

點對點鏈路不使用ARP。當設置這些鏈路時(一般在引導過程進行),必須告知內核鏈路每一端的IP地址。像以太網地址這樣的硬件地址並不涉及。

只有多路訪問鏈路才需要ARP這樣的技術。

技術分享

技術分享

技術分享


ARP高效運行的關鍵是由於每個主機上都有一個ARP高速緩存。這個高速緩存存放了最近Internet地址到硬件地址之間的映射記錄。高速緩存中每一項的生存時間一般為20分鐘,起始時間從被創建時開始算起。


ARP請求包樣例:

#!/usr/bin/python3.4
# -*- coding=utf-8 -*-

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)#清除報錯
from scapy.all import *

#配置各種信息,以便調用
localmac = ‘00:0c:29:8d:5c:b6‘
localip = ‘202.100.1.138‘
destip = ‘202.100.1.139‘
ifname = ‘eno33554944‘

#######################源MAC為本地MAC####目的MAC為廣播#########操作碼為1(請求)#######################################################由於多個網卡所以需要指派iface###########
result_raw = srp(Ether(src=localmac, dst=‘FF:FF:FF:FF:FF:FF‘)/ARP(op=1, hwsrc=localmac, hwdst=‘00:00:00:00:00:00‘, psrc=localip, pdst=destip), iface = ifname, verbose = False)

‘‘‘
sr() function is for sending packets and receiving answers. The function #returns a couple of packet and answers, and the unanswered packets. 
sr1() is a variant that only return one packet that answered the packet (or #the packet set) sent. The packets must be layer 3 packets (IP, ARP, etc.). 
srp() do the same for layer 2 packets (Ethernet, 802.3, etc.).
send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. 
sendp() function will work at layer 2.
‘‘‘

#print(result_raw)
#(<Results: TCP:0 UDP:0 ICMP:0 Other:1>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>) 一個元組,[0]收到響應的數據包,[1]未收到響應的數據包
#print(type(result_raw[0]))
#<class ‘scapy.plist.SndRcvList‘> #https://fossies.org/dox/scapy-2.3.1/classscapy_1_1plist_1_1SndRcvList.html
result_list = result_raw[0].res #res: the list of packets,產生由收發數據包所組成的清單(list)
#print(result_list)
#[(<Ether  dst=FF:FF:FF:FF:FF:FF src=00:0c:29:8d:5c:b6 type=ARP |<ARP  op=who-has hwsrc=00:0c:29:8d:5c:b6 psrc=202.100.1.138 hwdst=00:00:00:00:00:00 pdst=202.100.1.139 |>>, <Ether  dst=00:0c:29:8d:5c:b6 src=00:0c:29:43:52:cf type=ARP |<ARP  hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=00:0c:29:43:52:cf psrc=202.100.1.139 hwdst=00:0c:29:8d:5c:b6 pdst=202.100.1.138 |<Padding load=‘\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00’ |>>>)]
#一個列表,每一個item為一個元組,元組內包括一次ARP請求與回應

#result_list[0][1][0],[0]表示第一組數據包(收發),[1],表示收包(0為發包),[0]表示以太網頭部
#print(result_list[0][1][0].fields) 以太網頭部字段
#{‘dst‘: ‘00:0c:29:8d:5c:b6‘, ‘type‘: 2054, ‘src‘: ‘00:0c:29:43:52:cf‘}

#result_list[0][1][0],[0]表示第一組數據包(收發),[1],表示收包(0為發包),[1]表示ARP頭部
#print(result_list[0][1][1].fields) ARP頭部字段
#{‘pdst‘: ‘202.100.1.138‘, ‘hwtype‘: 1, ‘hwdst‘: ‘00:0c:29:8d:5c:b6‘, ‘plen‘: 4, ‘ptype‘: 2048, ‘hwsrc‘: ‘00:0c:29:43:52:cf‘, ‘op‘: 2, ‘hwlen‘: 6, ‘psrc‘: ‘202.100.1.139‘}

print(‘IP地址: ‘ + result_list[0][1][1].fields[‘psrc‘] + ‘ MAC地址: ‘ + result_list[0][1][1].fields[‘hwsrc‘])

技術分享



本文出自 “Gorilla City” 博客,請務必保留此出處http://juispan.blog.51cto.com/943137/1980254

Python Scapy ARP