[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / SOCK_Dgram_Bcast.cpp
blob7dbe796eed00bd89bc858bd731cd25c38a077399
1 // $Id: SOCK_Dgram_Bcast.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #include "ace/SOCK_Dgram_Bcast.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/ACE.h"
7 #include "ace/OS_NS_string.h"
8 #include "ace/os_include/net/os_if.h"
9 #include "ace/OS_NS_netdb.h"
10 #include "ace/OS_Memory.h"
12 #if !defined (__ACE_INLINE__)
13 #include "ace/SOCK_Dgram_Bcast.inl"
14 #endif /* __ACE_INLINE__ */
16 ACE_RCSID(ace, SOCK_Dgram_Bcast, "$Id: SOCK_Dgram_Bcast.cpp 80826 2008-03-04 14:51:23Z wotte $")
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Bcast)
22 ACE_Bcast_Node::ACE_Bcast_Node (ACE_INET_Addr &addr,
23 ACE_Bcast_Node *next)
24 : bcast_addr_ (addr),
25 next_ (next)
27 ACE_TRACE ("ACE_Bcast_Node::ACE_Bcast_Node");
30 void
31 ACE_SOCK_Dgram_Bcast::dump (void) const
33 #if defined (ACE_HAS_DUMP)
34 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::dump");
35 #endif /* ACE_HAS_DUMP */
38 // Close up and release resources.
40 int
41 ACE_SOCK_Dgram_Bcast::close (void)
43 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::close");
45 ACE_Bcast_Node *temp = this->if_list_;
46 this->if_list_ = 0;
48 // Release the dynamically allocated memory.
50 while (temp != 0)
52 ACE_Bcast_Node *hold = temp->next_;
53 delete temp;
54 temp = hold;
57 // Shut down the descriptor.
58 return ACE_SOCK::close ();
61 // Here's the simple-minded constructor.
63 ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (void)
64 : if_list_ (0)
66 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");
69 // Here's the general-purpose constructor used by a connectionless
70 // datagram ``server''...
72 ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (const ACE_Addr &local,
73 int protocol_family,
74 int protocol,
75 int reuse_addr,
76 const ACE_TCHAR *host_name)
77 : ACE_SOCK_Dgram (local, protocol_family, protocol, reuse_addr),
78 if_list_ (0)
80 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast");
82 if (this->mk_broadcast (host_name) == -1)
83 ACE_ERROR ((LM_ERROR,
84 ACE_TEXT ("%p\n"),
85 ACE_TEXT ("ACE_SOCK_Dgram_Bcast")));
88 // Here's the general-purpose open routine.
90 int
91 ACE_SOCK_Dgram_Bcast::open (const ACE_Addr &local,
92 int protocol_family,
93 int protocol,
94 int reuse_addr,
95 const ACE_TCHAR *host_name)
97 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::open");
99 if (this->ACE_SOCK_Dgram::open (local, protocol_family,
100 protocol, reuse_addr) == -1)
101 return -1;
103 return this->mk_broadcast (host_name);
106 // Make broadcast available for Datagram socket.
109 ACE_SOCK_Dgram_Bcast::mk_broadcast (const ACE_TCHAR *host_name)
111 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::mk_broadcast");
113 int one = 1;
115 if (ACE_OS::setsockopt (this->get_handle (),
116 SOL_SOCKET,
117 SO_BROADCAST,
118 (char *) &one,
119 sizeof one) == -1)
120 ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
121 "ACE_SOCK_Dgram_Bcast::mk_broadcast: setsockopt failed"),
122 -1);
124 #if !defined (ACE_WIN32) && !defined(__INTERIX)
125 ACE_HANDLE s = this->get_handle ();
127 char buf[BUFSIZ];
128 struct ifconf ifc;
130 ifc.ifc_len = sizeof buf;
131 ifc.ifc_buf = buf;
133 // Get interface structure and initialize the addresses using UNIX
134 // techniques.
135 if (ACE_OS::ioctl (s,
136 SIOCGIFCONF,
137 (char *) &ifc) == -1)
138 ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
139 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface configuration)"),
140 ACE_INVALID_HANDLE);
142 struct ifreq *ifr = ifc.ifc_req;
144 struct sockaddr_in host_addr;
146 // Get host ip address
147 if (host_name)
149 hostent *hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name));
151 if (hp == 0)
152 return -1;
153 else
154 #if defined(_UNICOS)
156 ACE_UINT64 haddr; // a place to put the address
157 char * haddrp = (char *) &haddr; // convert to char pointer
158 ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
159 host_addr.sin_addr.s_addr = haddr;
161 #else /* ! _UNICOS */
162 ACE_OS::memcpy ((char *) &host_addr.sin_addr.s_addr,
163 (char *) hp->h_addr,
164 hp->h_length);
165 #endif /* ! _UNICOS */
169 #if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_VXWORKS) && !defined(__APPLE__)
170 for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0;
171 n--, ifr++)
172 #else
174 There are addresses longer than sizeof (struct sockaddr) eg. IPv6
175 or QNX::links. In this case address does not fit into struct ifreq.
176 The code below could be applied everywhere, but not every system
177 provides sockaddr.sa_len field.
179 for (int nbytes = ifc.ifc_len; nbytes >= (int) sizeof (struct ifreq) &&
180 ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
181 (nbytes >= (int) sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len) : 1);
182 ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
183 (nbytes -= sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len,
184 ifr = (struct ifreq *)
185 ((caddr_t) &ifr->ifr_addr + ifr->ifr_addr.sa_len)) :
186 (nbytes -= sizeof (struct ifreq), ifr++)))
187 #endif /* !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_VXWORKS) && !defined(__APPLE__) */
189 #if defined (__QNX__) || defined (ACE_VXWORKS)
190 // Silently skip link interfaces
191 if (ifr->ifr_addr.sa_family == AF_LINK)
192 continue;
193 #endif /* __QNX__ */
194 // Compare host ip address with interface ip address.
195 if (host_name)
197 struct sockaddr_in if_addr;
199 ACE_OS::memcpy (&if_addr,
200 &ifr->ifr_addr,
201 sizeof if_addr);
203 if (host_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
204 continue;
207 if (ifr->ifr_addr.sa_family != AF_INET)
209 // Note that some systems seem to generate 0 (AF_UNDEF) for
210 // the sa_family, even when there are no errors! Thus, we
211 // only print an error if this is not the case, or if we're
212 // in "debugging" mode.
213 if (ifr->ifr_addr.sa_family != 0
214 || ACE::debug ())
215 ACE_DEBUG ((LM_DEBUG,
216 "warning %p: sa_family: %d\n",
217 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Not AF_INET",
218 ifr->ifr_addr.sa_family));
219 continue;
222 struct ifreq flags = *ifr;
223 struct ifreq if_req = *ifr;
225 if (ACE_OS::ioctl (s,
226 SIOCGIFFLAGS,
227 (char *) &flags) == -1)
229 ACE_ERROR ((LM_ERROR, "%p [%s]\n",
230 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface flags)",
231 flags.ifr_name));
232 continue;
235 if (ACE_BIT_ENABLED (flags.ifr_flags,
236 IFF_UP) == 0)
238 ACE_ERROR ((LM_ERROR, "%p [%s]\n",
239 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Network interface is not up",
240 flags.ifr_name));
241 continue;
244 if (ACE_BIT_ENABLED (flags.ifr_flags,
245 IFF_LOOPBACK))
246 continue;
248 if (ACE_BIT_ENABLED (flags.ifr_flags,
249 IFF_BROADCAST))
251 if (ACE_OS::ioctl (s,
252 SIOCGIFBRDADDR,
253 (char *) &if_req) == -1)
254 ACE_ERROR ((LM_ERROR, "%p [%s]\n",
255 "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get broadaddr)",
256 flags.ifr_name));
257 else
259 ACE_INET_Addr addr (reinterpret_cast <sockaddr_in *>
260 (&if_req.ifr_broadaddr),
261 sizeof if_req.ifr_broadaddr);
262 ACE_NEW_RETURN (this->if_list_,
263 ACE_Bcast_Node (addr,
264 this->if_list_),
265 -1);
268 else
270 if (host_name != 0)
271 ACE_ERROR ((LM_ERROR, "%p [%s]\n",
272 "ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface.",
273 flags.ifr_name));
276 #else
277 ACE_UNUSED_ARG (host_name);
279 ACE_INET_Addr addr (u_short (0),
280 ACE_UINT32 (INADDR_BROADCAST));
281 ACE_NEW_RETURN (this->if_list_,
282 ACE_Bcast_Node (addr,
283 this->if_list_),
284 -1);
285 #endif /* !ACE_WIN32 && !__INTERIX */
286 if (this->if_list_ == 0)
288 errno = ENXIO;
289 return -1;
291 else
292 return 0;
295 // Broadcast the datagram to every interface. Returns the average
296 // number of bytes sent.
298 ssize_t
299 ACE_SOCK_Dgram_Bcast::send (const void *buf,
300 size_t n,
301 u_short port_number,
302 int flags) const
304 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
305 ssize_t iterations = 0;
306 ssize_t total_bytes = 0;
308 if (this->if_list_ == 0)
309 return -1;
311 for (ACE_Bcast_Node *temp = this->if_list_;
312 temp != 0;
313 temp = temp->next_)
315 temp->bcast_addr_.set_port_number (port_number);
317 ssize_t bytes_sent = ACE_SOCK_Dgram::send (buf,
319 temp->bcast_addr_,
320 flags);
322 if (bytes_sent == -1)
323 return -1;
324 else
325 total_bytes += bytes_sent;
327 iterations++;
330 return iterations == 0 ? 0 : total_bytes / iterations;
333 #if defined (ACE_HAS_MSG)
334 // Broadcast datagram to every interfaces.
336 ssize_t
337 ACE_SOCK_Dgram_Bcast::send (const iovec iov[],
338 int n,
339 u_short port_number,
340 int flags) const
342 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
344 if (this->if_list_ == 0)
345 return -1;
347 // Send the message to every interface.
349 for (ACE_Bcast_Node *temp = this->if_list_;
350 temp != 0;
351 temp = temp->next_)
353 temp->bcast_addr_.set_port_number (port_number);
355 if (ACE_SOCK_Dgram::send (iov,
357 temp->bcast_addr_,
358 flags) == -1)
359 return -1;
362 return 0;
365 // Broadcast an iovec of size N to ADDR as a datagram (note that addr
366 // must be preassigned to the broadcast address of the subnet...).
368 ssize_t
369 ACE_SOCK_Dgram_Bcast::send (const iovec iov[],
370 int n,
371 const ACE_Addr &addr,
372 int flags) const
374 ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send");
376 return ACE_SOCK_Dgram::send (iov, n, addr, flags);
378 #endif /* ACE_HAS_MSG */
380 ACE_END_VERSIONED_NAMESPACE_DECL