00001
00002
00003 #include "ace/ICMP_Socket.h"
00004
00005 #if defined (ACE_HAS_ICMP_SUPPORT) && (ACE_HAS_ICMP_SUPPORT == 1)
00006
00007 #include "ace/ACE.h"
00008 #include "ace/Log_Msg.h"
00009 #include "ace/OS_NS_netdb.h"
00010 #include "ace/OS_NS_sys_socket.h"
00011
00012
00013 ACE_RCSID (ace,
00014 ICMP_Socket,
00015 "$Id: ICMP_Socket.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00016
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 ACE_ALLOC_HOOK_DEFINE (ACE_ICMP_Socket)
00021
00022
00023 void
00024 ACE_ICMP_Socket::dump (void) const
00025 {
00026 ACE_TRACE ("ACE_ICMP_Socket::dump");
00027 }
00028
00029 ACE_ICMP_Socket::ACE_ICMP_Socket (void)
00030 {
00031 ACE_TRACE ("ACE_ICMP_Socket::ACE_ICMP_Socket");
00032 }
00033
00034 ssize_t
00035 ACE_ICMP_Socket::send (void const * buf,
00036 size_t n,
00037 ACE_Addr const & addr,
00038 int flags) const
00039 {
00040 ACE_TRACE ("ACE_ICMP_Socket::send");
00041
00042 return ACE_OS::sendto (this->get_handle (),
00043 (char const *) buf,
00044 n,
00045 flags,
00046 (sockaddr const *) addr.get_addr (),
00047 addr.get_size ());
00048 }
00049
00050 ssize_t
00051 ACE_ICMP_Socket::recv (void * buf,
00052 size_t n,
00053 ACE_Addr & addr,
00054 int flags) const
00055 {
00056 ACE_TRACE ("ACE_ICMP_Socket::recv");
00057
00058 int addr_len = addr.get_size ();
00059 ssize_t status = ACE_OS::recvfrom (this->get_handle (),
00060 (char *) buf,
00061 n,
00062 flags,
00063 (sockaddr *) addr.get_addr (),
00064 (int*) &addr_len);
00065 addr.set_size (addr_len);
00066
00067 return status;
00068 }
00069
00070 ssize_t
00071 ACE_ICMP_Socket::recv (void * buf,
00072 size_t n,
00073 int flags,
00074 ACE_Time_Value const * timeout) const
00075 {
00076 ACE_TRACE ("ACE_ICMP_Socket::recv");
00077
00078 return ACE::recv (this->get_handle (),
00079 buf,
00080 n,
00081 flags,
00082 timeout);
00083 }
00084
00085 int
00086 ACE_ICMP_Socket::open (ACE_Addr const & local,
00087 int protocol,
00088 int reuse_addr)
00089 {
00090 ACE_TRACE ("ACE_ICMP_Socket::open");
00091
00092
00093 int proto_number = -1;
00094 protoent *proto;
00095
00096 if (! (proto = getprotobyname ("icmp")))
00097 {
00098 ACE_ERROR_RETURN
00099 ((LM_ERROR,
00100 ACE_TEXT ("(%P|%t) ACE_ICMP_Socket::open: %p; %s\n"),
00101 ACE_TEXT ("getprotobyname"),
00102 ACE_TEXT ("ICMP protocol is not properly configured ")
00103 ACE_TEXT ("or not supported.")),
00104 -1);
00105 }
00106 proto_number = proto->p_proto;
00107
00108 if (proto_number != IPPROTO_ICMP || proto_number != protocol)
00109 {
00110 ACE_ERROR_RETURN ((LM_ERROR,
00111 ACE_TEXT ("(%P|%t) ACE::ICMP_Socket::open - ")
00112 ACE_TEXT ("only IPPROTO_ICMP protocol is ")
00113 ACE_TEXT ("currently supported.\n")),
00114 -1);
00115 }
00116
00117 if (ACE_SOCK::open (SOCK_RAW,
00118 AF_INET,
00119 protocol,
00120 reuse_addr) == -1)
00121 {
00122 return -1;
00123 }
00124
00125 return this->shared_open (local);
00126 }
00127
00128 int
00129 ACE_ICMP_Socket::shared_open (ACE_Addr const & local)
00130 {
00131 ACE_TRACE ("ACE_ICMP_Socket::shared_open");
00132
00133 int error = 0;
00134 if (local == ACE_Addr::sap_any)
00135 {
00136 if (ACE::bind_port (this->get_handle ()) == -1)
00137 {
00138 error = 1;
00139 }
00140 }
00141 else if (ACE_OS::bind (this->get_handle (),
00142 reinterpret_cast<sockaddr *> (local.get_addr ()),
00143 local.get_size ()) == -1)
00144 {
00145 error = 1;
00146 }
00147
00148 if (error != 0)
00149 {
00150 this->close ();
00151 }
00152
00153 return error ? -1 : 0;
00154 }
00155
00156 unsigned short
00157 ACE_ICMP_Socket::calculate_checksum (unsigned short * paddress,
00158 int len)
00159 {
00160 int nleft = len;
00161 int sum = 0;
00162 unsigned short * w = paddress;
00163 unsigned short answer = 0;
00164 while (nleft > 1)
00165 {
00166 sum += *w++;
00167 nleft -= 2;
00168 }
00169
00170 if (nleft == 1)
00171 {
00172 *((unsigned char *) &answer) = *((unsigned char *) w);
00173 sum += answer;
00174 }
00175
00176
00177 sum = (sum >> 16) + (sum & 0xffff);
00178 sum += (sum >> 16);
00179 answer = ~sum;
00180
00181 return (answer);
00182 }
00183
00184 ACE_END_VERSIONED_NAMESPACE_DECL
00185
00186 #endif