Files
azerothcore-wotlk-pbot/modules/dep/acelite/ace/ICMP_Socket.cpp

180 lines
4.3 KiB
C++

#include "ace/ICMP_Socket.h"
#if defined (ACE_HAS_ICMP_SUPPORT) && (ACE_HAS_ICMP_SUPPORT == 1)
#include "ace/ACE.h"
#include "ace/Sock_Connect.h"
#include "ace/Log_Category.h"
#include "ace/OS_NS_netdb.h"
#include "ace/OS_NS_sys_socket.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE (ACE_ICMP_Socket)
void
ACE_ICMP_Socket::dump (void) const
{
ACE_TRACE ("ACE_ICMP_Socket::dump");
}
ACE_ICMP_Socket::ACE_ICMP_Socket (void)
{
ACE_TRACE ("ACE_ICMP_Socket::ACE_ICMP_Socket");
}
ssize_t
ACE_ICMP_Socket::send (void const * buf,
size_t n,
ACE_Addr const & addr,
int flags) const
{
ACE_TRACE ("ACE_ICMP_Socket::send");
return ACE_OS::sendto (this->get_handle (),
(char const *) buf,
n,
flags,
(sockaddr const *) addr.get_addr (),
addr.get_size ());
}
ssize_t
ACE_ICMP_Socket::recv (void * buf,
size_t n,
ACE_Addr & addr,
int flags) const
{
ACE_TRACE ("ACE_ICMP_Socket::recv");
int addr_len = addr.get_size ();
ssize_t status = ACE_OS::recvfrom (this->get_handle (),
(char *) buf,
n,
flags,
(sockaddr *) addr.get_addr (),
(int*) &addr_len);
addr.set_size (addr_len);
return status;
}
ssize_t
ACE_ICMP_Socket::recv (void * buf,
size_t n,
int flags,
ACE_Time_Value const * timeout) const
{
ACE_TRACE ("ACE_ICMP_Socket::recv");
return ACE::recv (this->get_handle (),
buf,
n,
flags,
timeout);
}
int
ACE_ICMP_Socket::open (ACE_Addr const & local,
int protocol,
int reuse_addr)
{
ACE_TRACE ("ACE_ICMP_Socket::open");
// Check if icmp protocol is supported on this host
int proto_number = -1;
protoent *proto = 0;
if (! (proto = ACE_OS::getprotobyname ("icmp")))
{
ACELIB_ERROR_RETURN
((LM_ERROR,
ACE_TEXT ("(%P|%t) ACE_ICMP_Socket::open: %p; %s\n"),
ACE_TEXT ("getprotobyname"),
ACE_TEXT ("ICMP protocol is not properly configured ")
ACE_TEXT ("or not supported.")),
-1);
}
proto_number = proto->p_proto;
if (proto_number != IPPROTO_ICMP || proto_number != protocol)
{
ACELIB_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%P|%t) ACE::ICMP_Socket::open - ")
ACE_TEXT ("only IPPROTO_ICMP protocol is ")
ACE_TEXT ("currently supported.\n")),
-1);
}
if (ACE_SOCK::open (SOCK_RAW,
AF_INET,
protocol,
reuse_addr) == -1)
{
return -1;
}
return this->shared_open (local);
}
int
ACE_ICMP_Socket::shared_open (ACE_Addr const & local)
{
ACE_TRACE ("ACE_ICMP_Socket::shared_open");
int error = 0;
if (local == ACE_Addr::sap_any)
{
if (ACE::bind_port (this->get_handle ()) == -1)
{
error = 1;
}
}
else if (ACE_OS::bind (this->get_handle (),
reinterpret_cast<sockaddr *> (local.get_addr ()),
local.get_size ()) == -1)
{
error = 1;
}
if (error != 0)
{
this->close ();
}
return error ? -1 : 0;
}
unsigned short
ACE_ICMP_Socket::calculate_checksum (unsigned short * paddress,
int len)
{
int nleft = len;
int sum = 0;
unsigned short * w = paddress;
unsigned short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*((unsigned char *) &answer) = *((unsigned char *) w);
sum += answer;
}
// add back carry outs from top 16 bits to low 16 bits
sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16
sum += (sum >> 16); // add carry
answer = ~sum; // truncate to 16 bits
return (answer);
}
ACE_END_VERSIONED_NAMESPACE_DECL
#endif /* ACE_HAS_ICMP_SUPPORT == 1 */