diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
commit | a5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch) | |
tree | bcf0a25c3d45a209a6e3ac37b233a4812f29c732 /ace/SOCK_Dgram_Bcast.cpp | |
download | ATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz |
Initial revision
Diffstat (limited to 'ace/SOCK_Dgram_Bcast.cpp')
-rw-r--r-- | ace/SOCK_Dgram_Bcast.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/ace/SOCK_Dgram_Bcast.cpp b/ace/SOCK_Dgram_Bcast.cpp new file mode 100644 index 00000000000..b38fe768e6f --- /dev/null +++ b/ace/SOCK_Dgram_Bcast.cpp @@ -0,0 +1,243 @@ +// SOCK_Dgram_Bcast.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/SOCK_Dgram_Bcast.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Bcast) + +ACE_Bcast_Node::ACE_Bcast_Node (ACE_INET_Addr &addr, + ACE_Bcast_Node *next) + : bcast_addr_ (addr), + next_ (next) +{ + ACE_TRACE ("ACE_Bcast_Node::ACE_Bcast_Node"); +} + +void +ACE_SOCK_Dgram_Bcast::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::dump"); +} + +// Close up and release resources. + +int +ACE_SOCK_Dgram_Bcast::close (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::close"); + + ACE_Bcast_Node *temp = this->if_list_; + + // Release the dynamically allocated memory. + while (temp != 0) + { + ACE_Bcast_Node *hold = temp->next_; + delete temp; + temp = hold; + } + + // Shut down the descriptor. + return ACE_SOCK::close (); +} + +// Here's the simple-minded constructor. + +ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (void) + : if_list_ (0) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast"); +} + +// Here's the general-purpose constructor used by a connectionless +// datagram ``server''... + +ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (const ACE_Addr &local, + int protocol_family, + int protocol) + : ACE_SOCK_Dgram (local, protocol_family, protocol), + if_list_ (0) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast"); + + if (this->mk_broadcast () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Dgram_Bcast")); +} + +// Here's the general-purpose open routine. + +int +ACE_SOCK_Dgram_Bcast::open (const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::open"); + if (this->ACE_SOCK_Dgram::open (local, protocol_family, + protocol) == -1) + return -1; + + return this->mk_broadcast (); +} + +// Make broadcast available for Datagram socket. + +int +ACE_SOCK_Dgram_Bcast::mk_broadcast (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::mk_broadcast"); + + int one = 1; + + if (ACE_OS::setsockopt (this->get_handle (), SOL_SOCKET, SO_BROADCAST, + (char *) &one, sizeof one) == -1) + return -1; + +#if !defined(ACE_WIN32) + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq *ifr; + + struct ifreq flags; + struct ifreq if_req; + + int s = this->get_handle (); + + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = buf; + + // Get interface structure and initialize the addresses using UNIX techniques. + if (ACE_OS::ioctl (s, SIOCGIFCONF, (char *) &ifc) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface configuration)"), + ACE_INVALID_HANDLE); + + ifr = ifc.ifc_req; + + for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0; n--, ifr++) + { + + if (ifr->ifr_addr.sa_family != AF_INET) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Dgram_Bcast::mk_broadcast: Not AF_INET")); + continue; + } + + flags = if_req = *ifr; + + if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface flags)")); + continue; + } + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_UP) == 0) + { + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: Network interface is not up")); + continue; + } + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK)) + continue; + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST)) + { + if (ACE_OS::ioctl (s, SIOCGIFBRDADDR, (char *) &if_req) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get broadaddr)")); + else + { + ACE_INET_Addr addr ((sockaddr_in *) &if_req.ifr_broadaddr, + sizeof if_req.ifr_broadaddr); + ACE_NEW_RETURN (this->if_list_, ACE_Bcast_Node (addr, this->if_list_), -1); + } + } + else + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface.")); + } +#else + ACE_INET_Addr addr (u_short (0), ACE_UINT32 (INADDR_BROADCAST)); + ACE_NEW_RETURN (this->if_list_, ACE_Bcast_Node (addr, this->if_list_), -1); +#endif /* !ACE_WIN32 */ + return this->if_list_ == 0 ? -1 : 0; +} + +// Broadcast the datagram to every interface. Returns the average +// number of bytes sent. + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const void *buf, + size_t n, + u_short port_number, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + size_t iterations = 0; + ssize_t total_bytes = 0; + + if (this->if_list_ == 0) + return -1; + + for (ACE_Bcast_Node *temp = this->if_list_; + temp != 0; + temp = temp->next_) + { + temp->bcast_addr_.set_port_number (port_number); + + ssize_t bytes_sent = ACE_SOCK_Dgram::send (buf, n, + temp->bcast_addr_, + flags); + + if (bytes_sent == -1) + return -1; + else + total_bytes += bytes_sent; + + iterations++; + } + + return iterations == 0 ? 0 : total_bytes / iterations; +} + +#if defined (ACE_HAS_MSG) +// Broadcast datagram to every interfaces. + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const iovec iov[], + size_t n, + u_short port_number, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + + if (this->if_list_ == 0) + return -1; + + // Send the message to every interface. + + for (ACE_Bcast_Node *temp = this->if_list_; temp != 0; temp++) + if (ACE_SOCK_Dgram::send (iov, n, temp->bcast_addr_, flags) == -1) + return -1; + + return 0; +} + +// Broadcast an ACE_IO_Vector of size N to ADDR as a datagram (note +// that addr must be preassigned to the broadcast address of the +// subnet...). + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + + return ACE_SOCK_Dgram::send (iov, n, addr, flags); +} +#endif /* ACE_HAS_MSG */ |