summaryrefslogtreecommitdiff
path: root/ace/SOCK_Dgram_Bcast.cpp
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
commita5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch)
treebcf0a25c3d45a209a6e3ac37b233a4812f29c732 /ace/SOCK_Dgram_Bcast.cpp
downloadATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz
Initial revision
Diffstat (limited to 'ace/SOCK_Dgram_Bcast.cpp')
-rw-r--r--ace/SOCK_Dgram_Bcast.cpp243
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 */