IPAddress.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const IPAddress_cxx_Version = 
  51.     "$Id: IPAddress.cxx,v 1.30 2001/04/11 19:55:02 icahoon Exp $";
  52. #include "IPAddress.hxx"
  53. #include "TransportCommon.hxx"
  54. #include "SystemException.hxx"
  55. #include "Socket.hxx"
  56. #include "VLog.hxx"
  57. #include <cstring>
  58. #include <cctype>
  59. #include <cstdlib>
  60. #include <cstdio>
  61. #include <cerrno>
  62. #include <arpa/inet.h>
  63. #include <sys/socket.h>
  64. #include <strstream>
  65. using Vocal::Transport::IPAddress;
  66. using Vocal::Transport::TransportAddress;
  67. using Vocal::Transport::Socket;
  68. using Vocal::Logging::VLog;
  69. IPAddress::IPAddress(u_int16_t port)
  70.     :   separationChar_(':')
  71. {
  72.     setAddressFamily(AF_INET);
  73.     inAddr_.sin_port       = htons(port);
  74.     inAddr_.sin_addr.s_addr = htonl(INADDR_ANY);
  75. }
  76. IPAddress::IPAddress(
  77.     const char      *   ip,
  78.     u_int16_t           port
  79. )   
  80.     :   separationChar_(':')
  81. {
  82.     setAddressFamily(AF_INET);
  83.     inAddr_.sin_port = htons(port);
  84.     setIP(ip);
  85. }
  86. IPAddress::IPAddress(
  87.     const u_int8_t  *   ip,
  88.     u_int16_t           port
  89. )
  90.     :   separationChar_(':')
  91. {
  92.     setAddressFamily(AF_INET);
  93.     inAddr_.sin_port = htons(port);
  94.     setIP(ip);
  95. }
  96. IPAddress::IPAddress(
  97.     u_int32_t          ip,
  98.     u_int16_t           port
  99. )
  100.     :   separationChar_(':')
  101. {
  102.     setAddressFamily(AF_INET);
  103.     inAddr_.sin_port       = htons(port);
  104.     inAddr_.sin_addr.s_addr = htonl(ip);
  105. }
  106. IPAddress::IPAddress(const sockaddr_in &   inAddr)
  107.     : inAddr_(inAddr),
  108.         separationChar_(':')
  109. {
  110.     setAddressFamily(AF_INET);
  111. }
  112. IPAddress::IPAddress(const IPAddress & src)
  113.     : inAddr_(src.inAddr_),
  114.         separationChar_(src.separationChar_)
  115. {
  116.     setAddressFamily(AF_INET);
  117. }
  118.     
  119. IPAddress::~IPAddress()
  120. {
  121. }
  122. IPAddress &
  123. IPAddress::operator=(const IPAddress & src)
  124. {
  125.     if ( this != &src )
  126.     {
  127.      setIPAddress(src.inAddr_);
  128.     }
  129.     return ( *this );
  130. }
  131. TransportAddress *
  132. IPAddress::clone() const
  133. {
  134.     return ( new IPAddress(*this) );
  135. }
  136. void               
  137. IPAddress::setAddress(sockaddr * addr)
  138. {
  139.     if ( addr->sa_family != AF_INET )
  140.     {
  141.      VLog log;
  142. VWARN(log)  << "IPAddress::setAddress: incorrect address family = "
  143.          << addr->sa_family << VWARN_END(log);
  144.      return;
  145.     }
  146.     inAddr_ = *reinterpret_cast<sockaddr_in *>(addr);
  147. }
  148. void          
  149. IPAddress::setIPAddress(const sockaddr_in & src)
  150. {
  151.     inAddr_ = src;
  152.     setAddressFamily(AF_INET);
  153. }
  154. void          
  155. IPAddress::setIP(const char * ip)
  156. {
  157.     if ( !ip )
  158.     {
  159.         inAddr_.sin_addr.s_addr = htonl(INADDR_ANY);
  160. return;
  161.     }
  162.     // Copy it, since we need to modify it.
  163.     //    
  164.     size_t  length = strlen(ip);
  165.     char *  ipCopy = new char[length+1];
  166.     strcpy(ipCopy, ip);
  167.         
  168.     // See if we have a string in the format a.b.c.d:port. We will search 
  169.     // until we find a separator character, being a member of the character
  170.     // set " t:;,/\". We will then replace that with a 0 and then
  171.     // search for the first digit.
  172.     //
  173.     string        searchString(ip);
  174.     string::size_type  pos = searchString.find_first_of(" t:;,/\");
  175.     bool foundPortSeparator = false;
  176.         
  177.     if ( pos != string::npos )
  178.     {
  179.         separationChar_ = searchString[pos];
  180.         
  181.         foundPortSeparator = true;
  182.         
  183.      // Null terminate the dotted decimal.
  184. //
  185. ipCopy[pos] = '';
  186. char * position = &ipCopy[pos+1];
  187. // Advance until we find the end or we find a digit.
  188. //
  189. while ( *position && !isdigit(*position) )
  190. {
  191.     position++;
  192. }
  193.      // See if we have a number.
  194. //
  195. if ( *position )
  196. {
  197.     char * endPtr = 0;
  198.     u_int16_t newPort = (u_int16_t)strtoul(position, &endPtr, 10);
  199.     if ( endPtr != position )
  200.     {
  201.           inAddr_.sin_port = htons(newPort);
  202.     }
  203. }
  204.     }
  205.     searchString = ipCopy;
  206.     pos = searchString.find_first_of(".");
  207.     // We have dotted decimal
  208.     //
  209.     if ( foundPortSeparator || pos != string::npos )
  210.     {
  211.         #if defined(__linux__)
  212.         if ( !inet_aton(ipCopy, &inAddr_.sin_addr) )
  213.         #else
  214.         if ( (inAddr_.sin_addr.s_addr = inet_addr(ipCopy)) != (in_addr_t)-1 )
  215.         #endif
  216.         {
  217.             inAddr_.sin_addr.s_addr = htonl(INADDR_ANY);
  218.         }
  219.     }
  220.     
  221.     // No dot. Assume it's a port.
  222.     //
  223.     else
  224.     {
  225.         char * endPtr = 0;
  226. u_int16_t newPort = (u_int16_t)strtoul(ipCopy, &endPtr, 10);
  227.         inAddr_.sin_addr.s_addr = htonl(INADDR_ANY);
  228.         inAddr_.sin_port = htons(newPort);
  229.     }
  230.     
  231.     delete [] ipCopy;
  232. }
  233. void          
  234. IPAddress::setIP(const u_int8_t * ip)
  235. {
  236.     // We have a 4 byte array that better be in network order.
  237.     //
  238.     if ( ip )
  239.     {
  240.         memcpy(&inAddr_.sin_addr.s_addr, ip, 4);
  241.     }
  242.     else
  243.     {
  244.      inAddr_.sin_addr.s_addr = htonl(INADDR_ANY);
  245.     }
  246. }
  247. void          
  248. IPAddress::setIP(u_int32_t ip)
  249. {
  250.     inAddr_.sin_addr.s_addr = htonl(ip);
  251. }
  252. void          
  253. IPAddress::setPort(u_int16_t port)
  254. {
  255.     inAddr_.sin_port = htons(port);
  256. }
  257. string          
  258. IPAddress::getIPAsString() const
  259. {
  260.     char    buffer[18];
  261.     string  ipAsString(inetNtoa(inAddr_.sin_addr, buffer));
  262.     return ( ipAsString );
  263. }
  264. void 
  265. IPAddress::getIPAsOctetString(u_int8_t* dst) const
  266. {
  267.     memcpy(dst, &inAddr_.sin_addr.s_addr, 4);
  268. }
  269. u_int32_t 
  270. IPAddress::getIPAsULong() const
  271. {
  272.     return ntohl(inAddr_.sin_addr.s_addr);
  273. }
  274. sockaddr *       
  275. IPAddress::getAddress() const
  276. {
  277.     return ( reinterpret_cast<sockaddr *>(&inAddr_) );
  278. }
  279. const sockaddr_in &     
  280. IPAddress::getIPAddress() const
  281. {
  282.     return ( inAddr_ );
  283. }
  284. socklen_t
  285. IPAddress::getAddressLength() const
  286. {
  287.     return ( sizeof(inAddr_) );
  288. }
  289. string          
  290. IPAddress::getIPAndPortAsString() const
  291. {
  292.     char     buf[32];
  293.     strstream addr(buf, 31);
  294.     addr << *this << ends;
  295.     string   ipAndPort(addr.str());
  296.     
  297.     return ( ipAndPort );
  298. }
  299. u_int16_t        
  300. IPAddress::getPort() const
  301. {
  302.     return ( ntohs(inAddr_.sin_port) );
  303. }
  304. void          
  305. IPAddress::updateAddress(const Socket & sock) 
  306. throw ( Vocal::SystemException )
  307. {
  308.     const string    fn = "IPAddress::updateAddress";
  309.     VLog         log(fn);
  310.     sockaddr_in     newAddress;
  311.     socklen_t     newAddressLength = sizeof(newAddress);
  312.     
  313.     if (   getsockname(sock.getFD(), 
  314.                (sockaddr *)&newAddress, 
  315.           &newAddressLength) 
  316.     < SUCCESS
  317. )
  318.     {
  319.      throw Vocal::SystemException(fn + " on getsockname(): " + strerror(errno), 
  320.                __FILE__, __LINE__, errno);
  321.     }
  322.     setIPAddress(newAddress);
  323.     
  324.     VVERBOSE(log)   << (fn + ": ")  << *this 
  325.               << ", from: "   << sock
  326.               << VVERBOSE_END(log);
  327. }
  328. bool          
  329. IPAddress::operator==(const IPAddress & rhs) const
  330. {
  331.     return 
  332.     (  this == &rhs
  333.     || (   getAddressFamily()      == rhs.getAddressFamily()
  334.      &&  inAddr_.sin_addr.s_addr == rhs.inAddr_.sin_addr.s_addr
  335.         &&  inAddr_.sin_port      == rhs.inAddr_.sin_port
  336. )
  337.     );
  338. }
  339. bool          
  340. IPAddress::operator!=(const IPAddress & rhs) const
  341. {
  342.     return ( !operator==(rhs) );
  343. }
  344. bool          
  345. IPAddress::operator<(const IPAddress & rhs) const
  346. {
  347.     u_int32_t  leftIp  = ntohl(inAddr_.sin_addr.s_addr),
  348.           rightIp = ntohl(rhs.inAddr_.sin_addr.s_addr);
  349.     u_int16_t  leftPort  = ntohs(inAddr_.sin_port),
  350.           rightPort = ntohs(rhs.inAddr_.sin_port);
  351.     return 
  352.     (  this != &rhs
  353.     && (   getAddressFamily() < rhs.getAddressFamily()
  354.      ||  leftIp < rightIp
  355.      ||  leftPort < rightPort
  356. )
  357.     );
  358. }
  359. bool          
  360. IPAddress::operator<=(const IPAddress & rhs) const
  361. {
  362.     return
  363.     ( operator==(rhs)
  364.     && operator<(rhs)
  365.     );
  366. }
  367. bool          
  368. IPAddress::operator>(const IPAddress & rhs) const
  369. {
  370.     return ( !operator<=(rhs) );
  371. }
  372. bool          
  373. IPAddress::operator>=(const IPAddress & rhs) const
  374. {
  375.     return ( !operator<(rhs) );
  376. }
  377. bool          
  378. IPAddress::isAny() const
  379. {
  380.     return ( *this == IPAddress() );
  381. }
  382. ostream &     
  383. IPAddress::writeTo(ostream & out) const
  384. {
  385.     return 
  386.     (
  387.      out << getIPAsString() << separationChar_ << getPort()
  388.     );
  389. }
  390. char *          
  391. IPAddress::inetNtoa(const struct in_addr & in, char * buffer) const
  392. {
  393.     u_int8_t * bytes = (u_int8_t *) &in;
  394.     snprintf(buffer, 18, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
  395.     return ( buffer );
  396. }