00001 #include "ace_pch.h"
00002
00003
00004 #include "ace/SOCK_Dgram_Bcast.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/ACE.h"
00007
00008 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00009 #include "ace/SOCK_Dgram_Bcast.i"
00010 #endif
00011
00012 ACE_RCSID(ace, SOCK_Dgram_Bcast, "$Id: SOCK_Dgram_Bcast.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00013
00014 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Bcast)
00015
00016 ACE_Bcast_Node::ACE_Bcast_Node (ACE_INET_Addr &addr,
00017 ACE_Bcast_Node *next)
00018 : bcast_addr_ (addr),
00019 next_ (next)
00020 {
00021 ACE_TRACE ("ACE_Bcast_Node::ACE_Bcast_Node");
00022 }
00023
00024 void
00025 ACE_SOCK_Dgram_Bcast::dump (void) const
00026 {
00027 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::dump");
00028 }
00029
00030
00031
00032 int
00033 ACE_SOCK_Dgram_Bcast::close (void)
00034 {
00035 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::close");
00036
00037 ACE_Bcast_Node *temp = this->if_list_;
00038
00039
00040
00041 while (temp != 0)
00042 {
00043 ACE_Bcast_Node *hold = temp->next_;
00044 delete temp;
00045 temp = hold;
00046 }
00047
00048
00049 return ACE_SOCK::close ();
00050 }
00051
00052
00053
00054 ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (void)
00055 : if_list_ (0)
00056 {
00057 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");
00058 }
00059
00060
00061
00062
00063 ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (const ACE_Addr &local,
00064 int protocol_family,
00065 int protocol,
00066 int reuse_addr,
00067 const ACE_TCHAR *host_name)
00068 : ACE_SOCK_Dgram (local, protocol_family, protocol, reuse_addr),
00069 if_list_ (0)
00070 {
00071 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");
00072
00073 if (this->mk_broadcast (host_name) == -1)
00074 ACE_ERROR ((LM_ERROR,
00075 ACE_LIB_TEXT ("%p\n"),
00076 ACE_LIB_TEXT ("ACE_SOCK_Dgram_Bcast")));
00077 }
00078
00079
00080
00081 int
00082 ACE_SOCK_Dgram_Bcast::open (const ACE_Addr &local,
00083 int protocol_family,
00084 int protocol,
00085 int reuse_addr,
00086 const ACE_TCHAR *host_name)
00087 {
00088 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::open");
00089
00090 if (this->ACE_SOCK_Dgram::open (local, protocol_family,
00091 protocol, reuse_addr) == -1)
00092 return -1;
00093
00094 return this->mk_broadcast (host_name);
00095 }
00096
00097
00098
00099 int
00100 ACE_SOCK_Dgram_Bcast::mk_broadcast (const ACE_TCHAR *host_name)
00101 {
00102 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::mk_broadcast");
00103
00104 int one = 1;
00105
00106 if (ACE_OS::setsockopt (this->get_handle (),
00107 SOL_SOCKET,
00108 SO_BROADCAST,
00109 (char *) &one,
00110 sizeof one) == -1)
00111 return -1;
00112
00113 #if !defined (ACE_WIN32)
00114 ACE_HANDLE s = this->get_handle ();
00115
00116 char buf[BUFSIZ];
00117 struct ifconf ifc;
00118
00119 ifc.ifc_len = sizeof buf;
00120 ifc.ifc_buf = buf;
00121
00122
00123
00124 if (ACE_OS::ioctl (s,
00125 SIOCGIFCONF,
00126 (char *) &ifc) == -1)
00127 ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
00128 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface configuration)"),
00129 ACE_INVALID_HANDLE);
00130
00131 struct ifreq *ifr = ifc.ifc_req;
00132
00133 struct sockaddr_in host_addr;
00134
00135
00136 if (host_name)
00137 {
00138 hostent *hp = ACE_OS::gethostbyname (host_name);
00139
00140 if (hp == 0)
00141 return -1;
00142 else
00143 #if defined(_UNICOS)
00144 {
00145 ACE_UINT64 haddr;
00146 char * haddrp = (char *) &haddr;
00147 ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
00148 host_addr.sin_addr.s_addr = haddr;
00149 }
00150 #else
00151 ACE_OS::memcpy ((char *) &host_addr.sin_addr.s_addr,
00152 (char *) hp->h_addr,
00153 hp->h_length);
00154 #endif
00155 }
00156
00157 for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0;
00158 #if !defined(CHORUS_4) && !defined(AIX)
00159 n--, ifr++)
00160 #else
00161 n--,
00162 ((ifr->ifr_addr.sa_len <= sizeof (struct sockaddr)) ?
00163 ifr++ :
00164 ifr = (struct ifreq *)
00165 (ifr->ifr_addr.sa_len + (caddr_t) &ifr->ifr_addr)))
00166 #endif
00167 {
00168
00169 if (host_name)
00170 {
00171 struct sockaddr_in if_addr;
00172
00173 ACE_OS::memcpy (&if_addr,
00174 &ifr->ifr_addr,
00175 sizeof if_addr);
00176
00177 if (host_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
00178 continue;
00179 }
00180
00181 if (ifr->ifr_addr.sa_family != AF_INET)
00182 {
00183
00184
00185
00186
00187 if (ifr->ifr_addr.sa_family != 0
00188 || ACE::debug () > 0)
00189 ACE_DEBUG ((LM_DEBUG,
00190 "warning %p: sa_family: %d\n",
00191 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Not AF_INET",
00192 ifr->ifr_addr.sa_family));
00193 continue;
00194 }
00195
00196 struct ifreq flags = *ifr;
00197 struct ifreq if_req = *ifr;
00198
00199 if (ACE_OS::ioctl (s,
00200 SIOCGIFFLAGS,
00201 (char *) &flags) == -1)
00202 {
00203 ACE_ERROR ((LM_ERROR, "%p\n",
00204 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface flags)"));
00205 continue;
00206 }
00207
00208 if (ACE_BIT_ENABLED (flags.ifr_flags,
00209 IFF_UP) == 0)
00210 {
00211 ACE_ERROR ((LM_ERROR, "%p\n",
00212 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Network interface is not up"));
00213 continue;
00214 }
00215
00216 if (ACE_BIT_ENABLED (flags.ifr_flags,
00217 IFF_LOOPBACK))
00218 continue;
00219
00220 if (ACE_BIT_ENABLED (flags.ifr_flags,
00221 IFF_BROADCAST))
00222 {
00223 if (ACE_OS::ioctl (s,
00224 SIOCGIFBRDADDR,
00225 (char *) &if_req) == -1)
00226 ACE_ERROR ((LM_ERROR, "%p\n",
00227 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get broadaddr)"));
00228 else
00229 {
00230 ACE_INET_Addr addr (ACE_reinterpret_cast (sockaddr_in *,
00231 &if_req.ifr_broadaddr),
00232 sizeof if_req.ifr_broadaddr);
00233 ACE_NEW_RETURN (this->if_list_,
00234 ACE_Bcast_Node (addr,
00235 this->if_list_),
00236 -1);
00237 }
00238 }
00239 else
00240 ACE_ERROR ((LM_ERROR, "%p\n",
00241 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface."));
00242 }
00243 #else
00244 ACE_UNUSED_ARG (host_name);
00245
00246 ACE_INET_Addr addr (u_short (0),
00247 ACE_UINT32 (INADDR_BROADCAST));
00248 ACE_NEW_RETURN (this->if_list_,
00249 ACE_Bcast_Node (addr,
00250 this->if_list_),
00251 -1);
00252 #endif
00253 return this->if_list_ == 0 ? -1 : 0;
00254 }
00255
00256
00257
00258
00259 ssize_t
00260 ACE_SOCK_Dgram_Bcast::send (const void *buf,
00261 size_t n,
00262 u_short port_number,
00263 int flags) const
00264 {
00265 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
00266 size_t iterations = 0;
00267 ssize_t total_bytes = 0;
00268
00269 if (this->if_list_ == 0)
00270 return -1;
00271
00272 for (ACE_Bcast_Node *temp = this->if_list_;
00273 temp != 0;
00274 temp = temp->next_)
00275 {
00276 temp->bcast_addr_.set_port_number (port_number);
00277
00278 ssize_t bytes_sent = ACE_SOCK_Dgram::send (buf,
00279 n,
00280 temp->bcast_addr_,
00281 flags);
00282
00283 if (bytes_sent == -1)
00284 return -1;
00285 else
00286 total_bytes += bytes_sent;
00287
00288 iterations++;
00289 }
00290
00291 return iterations == 0 ? 0 : total_bytes / iterations;
00292 }
00293
00294 #if defined (ACE_HAS_MSG)
00295
00296
00297 ssize_t
00298 ACE_SOCK_Dgram_Bcast::send (const iovec iov[],
00299 int n,
00300 u_short ,
00301 int flags) const
00302 {
00303 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
00304
00305 if (this->if_list_ == 0)
00306 return -1;
00307
00308
00309
00310 for (ACE_Bcast_Node *temp = this->if_list_;
00311 temp != 0;
00312 temp = temp->next_)
00313 if (ACE_SOCK_Dgram::send (iov,
00314 n,
00315 temp->bcast_addr_,
00316 flags) == -1)
00317 return -1;
00318
00319 return 0;
00320 }
00321
00322
00323
00324
00325 ssize_t
00326 ACE_SOCK_Dgram_Bcast::send (const iovec iov[],
00327 int n,
00328 const ACE_Addr &addr,
00329 int flags) const
00330 {
00331 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
00332
00333 return ACE_SOCK_Dgram::send (iov, n, addr, flags);
00334 }
00335 #endif