ICMP_Socket.cpp

Go to the documentation of this file.
00001 // ICMP_Socket.cpp,v 1.7 2005/10/28 16:14:52 ossama Exp
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            "ICMP_Socket.cpp,v 1.7 2005/10/28 16:14:52 ossama Exp")
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   // Check if icmp protocol is supported on this host
00093   int proto_number = -1;
00094   protoent *proto;
00095 
00096   if (! (proto = getprotobyname ("icmp")))
00097     {
00098       ACE_ERROR_RETURN
00099         ((LM_ERROR,
00100           ACE_LIB_TEXT ("(%P|%t) ACE_ICMP_Socket::open: %p; %s\n"),
00101           ACE_LIB_TEXT ("getprotobyname"),
00102           ACE_LIB_TEXT ("ICMP protocol is not properly configured ")
00103           ACE_LIB_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_LIB_TEXT ("(%P|%t) ACE::ICMP_Socket::open - ")
00112                          ACE_LIB_TEXT ("only IPPROTO_ICMP protocol is ")
00113                          ACE_LIB_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   // add back carry outs from top 16 bits to low 16 bits
00177   sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16
00178   sum += (sum >> 16);                 // add carry
00179   answer = ~sum;                      // truncate to 16 bits
00180 
00181   return (answer);
00182 }
00183 
00184 ACE_END_VERSIONED_NAMESPACE_DECL
00185 
00186 #endif  /* ACE_HAS_ICMP_SUPPORT == 1 */

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6