And*_*res 5 unix sockets networking haskell
Network.Socket中提供了一个原始套接字类型,但是在近端绑定套接字上有一条注释"目前只支持Unix域套接字并支持Internet系列".我怎样才能在haskell中使用原始套接字?
我正在尝试实现的功能,如使用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))
Run Code Online (Sandbox Code Playgroud)
EDIT1:在Haskell中,我sock <- socket AF_PACKET Raw 0xFFFF用来创建一个套接字,但bindSocket需要一个SockAddr参数,可用的构造函数
SockAddrInet PortNumber HostAddress
SockAddrInet6 PortNumber FlowInfo HostAddress6 ScopeID
SockAddrUnix String
Run Code Online (Sandbox Code Playgroud)
但这些似乎都没有.
编辑2:感谢Yuras的评论我收到了工作包:
import Network.Socket
sock <- socket AF_PACKET Raw 0xFFFF
recv sock 0xFFFF
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为内核对于实际传输数据包的接口没有任何线索.有没有办法将(原始)套接字绑定到Haskell中的接口?
Network.Pcap可用于发送和接收原始数据。
import qualified Data.ByteString.Char8 as B
import Network.Pcap
main = do
-- open device
dev <- openLive "lo" 65535 False 0
setFilter dev "ether proto 0xFFFF" True 0
-- send
sendPacketBS dev (B.pack "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\255\255Hello, World!")
-- receive
loopBS dev (-1) (\_ packet -> putStrLn (show packet))
Run Code Online (Sandbox Code Playgroud)