I like to propose a code addition for IGMP V3
(http://de.wikipedia.org/wiki/Internet_Group_Management_Protocol) to the
OverbyteICSWSocket unit.
It is mostly used by professional equipment (Cisco & Co) to join a multicast
group. We use it for our IPTV analyzing tool and the code is confirmed to
work. :)

Regards
Lars

Proposal:

Type 
    ip_mreq_source = record
      imr_multiaddr: in_addr; // IP multicast address of group
      imr_sourceaddr: in_addr; // IP address of source
      imr_interface: in_addr; // local IP address of interface
    end;

Const
   IP_ADD_SOURCE_MEMBERSHIP  = 15; // join IP group/source 
   {$EXTERNALSYM IP_ADD_SOURCE_MEMBERSHIP}


In the definition of 

 TCustomWSocket = class(TIcsWndControl)

[...]
    FMultiCastAddrStr   : String;
    FMultiCastIpTTL     : Integer;
    FMultiCastSourceAddrStr: String;  // the source IP of the multicast

[...]

    property MultiCastAddrStr: String               read  FMultiCastAddrStr
                                                    write FMultiCastAddrStr;
    property MultiCastIpTTL  : Integer              read  FMultiCastIpTTL
                                                    write FMultiCastIpTTL;
    property MultiCastSourceAddrStr: String         read
FMultiCastSourceAddrStr 
                                                    write
FMultiCastSourceAddrStr;  // the source IP of the multicast property -> must
be published in TWSocket
[...]

and in 

procedure TCustomWSocket.Listen;
var
    iStatus        : Integer;
    optval         : Integer;
    mreq           : ip_mreq;
    mreqSrc        : ip_mreq_source; // new

[...]

    SOCK_DGRAM :
        begin
            if FMultiCast then begin
            if (FMultiCastSourceAddrStr='') then  //simple join
            begin
                 { Use setsockopt() to join a multicast group }
                 { mreq.imr_multiaddr.s_addr :=
WSocket_inet_addr('225.0.0.37');}
                 { mreq.imr_multiaddr.s_addr := sin.sin_addr.s_addr;}
                 { mreq.imr_multiaddr.s_addr :=
WSocket_inet_addr(FAddrStr);}
                 mreq.imr_multiaddr.s_addr :=
WSocket_Synchronized_inet_addr(AnsiString(FMultiCastAddrStr));
                 { mreq.imr_interface.s_addr := htonl(INADDR_ANY);} { RK}
                 mreq.imr_interface.s_addr :=
WSocket_Synchronized_ResolveHost(AnsiString(FAddrStr)).s_addr;
                 iStatus := WSocket_Synchronized_SetSockOpt(FHSocket,
IPPROTO_IP,
 
IP_ADD_MEMBERSHIP,
                                                            mreq,
SizeOf(mreq));

                 if iStatus <> 0 then begin
                    SocketError('setsockopt(IP_ADD_MEMBERSHIP)');
                    Exit;
                 end;
            end
            else
            begin  //IGMP V3 Join
                 { Use setsockopt() to join a multicast group }
                 mreqSrc.imr_multiaddr.s_addr :=
WSocket_Synchronized_inet_addr(AnsiString(FMultiCastAddrStr));
                 mreqSrc.imr_sourceaddr.s_addr :=
WSocket_Synchronized_inet_addr(AnsiString(FMultiCastSourceAddrStr));
                 mreqSrc.imr_interface.s_addr :=
WSocket_Synchronized_ResolveHost(AnsiString(FAddrStr)).s_addr;

                 iStatus := WSocket_Synchronized_SetSockOpt(FHSocket,
IPPROTO_IP,
 
IP_ADD_SOURCE_MEMBERSHIP,
                                                            @mreqSrc,
SizeOf(mreqSrc));

                 if iStatus <> 0 then begin
                    SocketError('setsockopt(IP_ADD_SOURCE_MEMBERSHIP)');
                    Exit;
                 end;
            end;
            end;
            ChangeState(wsListening);
            ChangeState(wsConnected);
            TriggerSessionConnectedSpecial(0);
        end;


--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to