Networking

Socat:從標準輸入發送 UDP 廣播,但使用 SYSTEM 處理響應

  • October 31, 2020

我正在嘗試使用socat. 發現是通過將 UDP 廣播發送到具有小負載的明確定義的埠來完成的,然後偵聽來自我網路上這些設備的“回复”。

如果我使用雙向socat並且“響應”轉到標準輸出,則此方法有效:

echo -ne "\x00\x01\x00\xF6" | socat -t5 - udp-datagram:255.255.255.255:30718,broadcast |xxd -p

來自本地網路上一些設備的範例響應(每行是來自不同設備的響應):

000000f70020300258366d112c15000062a71b21ff0000000080a3d2ded9
000000f70020300258366d112c15000062a71b21ff0000000080a3a40670
000000f70020300258366d112c15000062a71b21ff0000000080a3b94ca0
000000f70020300258366d112c15000062a71b21ff0000000080a3a4046b

有效載荷是我所期望的,但是我缺少的是發件人元數據,特別是如果我使用ip-pktinfo,fork SYSTEM:. 所以我想要的是從標準輸入發送初始廣播,但用於SYSTEM處理返回的結果數據包。

我嘗試了一些-u單向模式的變體,但我似乎沒有在我的監聽器上接收到數據:

# Listener: 
socat -u udp-recvfrom:30222,reuseaddr,ip-pktinfo,fork SYSTEM:./test.sh &

# Broadcast:
echo -ne "\x00\x01\x00\xF6" | socat -u - udp-datagram:255.255.255.255:30222,sourceport=30222,broadcast,reuseaddr

請注意“此端”源埠可能是隨機的,因此我明確選擇30222,以便我的廣播源埠與我的響應偵聽器匹配。例如,如果廣播來自埠 9987,客戶端會將其單播響應發送回埠 9987。如果我以這種方式執行單向廣播,我偶爾會收到響應;我有一種感覺,這取決於廣播過程退出的速度。

(我打算接下來檢查數據包擷取;我正在遠端機器上進行測試,我必須先刷新我的記憶tcpdump。)

參考:

OP 提到ip-pktinfo這通常是 Linux 套接字選項(用於IP_PKTINFO)。我將在下面假設 Linux(但請參閱 *BSD 末尾的註釋)。這個選項實際上是不需要的(另見最後的註釋),但可以添加以獲取更多資訊。


關鍵部分是使用reuseport切換SO_REUSEPORT套接字選項的選項:

SO_REUSEPORT(自 Linux 3.9 起)

允許將多個 AF_INET 或 AF_INET6 套接字綁定到相同的套接字地址。在對套接字呼叫 bind(2) 之前,必須在每個套接字(包括第一個套接字)上設置此選項。為防止埠劫持,綁定到同一地址的所有程序必須具有相同的有效 UID。此選項可用於 TCP 和 UDP 套接字。

除了這個缺失的選項,OP 已經得到了所有需要的東西。

主要是為了其他讀者的利益,我將描述所做的事情並給出一個完整的例子。


如果一個socat命令由於限制無法完成工作,則使用兩個socat,將全雙工通信通道分成兩個單工通道,適用於這種情況。

一個用於回讀答案,另一個用於發送廣播。同樣,為了解決socat限制,讀取socat必須使用UDP-RECVFROMand fork-u對於只讀,因此其結果將發送到stdout,而不是被發送迴響應者)而不是通常自然的選擇UDP-RECV: 這是允許每個數據包派生一個命令,並通過環境變數傳輸每個數據包的元數據。同樣正如 OP 所寫,必須提前選擇一個埠才能讓它們都使用相同的埠。發送套接字也必須使用-u以避免冒險讀回答案並將其竊取給其他專用socat命令。

這是區域網路中的一個範例,本地系統具有 192.0.2.2/24,對等系統具有 192.0.2.3/24。

名為peer 的對等系統(響應者):

$ socat udp4-recvfrom:30718,fork system:hostname

本地系統的 term1 (也可以選擇使用,ip-pktinfo):

$ socat -u udp4-recvfrom:30222,reuseport,fork system:'cat; printenv|grep -E \"SOCAT_.*(ADDR|PORT)\"'

本地系統的術語2:

$ echo dummyprobe | socat -u - udp-datagram:255.255.255.255:30718,bind=:30222,reuseport,broadcast

在第 1 學期收到的回复:

peer
SOCAT_PEERADDR=192.0.2.3
SOCAT_PEERPORT=30718

筆記

SO_REUSEPORT如果它們在綁定埠之前都設置了 SO_REUSEPORT,則允許多個程序完全重複綁定。此選項允許程序的多個實例分別接收發往綁定埠的 UDP/IP 多播或廣播數據報。

  • ip-pktinfo不需要檢索peer的地址。它需要檢索本地地址,並且對於多宿主系統非常有用,因此它知道它的多個地址中的哪個地址接收到數據報,或者還知道接收到的數據報是否是廣播。即使沒有此選項,對等方的地址資訊也始終可用。*BSD 只需將此選項替換為ip-recvdstaddr,ip-recvif(=> IP_RECVDSTADDR+ IP_RECVIF) 即可接收相同的資訊。

引用自:https://unix.stackexchange.com/questions/612193