At 16:41 04.11.98 +0530, S.RadhaKrishna wrote:
>Hi,
> Actually I'm looking for something that a user (not root) can do from an
>application program. It's not that I wanted to send always through en1
>and not en0. Like, when we send a unicast address, the kernel routes to the
>appropriate interface depending on the destination address. Can we say from
>an application program using socket interface to send a multicast packet
>through a particular interface ? I'm not sure whether it's possible using
>setsockopt, but this also needs "root" privileges I guess! Can't the kernel
>route the multicast packet on the interface to which the application has
>bound using the "bind" socket call?
>thanks
the following code snipped works for me...
// check the interfaces and set the multicast network interface
if (rMulticast) {
struct ifreq ifr;
ifr = getMulticastInterface(aMulticastInterface);
memcpy ((char *)&rMulticastInterface, (char *)&ifr.ifr_addr,
sizeof(ifr.ifr_addr));
#ifdef __SUNOS__
if (setsockopt(rSocket, IPPROTO_IP, IP_MULTICAST_IF,
(char*)&rMulticastInterface.sin_addr, sizeof(rMulticastInterface.sin_addr))
== -1) {
#else
if (setsockopt(rSocket, IPPROTO_IP, IP_MULTICAST_IF,
&rMulticastInterface.sin_addr, sizeof(rMulticastInterface.sin_addr)) == -1) {
#endif
ostrstream os;
os << me << " setsockopt() failed: IP_MULTICAST_IF " <<
strerror(errno) << ends;
char *msg = os.str();
rLog->log(Log::ERROR, "%s", msg);
throw data_sink_error (msg);
}
{
ostrstream os;
os << me << " interface " << ifr.ifr_name << ", inet " << inet_ntoa
(rMulticastInterface.sin_addr) << ends;
char *msg = os.str();
rLog->log(Log::NOTICE, "%s", msg);
delete[] msg;
}
}
The getMulticastInterface() call:
struct ifreq TcpIpSinkThread::getMulticastInterface (const char*
aMulticastInterface) {
char *me = "TcpIpSinkThread::getMulticastInterface()";
// locals
struct ifconf ifc;
char buf[4096];
string multicastInterface;
bool interface = false;
vector<string> interfaces;
// set the string if not null
if (aMulticastInterface != NULL)
multicastInterface = aMulticastInterface;
// retrieve the interfaces
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
if (ioctl (rSocket, SIOCGIFCONF, (char *) &ifc) < 0) {
ostrstream os;
os << me << " ioctl() failed: SIOCGIFCONF " << strerror(errno) << ends;
char *msg = os.str();
rLog->log(Log::ERROR, "%s", msg);
throw data_sink_error (msg);
}
// now retrieve the flags
struct ifreq *ifr;
// loop over all interfaces
ifr = ifc.ifc_req;
for (int n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) {
// check if this is the requested interface
if ((!multicastInterface.empty()) &&
multicastInterface.compare(ifr->ifr_name))
continue;
// pushback the interface we are just checking
interfaces.push_back(string(ifr->ifr_name));
// check if it supports this protocol family
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
// now get the flags
if (ioctl(rSocket, SIOCGIFFLAGS, (char *) ifr) < 0) {
ostrstream os;
os << me << " ioctl() failed: SIOCGIFFLAGS " << strerror(errno) << ends;
char *msg = os.str();
rLog->log(Log::ERROR, "%s", msg);
throw data_sink_error (msg);
}
// now check if this is a valid, up, not loopback, and
multicast-supporting if
if (((ifr->ifr_flags & IFF_UP) == 0) || (ifr->ifr_flags & IFF_LOOPBACK) ||
((ifr->ifr_flags & IFF_MULTICAST) == 0))
continue;
// this interface supports multicast
interface = true;
break;
}
// did we have a valid interface?
if (!interface) {
ostrstream os;
os << me << " failed: (";
// did we check some interfaces
if (interfaces.size() > 0) {
for (int i=0; i<interfaces.size()-1; i++)
os << interfaces[i] << ", ";
os << interfaces[interfaces.size()-1];
os << ") not multicast enabled" << ends;
}
// else we did not find the selected interface
else
os << multicastInterface << ") unknown interface" << ends;
// and throw the exception
char *msg = os.str();
rLog->log(Log::ERROR, "%s", msg);
throw data_sink_error (msg);
}
return *ifr;
}
--
Christoph Moar ([EMAIL PROTECTED]) Tel. (++49) 89 636-44628
SIEMENS AG Corporate Technology Fax. (++49) 89 636-47457
Information and Media Technology
Office Adress: SIEMENS AG ZT IK 1, Otto-Hahn-Ring 6, D-81739 Munich
Postal Adress: SIEMENS AG ZT IK 1, D-81730 Munich
pgpkey http://pgp5.ai.mit.edu:11371/pks/lookup?op=index&search=0xae81b9cc
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]