Socat: 표준 입력에서 UDP 브로드캐스트를 보내지만 SYSTEM을 사용하여 응답을 처리합니다.

Socat: 표준 입력에서 UDP 브로드캐스트를 보내지만 SYSTEM을 사용하여 응답을 처리합니다.

을(를) 사용하려고 합니다 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.)

인용하다:

답변1

OP에서는 ip-pktinfo이것이 일반적으로 Linux 소켓 옵션(에 사용됨 IP_PKTINFO)이라고 언급했습니다. 아래에서는 Linux를 가정하겠습니다(그러나 마지막에 *BSD 참고 사항 참조). 이 옵션은 실제로 필수는 아니지만(마지막 참고 사항 참조) 자세한 내용을 확인하기 위해 추가할 수 있습니다.


중요한 부분은 reuseport토글을 사용하는 옵션 입니다.SO_REUSEPORT소켓 옵션:

SO_REUSEPORT(리눅스 3.9부터)

여러 AF_INET 또는 AF_INET6 소켓을 동일한 소켓 주소에 바인딩할 수 있습니다. 이 옵션은 소켓에서 바인드(2)를 호출하기 전에 모든 소켓(첫 번째 소켓 포함)에 설정되어야 합니다. 포트 하이재킹을 방지하려면 동일한 주소에 바인딩된 모든 프로세스는 동일한 유효 UID를 가져야 합니다. 이 옵션은 TCP 및 UDP 소켓에 사용할 수 있습니다.

OP에는 이 옵션이 없다는 점을 제외하고 필요한 모든 것이 있습니다.

주로 다른 독자들의 이익을 위해 수행된 작업을 설명하고 완전한 예를 제시하겠습니다.


만약소캇이 명령은 제한으로 인해 작업을 수행하지 않습니다. 두 가지를 사용하십시오.소캇이 경우 전이중 통신 채널을 두 개의 단방향 채널로 분할합니다.

하나는 답변을 다시 읽는 데 사용되고 다른 하나는 브로드캐스트를 보내는 데 사용됩니다. 다시말해 해결책소캇제한하다, 읽다소캇and와 UDP-RECVFROM함께 사용해야 합니다 (읽기 전용이므로 결과는 다음과 같습니다).fork-u표준 출력, 응답자로 다시 전송되는 대신) 일반적으로 자연스러운 선택 대신 UDP-RECV: 즉, 패킷당 명령을 분기하고 환경 변수를 통해 각 패킷의 메타데이터를 전송할 수 있습니다. 또한 OP가 작성한 것처럼 포트는 모두 동일한 포트를 사용하도록 미리 선택해야 합니다. -u응답을 다시 읽고 다른 개인 소켓으로 훔치는 위험을 피하기 위해 송신 소켓도 사용해야 합니다.소캇주문하다.

다음은 로컬 시스템에 192.0.2.2/24가 있고 피어 시스템에 192.0.2.3/24가 있는 LAN의 예입니다.

피어 시스템(응답자) 이름 지정동료:

$ 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

노트

  • FreeBSD에도 비슷한 설명이 있습니다.SO_REUSEPORT(더 구체적으로,Linux는 최근 *BSD에 맞춰 조정되었습니다.):

    SO_REUSEPORT포트를 바인딩하기 전에 모두 SO_REUSEPORT를 설정한 경우 여러 프로세스에 의한 정확한 중복 바인딩이 허용됩니다. 이 옵션을 사용하면 프로그램의 여러 인스턴스가 바인딩된 포트로 향하는 UDP/IP 멀티캐스트 또는 브로드캐스트 데이터그램을 각각 수신할 수 있습니다.

  • ip-pktinfo검색이 필요하지 않습니다동료주소. 검색이 필요하다현지의다중 홈 시스템에 가장 유용한 주소이므로 여러 주소 중 어느 주소가 데이터그램을 수신했는지 알거나 수신된 데이터그램이 브로드캐스트인지 여부도 알 수 있습니다. 이 옵션이 없어도 피어의 주소 정보는 항상 사용 가능합니다. *BSD는 동일한 정보를 받으려면 이 옵션을 ip-recvdstaddr,ip-recvif(=> IP_RECVDSTADDR+ ) 로 대체하면 됩니다 .IP_RECVIF

관련 정보