Multicast Datagram via UDP

    • Offizieller Beitrag

    Heyho,

    Ich habe mal ne kleine Frage: Ich versuche via Multicast datagrams sowohl die IP Adresse als auch die MAC Adresse von einem betsimmten PC (Um genau zu sein einer Medienbox) im Netzwerk zu bekommen. Es gibt ein Programm, welches dies erfolgreich für diese Box tut. Ich habe nun via Wireshark geguckt wie das Programm dies macht. Er sendet über dem UDP Protokoll zwei Strings an die IP 225.1.1.1 über den Port 5555.
    Im Anhang mal das, was Wireshark mir rausgespuckt hat. Ich habe es nun geschafft, in AutoIt das nachzu bilden, bzw. es kommt exakt das gleiche bei WireShark an, wenn ich mein Script laufen lasse, allerdings kommt in meinem Script nie eine eingehende Nachricht an (UDPRecv).
    Hier mal das Script:

    Spoiler anzeigen
    [autoit]


    ;Das sind die beiden Strings die gesendet werden.
    $b01 = Binary("0x5365617263685f47726f75703a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    $b02 = Binary("0x506f705f5365727665723a3139322e3136382e302e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000")

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier werden sie nochma in die Console ausgegeben
    ConsoleWrite(BinaryToString($b01))
    ConsoleWrite(@CRLF)
    ConsoleWrite(BinaryToString($b02))
    ConsoleWrite(@CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    UDPStartup()
    OnAutoItExitRegister("cleanup")
    ;Hier Verbindet er sich zu 225.1.1.1 auf dem Port 5555 (gibt kein Error zurück)
    $hUPDopen = UDPOpen("225.1.1.1", 5555)
    If @error Then Exit MsgBox(16, "", "")

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier bindet er ein socket auf meine lokale ip adresse. in meinem Fall ist das 192.168.0.2 (siehe in der Console, dort ist die IP)
    ;Ich bin mir nicht sicher ob ich das überhaupt brauche...
    $hUPDbind = UDPBind(@IPAddress1, 32769)
    If @error Then Exit MsgBox(16, "", "")
    ;Nun sendet er die beiden Strings
    ConsoleWrite("Send: " & UDPSend($hUPDopen, $b01) & "/" & BinaryLen($b01) & @CRLF)
    Sleep(100)
    ConsoleWrite("Send: " & UDPSend($hUPDopen, $b02) & "/" & BinaryLen($b02) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    ;Hier fragt er nach receives ab..
    $data = UDPRecv($hUPDopen, 50)
    If @error Then ConsoleWrite("Err: " & @error & @CRLF)
    $data &= UDPRecv($hUPDbind, 50)
    If @error Then ConsoleWrite("Err2: " & @error & @CRLF)
    ;..kommt aber leider nie was an :(
    If $data <> "" Then MsgBox(0, "", $data)
    Sleep(200)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func cleanup()
    UDPCloseSocket($hUPDopen)
    UDPCloseSocket($hUPDbind)
    UDPShutdown()
    EndFunc ;==>Cleanup

    [/autoit]

    Es sieht relativ ähnlich aus, wie IBM das für ihre Boxen tut:
    http://publib.boulder.ibm.com/infocenter/ise…x1multicast.htm

    Leider werde ich aus dem Code nicht richtig schlau...
    Wäre super wenn mir jemand helfen kann. :)

    Gruß,
    Spider

  • Genau so ein Problem hatte ich auch schon einmal, das problem bei mir war damals der Port auf dem gesendet wurde war jedes mal ein anderer, also auch schwierig herraus zu finden auf welchem Port er abhören soll.
    überprüfe das doch mal mit tcpview
    das sleep zwischen den beiden send befehlen täte ich weg nehmen - Zeit in der schon eine antwort kommen könnte.

    habe leider im mom keine zeit mir deinen code unter die Lupe zu nehmen, habe hier deshalb mal meinen gesendet, darin habe ich dieses problem gelöst, vieleicht wirste schlau draus.

    Gruß
    Pre

    Spoiler anzeigen
    [autoit]

    ;======================================================================================================================
    ; Function Name: _afindalice()
    ; Description:: Sucht via UDP nach AliceLE/Alice5 Recordern
    ; Return Value(s): Erfolg - Array mit Datensätzen
    ; Fehler - 1 Wenn keine Alice gefunden wurde
    ;======================================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _findalice($IP)

    [/autoit] [autoit][/autoit] [autoit]

    #Region Broadcast IP erstellen und Port öffnen zu dem gesendet werden soll.
    UDPStartup()
    $socket = UDPOpen("255.255.255.255", 10011, 1)
    If @error Then
    SetError(1)
    ;~ MsgBox(-1, "", "error udpopen")
    Exit
    EndIf
    #EndRegion Broadcast IP erstellen und Port öffnen zu dem gesendet werden soll.

    [/autoit] [autoit][/autoit] [autoit]

    broadcastsend($socket, ".") ; irgentetwas senden um einen Port zu aktivieren

    [/autoit] [autoit][/autoit] [autoit]

    #Region Port auslesen von dem aus gesendet wurde
    $ausgabe = _getDOSOutput("netstat -aonp udp")
    $ausgabe = StringStripWS($ausgabe, 8)
    $ausgabe = StringTrimRight($ausgabe, StringLen($ausgabe) - StringInStr($ausgabe, "*:*" & @AutoItPID) - 6)
    $ausgabe = StringTrimLeft($ausgabe, StringInStr($ausgabe, "*:*" & @AutoItPID) - 25)
    $zwischenwert = _StringBetween($ausgabe, "0.0.0.0:", "*:*" & @AutoItPID)
    Global $port = _ArrayUnique($zwischenwert)
    #EndRegion Port auslesen von dem aus gesendet wurde

    [/autoit] [autoit][/autoit] [autoit]

    For $in = 1 To 3
    UDPSend($socket, "<query mess='" & $in & "' id='" & $in & "'/>.")
    Next
    UDPCloseSocket($socket)
    $socket1 = UDPBind($IP, $port[1])

    [/autoit] [autoit][/autoit] [autoit]

    ; Array Größe
    $azeilen = 100; Anzahl der Findbarengeräte
    $aspalten = 10 ; Anzahl der nötigen Settingsspalten

    [/autoit] [autoit][/autoit] [autoit]

    Local $data[$azeilen][$aspalten]
    $countansers = 0
    For $d = 0 To UBound($data) - 1
    $value = _HexToString(UDPRecv($socket1, 4096, 1))
    If $value <> "" Then
    ;~ Dim $nArray[UBound($data)][20], $counter = 0;

    [/autoit] [autoit][/autoit] [autoit]

    ;~ msgbox(-1,"",$value)
    $sRegExpArray = StringRegExp($value, '"(.*?)"', 3)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _ArrayDisplay($sRegExpArray)

    [/autoit] [autoit][/autoit] [autoit]

    If IsArray($sRegExpArray) Then
    ;~ _ArrayDisplay($sRegExpArray)
    If $sRegExpArray[0] = "3" And $sRegExpArray[1] <> "102" Then
    $counter2 = 0
    For $j = 1 To $aspalten ; Werte die noch gespiechert wrden horizontal
    ;~ If $j <> 3 And $j <> 6 And $j <> 9 Then ; Ausschluss
    $data[$countansers][$counter2] = $sRegExpArray[$j]
    $counter2 = $counter2 + 1
    ;~ EndIf
    Next
    ;~ _ArrayDisplay($sRegExpArray)
    $countansers = $countansers + 1;
    EndIf
    EndIf
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    UDPCloseSocket($socket1)

    [/autoit] [autoit][/autoit] [autoit]

    If $countansers = 0 Then
    SetError(1)
    Else
    ReDim $data[$countansers][$aspalten]
    Return $data
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_findalice

    [/autoit] [autoit][/autoit] [autoit]

    Func broadcastsend($sSocket, $sSendewert)
    UDPSend($sSocket, $sSendewert & @CRLF)
    If @error Then
    MsgBox(-1, "", "error send")
    EndIf
    EndFunc ;==>broadcastsend

    [/autoit] [autoit][/autoit] [autoit]

    Func _getDOSOutput($command)
    Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2)
    While 1
    $text &= StdoutRead($Pid, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd
    Return $text
    EndFunc ;==>_getDOSOutput

    [/autoit]
    • Offizieller Beitrag

    Heyho,

    Danke schonmal für deine Antwort. Ich bezweifle, dass es an dem Source Port liegt, immerhin gibt die Box den wert wieder an den normalen Destination Port (5555) ab. Ich habe es trotzdem mal versucht, aber es hat leider nicht funktioniert. Komisch finde ich, dass Wireshark mir anzeigt, dass die IP von der Box (192.168.0.114) auf 225.1.1.1 zugreift, ich kann aber kein UDPBind auf diese IP Adresse setzen (sonst Fehler 10049)..

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <String.au3>
    ;======================================================================================================================
    ; Function Name: _afindalice()
    ; Description:: Sucht via UDP nach AliceLE/Alice5 Recordern
    ; Return Value(s): Erfolg - Array mit Datensätzen
    ; Fehler - 1 Wenn keine Alice gefunden wurde
    ;======================================================================================================================
    $adata = _findalice("0.0.0.0");0.0.0.0 = 127.0.0.1
    ConsoleWrite(@error & @CRLF)
    Func _findalice($IP)

    [/autoit] [autoit][/autoit] [autoit]

    #region Broadcast IP erstellen und Port öffnen zu dem gesendet werden soll.
    UDPStartup()
    $socket = UDPOpen("255.255.255.255", 5555, 1)
    If @error Then
    SetError(1)
    MsgBox(-1, "", "error udpopen")
    Exit
    EndIf
    #endregion Broadcast IP erstellen und Port öffnen zu dem gesendet werden soll.

    [/autoit] [autoit][/autoit] [autoit]

    broadcastsend($socket, ".") ; irgentetwas senden um einen Port zu aktivieren

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Port auslesen von dem aus gesendet wurde
    $ausgabe = _getDOSOutput("netstat -aonp udp")
    $ausgabe = StringStripWS($ausgabe, 8)
    $ausgabe = StringTrimRight($ausgabe, StringLen($ausgabe) - StringInStr($ausgabe, "*:*" & @AutoItPID) - 6)
    $ausgabe = StringTrimLeft($ausgabe, StringInStr($ausgabe, "*:*" & @AutoItPID) - 25)
    $zwischenwert = _StringBetween($ausgabe, "0.0.0.0:", "*:*" & @AutoItPID)
    Global $port = _ArrayUnique($zwischenwert)
    #endregion Port auslesen von dem aus gesendet wurde

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $b01 = Binary("0x5365617263685f47726f75703a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    $b02 = Binary("0x506f705f5365727665723a3139322e3136382e302e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    UDPSend($socket, $b01)
    UDPSend($socket, $b02)
    UDPCloseSocket($socket)
    ConsoleWrite($IP & ":" & $port[1] & @CRLF)
    $socket1 = UDPBind($IP, 5555)
    If @error Then ConsoleWrite("!" & @error & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $srecv = UDPRecv($socket1, 1024)
    If $srecv <> '' Then MsgBox(0, "", $srecv)
    Sleep(100)
    WEnd
    EndFunc ;==>_findalice

    [/autoit] [autoit][/autoit] [autoit]

    Func broadcastsend($sSocket, $sSendewert)
    UDPSend($sSocket, $sSendewert & @CRLF)
    If @error Then
    MsgBox(-1, "", "error send")
    EndIf
    EndFunc ;==>broadcastsend

    [/autoit] [autoit][/autoit] [autoit]

    Func _getDOSOutput($command)
    Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2)
    While 1
    $text &= StdoutRead($Pid, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd
    Return $text
    EndFunc ;==>_getDOSOutput

    [/autoit]

    Sah es bei dir denn bei deiner Alice Box auch so aus, dass der Destination Port und die Dest IP immer gleich waren? Oder haben die variiert?

    Gruß, und danke nochmal :)
    Spider