46

破損したデータを処理するためのネットワーク ドライバーをテストするアプリケーションを作成しています。そして、このデータを raw ソケットを使用して送信することを考えたので、送信側のマシンの TCP-IP スタックによって修正されません。

私はこのアプリケーションを Linux だけで書いています。システムコールで生のソケットを使用するコード例がありますが、テストをできるだけ動的に保ち、すべてではないにしてもほとんどを Python で記述したいと考えています。

Python で生のソケットを使用する方法の説明と例を Web で少し調べましたが、本当に有益なものは見つかりませんでした。アイデアを示す非常に古いコード例ですが、決して機能しません。

私が収集したところによると、Python での Raw Socket の使用法は、セマンティクスにおいて UNIX の raw ソケットとほぼ同じですがstruct、パケット構造を定義する s はありません。

テストの生のソケット部分を Python ではなく、C でシステム コールを使用して記述し、メインの Python コードから呼び出すほうがよいのではないかと考えていました。

4

8 に答える 8

59

あなたはこのようにします:

まず、ネットワークカードの自動チェックサムを無効にします。

sudo ethtool -K eth1 tx off

そして、Python 2から危険なフレームを送信します(Python 3に自分で変換する必要があります):

#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW
s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth1", 0))

# We're putting together an ethernet frame here, 
# but you could have anything you want instead
# Have a look at the 'struct' module for more 
# flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"
ethertype = "\x08\x01"

s.send(dst_addr+src_addr+ethertype+payload+checksum)

終わり。

于 2011-06-16T15:57:17.963 に答える
11

Sockets システム コール (Windows では Winsocks) は、既に標準モジュールintroreferencesocketにラップされています。

生のソケットを使用したことはありませんが、このモジュールで使用できるようです。

最後の例は、Windows で raw ソケットを使用する非常に単純なネットワーク スニファーを作成する方法を示しています。この例では、インターフェイスを変更するために管理者権限が必要です。

import socket

# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# receive a package
print s.recvfrom(65565)

# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
于 2009-07-13T06:52:13.807 に答える
2

最終的に、この場合の最善の解決策は、Cですべてを書くことでした。これは、大きなアプリケーションではないため、このような小さなものを複数の言語で書くと、より大きなペナルティが発生するためです。

Cとpythonの両方のRAWソケットをいじくり回した後、私は最終的にCRAWソケットを好みました。RAWソケットでは、パケットヘッダーを書き込むために、8ビットグループ未満のビットレベルの変更が必要です。時々4ビット以下しか書きません。pythonはこれに対する支援を定義していませんが、LinuxCにはこれに対する完全なAPIがあります。

しかし、このほんの少しのヘッダー初期化がPythonで便利に処理されていれば、ここでCを使用したことはないと確信しています。

于 2009-07-27T06:58:51.340 に答える
2

これはあなたが見つけたと述べた古いコードですか?私には理にかなっているように見えますが、自分でテストしたことはありません(または生のソケットをあまり使用していません)。ドキュメントのこの例は、生のソケットを使用してパケットを盗聴する方法を示しており、見た目は十分に似ています。

于 2009-07-13T06:50:15.340 に答える
1
s = socket(AF_PACKET, SOCK_RAW)
s = socket(PF_PACKET, SOCK_RAW)

結果:</p>

[root@localhost python]# tcpdump -i eth0

capture size 96 bytes
11:01:46.850438 

01:02:03:04:05:06 (oui Unknown) > 01:02:03:04:05:06 (oui Unknown), ethertype Unknown (0x0801), length 85:

        0x0000:  5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b  [[[[[[[[[[[[[[[[
        0x0010:  5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5041  [[[[[[[[[[[[[[PA
        0x0020:  594c 4f41 445d 5d5d 5d5d 5d5d 5d5d 5d5d  YLOAD]]]]]]]]]]]
        0x0030:  5d5d 5d5d 5d5d 5d5d 5d5d 5d5d 5d5d 5d5d  ]]]]]]]]]]]]]]]]
        0x0040:  5d5d 5d00 0000 00                        ]]]....
于 2012-09-28T03:15:43.410 に答える
0

ソケット クラスが役立ちます。そうでない場合は、C で Python モジュールを作成するか、単に C を使用する必要があります。http://mail.python.org/pipermail/python-list/2001-April/077454.htmlを参照してください。

基本的なグーグルはそれを見つけました。

「unwind」さんが指摘してくださったコード例を実際に試してみました。AF_PACKET は Python 2.7.4 で動作しました

于 2009-07-13T06:49:05.763 に答える