天天看點

Python Scapy ARP

參考手冊: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這樣的技術。

<a href="https://s5.51cto.com/oss/201711/09/bd026c46612d8c05a571a8a2d1184d4d.png" target="_blank"></a>

<a href="https://s4.51cto.com/oss/201711/09/1362a196e266c72a6642320c05a4c27c.png" target="_blank"></a>

<a href="https://s2.51cto.com/oss/201711/09/3ebaa89c5e14ed66f7669aea729dc5ed.png" target="_blank"></a>

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

▼ARP請求包樣例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

<code>#!/usr/bin/python3.4</code>

<code># -*- coding=utf-8 -*-</code>

<code>import</code> <code>logging</code>

<code>logging.getLogger(</code><code>"scapy.runtime"</code><code>).setLevel(logging.ERROR)</code><code>#清除報錯</code>

<code>from</code> <code>scapy.</code><code>all</code> <code>import</code> <code>*</code>

<code>#配置各種資訊,以便調用</code>

<code>localmac </code><code>=</code> <code>'00:0c:29:8d:5c:b6'</code>

<code>localip </code><code>=</code> <code>'202.100.1.138'</code>

<code>destip </code><code>=</code> <code>'202.100.1.139'</code>

<code>ifname </code><code>=</code> <code>'eno33554944'</code>

<code>#######################源MAC為本地MAC####目的MAC為廣播#########操作碼為1(請求)#######################################################由于多個網卡是以需要指派iface###########</code>

<code>result_raw </code><code>=</code> <code>srp(Ether(src</code><code>=</code><code>localmac, dst</code><code>=</code><code>'FF:FF:FF:FF:FF:FF'</code><code>)</code><code>/</code><code>ARP(op</code><code>=</code><code>1</code><code>, hwsrc</code><code>=</code><code>localmac, hwdst</code><code>=</code><code>'00:00:00:00:00:00'</code><code>, psrc</code><code>=</code><code>localip, pdst</code><code>=</code><code>destip), iface </code><code>=</code> <code>ifname, verbose </code><code>=</code> <code>False</code><code>)</code>

<code>'''</code>

<code>sr() function is for sending packets and receiving answers. The function #returns a couple of packet and answers, and the unanswered packets. </code>

<code>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.). </code>

<code>srp() do the same for layer 2 packets (Ethernet, 802.3, etc.).</code>

<code>send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. </code>

<code>sendp() function will work at layer 2.</code>

<code>#print(result_raw)</code>

<code>#(&lt;Results: TCP:0 UDP:0 ICMP:0 Other:1&gt;, &lt;Unanswered: TCP:0 UDP:0 ICMP:0 Other:0&gt;) 一個元組,[0]收到響應的資料包,[1]未收到響應的資料包</code>

<code>#print(type(result_raw[0]))</code>

<code>#&lt;class 'scapy.plist.SndRcvList'&gt; #https://fossies.org/dox/scapy-2.3.1/classscapy_1_1plist_1_1SndRcvList.html</code>

<code>result_list </code><code>=</code> <code>result_raw[</code><code>0</code><code>].res </code><code>#res: the list of packets,産生由收發資料包所組成的清單(list)</code>

<code>#print(result_list)</code>

<code>#[(&lt;Ether  dst=FF:FF:FF:FF:FF:FF src=00:0c:29:8d:5c:b6 type=ARP |&lt;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 |&gt;&gt;, &lt;Ether  dst=00:0c:29:8d:5c:b6 src=00:0c:29:43:52:cf type=ARP |&lt;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 |&lt;Padding load=‘\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00’ |&gt;&gt;&gt;)]</code>

<code>#一個清單,每一個item為一個元組,元組内包括一次ARP請求與回應</code>

<code>#result_list[0][1][0],[0]表示第一組資料包(收發),[1],表示收包(0為發包),[0]表示以太網頭部</code>

<code>#print(result_list[0][1][0].fields) 以太網頭部字段</code>

<code>#{'dst': '00:0c:29:8d:5c:b6', 'type': 2054, 'src': '00:0c:29:43:52:cf'}</code>

<code>#result_list[0][1][0],[0]表示第一組資料包(收發),[1],表示收包(0為發包),[1]表示ARP頭部</code>

<code>#print(result_list[0][1][1].fields) ARP頭部字段</code>

<code>#{'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'}</code>

<code>print</code><code>(</code><code>'IP位址: '</code> <code>+</code> <code>result_list[</code><code>0</code><code>][</code><code>1</code><code>][</code><code>1</code><code>].fields[</code><code>'psrc'</code><code>] </code><code>+</code> <code>' MAC位址: '</code> <code>+</code> <code>result_list[</code><code>0</code><code>][</code><code>1</code><code>][</code><code>1</code><code>].fields[</code><code>'hwsrc'</code><code>])</code>

<a href="https://s5.51cto.com/oss/201711/09/1ccf59da24da649641629ff436b7daae.png" target="_blank"></a>

本文轉自Grodd51CTO部落格,原文連結:http://blog.51cto.com/juispan/1980254,如需轉載請自行聯系原作者