sockets - Haskell 中的原始套接字

标签 sockets unix networking haskell

Network.Socket 中提供了原始套接字类型,但在绑定(bind)套接字附近有一条注释“当前仅支持 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))

编辑1: 在 Haskell 中,我使用 sock <- socket AF_PACKET Raw 0xFFFF创建一个套接字,但是 bindSocket需要 SockAddr作为参数,可用的构造函数是

SockAddrInet PortNumber HostAddress  
SockAddrInet6 PortNumber FlowInfo HostAddress6 ScopeID   
SockAddrUnix String

但这些似乎都不正确。

编辑2: 感谢 Yuras 的评论,我收到了可以工作的数据包:

import Network.Socket
sock <- socket AF_PACKET Raw 0xFFFF
recv sock 0xFFFF

编辑3: 尝试从套接字发送数据包而不绑定(bind)它会导致异常:

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)

这是有道理的,因为内核不知道实际传输数据包的接口(interface)。有什么方法可以将(原始)套接字绑定(bind)到 Haskell 中的接口(interface)吗?

最佳答案

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))

关于sockets - Haskell 中的原始套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10229381/

相关文章:

Java Socket 服务器未从客户端套接字接收数据

c - 套接字编程中struct addrinfo {}中链接列表的用途

python - 在 Python 中删除 Root 权限

linux - 用户可编辑的回显文本

c# - 如何在FTP服务器上复制文件?

apache - 有没有办法用 HTTPS 加密主机头?

c# - 从 C# 连接到 node.js 服务器

linux - sed 行将周围的冒号更改为 bash 中的点

bash - Linux 测试项目 'nfs_stress' nfs01 'RTNETLINK answers: Operation not permitted'

c++ - 在以下情况下从套接字读取数据已损坏?