Network.Socketで提供されるrawソケットタイプがありますが、バインディングソケットの近くに、「現在、Unixドメインソケットとインターネットファミリのみがサポートされています」というコメントがあります。Haskellでrawソケットを使用するにはどうすればよいですか?
動作するPythonコードとして、私が達成しようとしていること:
import binascii
import socket
# Create raw socket.
ethType = b'FFFF' # 2 bytes, has to be >= 0x0600. FFFF is "unavailable" by IEEE.
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
sock.bind( ('lo', int(ethType,16)) )
# Create packet.
srcMac = b'000000000000' # 6 bytes
destMac = b'000000000000' # 6 bytes
header = binascii.a2b_hex( destMac + srcMac + ethType ) # 14 bytes
message = b'Hello, World!'
sock.send(header + message)
# Receive such packets
while True: print (sock.recv(65535))
編集1:Haskellではsock <- socket AF_PACKET Raw 0xFFFF
、ソケットを作成するために使用しますが、引数としてbindSocket
aが必要であり、使用可能なコンストラクターは次のとおりです。SockAddr
SockAddrInet PortNumber HostAddress
SockAddrInet6 PortNumber FlowInfo HostAddress6 ScopeID
SockAddrUnix String
しかし、これらのどれも正しくないようです。
EDIT2:Yurasのコメントのおかげで、パケットを受信して動作するようになりました。
import Network.Socket
sock <- socket AF_PACKET Raw 0xFFFF
recv sock 0xFFFF
EDIT3:バインドせずにソケットからパケットを送信しようとすると、例外が発生します。
sock <- socket AF_PACKET Raw 0xFFFF
send sock "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\255\255"
*** Exception: send: does not exist (No such device or address)
カーネルには、実際にパケットを送信するインターフェイスの手がかりがないため、これは理にかなっています。(raw)ソケットをHaskellのインターフェースにバインドする方法はありますか?