1. takimai39

    Posted

    takimai39
Changes in title
+scapy で仮想 IP を作成し ping の応答を得る。
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,86 @@
+## はじめに
+
+Scapy は、ネットワークパケット操作のツールで、パケットの生成からデコードまで、色々な事ができます。
+例えば、通信エラー発生時のパケットを同じように作成して動作確認するなど、問題の再現テストなどにも利用できると思います。
+ここでは、単に仮想的なアドレスに対しての ping 応答を得るだけの環境を作成してみましたので、その説明です。
+
+## scapy のインストール
+
+・RedHat
+ https://access.redhat.com/solutions/3759961
+ (How to install scapy for network troubleshooting in Red Hat Enterprise Linux 7? )
+
+## arp 応答プログラム
+
+IP 通信を行うためには、まずは arp の問い合わせに対して応答を返さないといけません。
+そのためのプログラムとして以下。※どこかの URL を参考にしたのですが、もう思い出せない。
+
+```
+#!/usr/bin/python3
+
+from scapy.all import *
+
+# Your network broadcast address
+broadcastNet = "192.168.1.255"
+
+macDict = { "192.168.1.123" : "01:01:01:01:01:01" }
+
+# Use MAC address of this machine as source. If not eth0, change this:
+myMAC = get_if_hwaddr('eth1')
+
+def handle_packet(packet):
+ if packet[ARP].op == 1: # who-has
+ print("Someone is asking about " + packet.pdst)
+ print(packet.summary())
+
+ if packet.pdst in macDict:
+ print("Sending ARP response for " + packet.pdst)
+ reply = ARP(op=2, hwsrc=macDict[packet.pdst], psrc=packet.pdst, hwdst="ff:ff:ff:ff:ff:ff", pdst=broadcastNet)
+ # reply = ARP(op=ARP.is_at, hwsrc=macDict[packet.pdst], psrc=packet.pdst, hwdst="ff:ff:ff:ff:ff:ff", pdst=broadcastN
+et)
+ go = Ether(dst="ff:ff:ff:ff:ff:ff", src=myMAC) / reply
+ sendp(go)
+ return
+
+# Sniff for ARP packets. Run handle_packet() on each one
+sniff(filter="arp", prn=handle_packet, store=0)
+
+```
+
+## ping を打って arp テーブルを確認
+
+つまり、こういう事。
+ping の応答は、まだ得られませんが arp テーブルは出来ていることがわかります。
+
+![arp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246034/3ec15869-08bf-e6b8-ca77-93e23770f124.jpeg)
+
+
+## ping の応答プログラム
+
+```
+#!/usr/bin/python3
+
+from scapy.all import *
+
+def handle_packet(packet):
+ if str(packet[ICMP].type) == "8":
+ if packet[IP].dst == '192.168.1.123':
+ # packet.show()
+ echoReply = IP(dst=packet[IP].src, src='192.168.1.123')/ICMP()/Raw()
+ echoReply[ICMP].type = 0 # echo reply
+ echoReply[ICMP].id = packet[ICMP].id
+ echoReply[ICMP].seq = packet[ICMP].seq
+ echoReply[ICMP][Raw].load = packet[ICMP][Raw].load
+ send(echoReply)
+ return
+
+# Sniff for icmp packets
+sniff(filter="icmp", prn=handle_packet, store=0)
+```
+
+## 実行してみる
+
+こんな感じ、めでたく 192.168.1.123 へ ping が飛びました。
+
+![ping.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246034/af8376eb-00f0-fe8f-4030-d8886a055cd1.jpeg)
+