Help us understand the problem. What is going on with this article?

scapy で仮想 IP を作成し ping の応答を得る。

はじめに

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした