Link to home
Start Free TrialLog in
Avatar of desktop2
desktop2

asked on

setsockopt IP_MULTICAST_IF

How can I set this option on socket?
IP_MULTICAST_IF
Avatar of kandura
kandura

To make your life a whole lot easier, I'd suggest you install IO::Socket::Multicast as it contains all the things you need nicely wrapped into object methods.

The low level details are:
   The level for this option is SOL_IP
   Value is a ip_mreqn structure

In other words, you would call it as
   setsockopt $socket. SOL_IP, IP_MULTICAST_IF, $ip_mreqn
where $socket is your socket, and $ip_mreqn is the structure mentioned above (packed of course).

Quoting 'man ip':

 IP_MULTICAST_IF
              Set the local device for a multicast socket.  Argu­ment is an ip_mreqn
              or ip_mreq structure similar to IP_ADD_MEMBERSHIP.

Over there I read:
       IP_ADD_MEMBERSHIP
              Join  a  multicast  group.  Argument  is  a  struct
              ip_mreqn structure.

              struct ip_mreqn {
                  struct in_addr imr_multiaddr; /* IP multicast group address */
                  struct in_addr imr_address;   /* IP address of local interface */
                  int            imr_ifindex;   /* interface index */
              };

              imr_multiaddr contains the address of the multicast
              group the application wants to join or  leave.   It
              must  be a valid multicast address.  imr_address is
              the address of the local interface with  which  the
              system  should  join  the multicast group; if it is
              equal to INADDR_ANY  an  appropriate  interface  is
              chosen by the system.  imr_ifindex is the interface
              index of the interface that should  join/leave  the
              imr_multiaddr   group,   or   0   to  indicate  any
              interface.

              For compatibility, the  old  ip_mreq  structure  is
              still  supported.  It differs from ip_mreqn only by
              not including the imr_ifindex field. Only valid  as
              a setsockopt(2).
Avatar of desktop2

ASKER

Could you please show how should I pack "ip_mreqn  $ip_mreqn" before calling setsockopt
Still having problem with it :-(

assuming you have obtained the in_addr parts of the structure through sockaddr_in or something like that, you would do

$packed = pack "NNI", $imr_multiaddr, $imr_address, $imr_ifindex;

N   An unsigned long in "network" (big-endian) order.
I   An unsigned integer value.
socket(Sock, PF_INET, SOCK_DGRAM, 0);
bind(Sock, sockaddr_in(0, INADDR_ANY)); # use first free port
setsockopt(Sock, SOL_IP, IP_MULTICAST_IF, $IpPacked) or DebugOut("Error setsockopt $!\n");

It returns error "Protocol not available"

Does it mean that network does not support multicast?
No, it probably means that the constants SOL_IP and IP_MULTICAST_IF are not exported from Socket.

I dug a little deeper (with the help of the source of IO::Socket::Multicast), and the standard include files on my system.
SOL_IP is defined as 0, and IP_MULTICAST_IF is defined as 32.

Either try the setsockopt call with those values, or follow my original recommendation to use IO::Socket::Multicast.

Does your operating system support multicast?
By the way, is there a specific reason why you're writing all this code yourself instead of using IO::Socket::Multicast?
It worked OK, thanks.
but I still have problem with
setsockopt(Sock, 0, 3, pack("C", 80)) or DebugOut("Error setsockopt(IP_MULTICAST_TTL) $!\n");

same error :-(

I'm not sure if Apache where I'm hosting my web site support multicast or not...
Where can I download this module IO:Socket::Multicast?
ASKER CERTIFIED SOLUTION
Avatar of kandura
kandura

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial