PTLib
Version 2.10.4
|
00001 /* 00002 * ipsock.h 00003 * 00004 * Internet Protocol socket I/O channel class. 00005 * 00006 * Portable Tools Library 00007 * 00008 * Copyright (c) 1993-1998 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Portions are Copyright (C) 1993 Free Software Foundation, Inc. 00025 * All Rights Reserved. 00026 * 00027 * Contributor(s): ______________________________________. 00028 * 00029 * $Revision: 25231 $ 00030 * $Author: rjongbloed $ 00031 * $Date: 2011-03-02 08:41:46 -0600 (Wed, 02 Mar 2011) $ 00032 */ 00033 00034 #ifndef PTLIB_IPSOCKET_H 00035 #define PTLIB_IPSOCKET_H 00036 00037 #ifdef P_USE_PRAGMA 00038 #pragma interface 00039 #endif 00040 00041 #include <ptlib/socket.h> 00042 00043 #if P_QOS 00044 #ifdef _WIN32 00045 #ifdef P_KNOCKOUT_WINSOCK2 00046 #include "IPExport.h" 00047 #endif // KNOCKOUT_WINSOCK2 00048 #endif // _WIN32 00049 #endif // P_QOS 00050 00051 00052 class PIPSocketAddressAndPort; 00053 00054 00055 00063 class PIPSocket : public PSocket 00064 { 00065 PCLASSINFO(PIPSocket, PSocket); 00066 protected: 00070 PIPSocket(); 00071 00072 public: 00075 class Address : public PObject { 00076 public: 00077 00080 00081 Address(); 00082 00086 Address(const PString & dotNotation); 00087 00089 Address(PINDEX len, const BYTE * bytes); 00090 00092 Address(BYTE b1, BYTE b2, BYTE b3, BYTE b4); 00093 00095 Address(DWORD dw); 00096 00098 Address(const in_addr & addr); 00099 00100 #if P_HAS_IPV6 00101 00102 Address(const in6_addr & addr); 00103 #endif 00104 00107 Address(const int ai_family, const int ai_addrlen,struct sockaddr *ai_addr); 00108 00109 #ifdef __NUCLEUS_NET__ 00110 Address(const struct id_struct & addr); 00111 Address & operator=(const struct id_struct & addr); 00112 #endif 00113 00115 Address & operator=(const in_addr & addr); 00116 00117 #if P_HAS_IPV6 00118 00119 Address & operator=(const in6_addr & addr); 00120 #endif 00121 00123 Address & operator=(const PString & dotNotation); 00124 00126 Address & operator=(DWORD dw); 00128 00130 Comparison Compare(const PObject & obj) const; 00131 bool operator==(const Address & addr) const { return Compare(addr) == EqualTo; } 00132 bool operator!=(const Address & addr) const { return Compare(addr) != EqualTo; } 00133 #if P_HAS_IPV6 00134 bool operator==(in6_addr & addr) const; 00135 bool operator!=(in6_addr & addr) const { return !operator==(addr); } 00136 #endif 00137 bool operator==(in_addr & addr) const; 00138 bool operator!=(in_addr & addr) const { return !operator==(addr); } 00139 bool operator==(DWORD dw) const; 00140 bool operator!=(DWORD dw) const { return !operator==(dw); } 00141 #ifdef P_VXWORKS 00142 bool operator==(long unsigned int u) const { return operator==((DWORD)u); } 00143 bool operator!=(long unsigned int u) const { return !operator==((DWORD)u); } 00144 #endif 00145 #ifdef _WIN32 00146 bool operator==(unsigned u) const { return operator==((DWORD)u); } 00147 bool operator!=(unsigned u) const { return !operator==((DWORD)u); } 00148 #endif 00149 #ifdef P_RTEMS 00150 bool operator==(u_long u) const { return operator==((DWORD)u); } 00151 bool operator!=(u_long u) const { return !operator==((DWORD)u); } 00152 #endif 00153 #ifdef P_BEOS 00154 bool operator==(in_addr_t a) const { return operator==((DWORD)a); } 00155 bool operator!=(in_addr_t a) const { return !operator==((DWORD)a); } 00156 #endif 00157 bool operator==(int i) const { return operator==((DWORD)i); } 00158 bool operator!=(int i) const { return !operator==((DWORD)i); } 00159 00162 #if P_HAS_IPV6 00163 bool operator*=(const Address & addr) const; 00164 #else 00165 bool operator*=(const Address & addr) const { return operator==(addr); } 00166 #endif 00167 00169 PString AsString( 00170 bool bracketIPv6 = false 00171 ) const; 00172 00174 PBoolean FromString( 00175 const PString & str 00176 ); 00177 00179 operator PString() const; 00180 00182 operator in_addr() const; 00183 00184 #if P_HAS_IPV6 00185 00186 operator in6_addr() const; 00187 #endif 00188 00190 operator DWORD() const; 00191 00193 BYTE Byte1() const; 00194 00196 BYTE Byte2() const; 00197 00199 BYTE Byte3() const; 00200 00202 BYTE Byte4() const; 00203 00205 BYTE operator[](PINDEX idx) const; 00206 00208 PINDEX GetSize() const; 00209 00211 const char * GetPointer() const { return (const char *)&v; } 00212 00214 unsigned GetVersion() const { return version; } 00215 00217 PBoolean IsValid() const; 00218 PBoolean IsAny() const; 00219 00221 PBoolean IsLoopback() const; 00222 00224 PBoolean IsBroadcast() const; 00225 00227 PBoolean IsMulticast() const; 00228 00237 PBoolean IsRFC1918() const ; 00238 00239 #if P_HAS_IPV6 00240 00241 PBoolean IsV4Mapped() const; 00242 00244 PBoolean IsLinkLocal() const; 00245 #endif 00246 00247 static const Address & GetLoopback(int version = 4); 00248 static const Address & GetAny(int version = 4); 00249 static const Address GetBroadcast(int version = 4); 00250 00251 protected: 00253 union { 00254 in_addr four; 00255 #if P_HAS_IPV6 00256 in6_addr six; 00257 #endif 00258 } v; 00259 unsigned version; 00260 00262 friend ostream & operator<<(ostream & s, const Address & a); 00263 00265 friend istream & operator>>(istream & s, Address & a); 00266 }; 00267 00268 //**@name Overrides from class PChannel */ 00270 00277 virtual PString GetName() const; 00278 00285 static int GetDefaultIpAddressFamily(); 00286 static void SetDefaultIpAddressFamily(int ipAdressFamily); // PF_INET, PF_INET6 00287 static void SetDefaultIpAddressFamilyV4(); // PF_INET 00288 #if P_HAS_IPV6 00289 static void SetDefaultIpAddressFamilyV6(); // PF_INET6 00290 static PBoolean IsIpAddressFamilyV6Supported(); 00291 00292 static void SetDefaultV6ScopeId(int scopeId); // local-link adresses require one 00293 static int GetDefaultV6ScopeId(); 00294 #endif 00295 static PIPSocket::Address GetDefaultIpAny(); 00296 00299 virtual PBoolean OpenSocket( 00300 int ipAdressFamily=PF_INET 00301 ) = 0; 00303 00317 virtual PBoolean Connect( 00318 const PString & address 00319 ); 00320 virtual PBoolean Connect( 00321 const Address & addr 00322 ); 00323 virtual PBoolean Connect( 00324 WORD localPort, 00325 const Address & addr 00326 ); 00327 virtual PBoolean Connect( 00328 const Address & iface, 00329 const Address & addr 00330 ); 00331 virtual PBoolean Connect( 00332 const Address & iface, 00333 WORD localPort, 00334 const Address & addr 00335 ); 00336 00352 virtual PBoolean Listen( 00353 unsigned queueSize = 5, 00354 WORD port = 0, 00355 Reusability reuse = AddressIsExclusive 00356 ); 00357 virtual PBoolean Listen( 00358 const Address & bind, 00359 unsigned queueSize = 5, 00360 WORD port = 0, 00361 Reusability reuse = AddressIsExclusive 00362 ); 00364 00374 static PString GetHostName(); 00375 static PString GetHostName( 00376 const PString & hostname 00377 ); 00378 static PString GetHostName( 00379 const Address & addr 00380 ); 00381 00388 static PBoolean GetHostAddress( 00389 Address & addr 00390 ); 00391 static PBoolean GetHostAddress( 00392 const PString & hostname, 00396 Address & addr 00397 ); 00398 00406 static PStringArray GetHostAliases( 00410 const PString & hostname 00411 ); 00412 static PStringArray GetHostAliases( 00413 const Address & addr 00414 /* Name of host to get address for. This may be either a domain name or 00415 an IP number in "dot" format. 00416 */ 00417 ); 00418 00426 static PBoolean IsLocalHost( 00430 const PString & hostname 00431 ); 00432 00438 virtual PString GetLocalAddress(); 00439 virtual PBoolean GetLocalAddress( 00440 Address & addr 00441 ); 00442 virtual PBoolean GetLocalAddress( 00443 PIPSocketAddressAndPort & addr 00444 ); 00445 virtual PBoolean GetLocalAddress( 00446 Address & addr, 00447 WORD & port 00448 ); 00449 00456 virtual PString GetPeerAddress(); 00457 virtual PBoolean GetPeerAddress( 00458 Address & addr 00459 ); 00460 virtual PBoolean GetPeerAddress( 00461 PIPSocketAddressAndPort & addr 00462 ); 00463 virtual PBoolean GetPeerAddress( 00464 Address & addr, 00465 WORD & port 00466 ); 00467 00473 PString GetLocalHostName(); 00474 00480 PString GetPeerHostName(); 00481 00484 static void ClearNameCache(); 00485 00497 static PBoolean GetGatewayAddress( 00498 Address & addr, 00499 int version = 4 00500 ); 00501 00513 static PString GetGatewayInterface(int version = 4); 00514 00522 static PIPSocket::Address GetRouteInterfaceAddress(PIPSocket::Address remoteAddress); 00523 00524 #ifdef _WIN32 00525 00536 static PIPSocket::Address GetGatewayInterfaceAddress(int version = 4); 00537 00541 static PIPSocket::Address GetRouteAddress(PIPSocket::Address RemoteAddress); 00542 00545 static unsigned AsNumeric(Address addr); 00546 00549 static PBoolean IsAddressReachable(PIPSocket::Address LocalIP, 00550 PIPSocket::Address LocalMask, 00551 PIPSocket::Address RemoteIP); 00552 00555 static PString GetInterface(PIPSocket::Address addr); 00557 #endif 00558 00560 class RouteEntry : public PObject 00561 { 00562 PCLASSINFO(RouteEntry, PObject); 00563 public: 00565 RouteEntry(const Address & addr) : network(addr) { } 00566 00568 Address GetNetwork() const { return network; } 00569 00571 Address GetNetMask() const { return net_mask; } 00572 00574 Address GetDestination() const { return destination; } 00575 00577 const PString & GetInterface() const { return interfaceName; } 00578 00580 long GetMetric() const { return metric; } 00581 00582 protected: 00583 Address network; 00584 Address net_mask; 00585 Address destination; 00586 PString interfaceName; 00587 long metric; 00588 00589 friend class PIPSocket; 00590 }; 00591 00592 PARRAY(RouteTable, RouteEntry); 00593 00599 static PBoolean GetRouteTable( 00600 RouteTable & table 00601 ); 00602 00604 class RouteTableDetector 00605 { 00606 public: 00607 virtual ~RouteTableDetector() { } 00608 virtual bool Wait( 00609 const PTimeInterval & timeout 00610 ) = 0; 00611 virtual void Cancel() = 0; 00612 }; 00613 00622 static RouteTableDetector * CreateRouteTableDetector(); 00623 00626 class InterfaceEntry : public PObject 00627 { 00628 PCLASSINFO(InterfaceEntry, PObject) 00629 00630 public: 00632 InterfaceEntry(); 00633 InterfaceEntry( 00634 const PString & name, 00635 const Address & addr, 00636 const Address & mask, 00637 const PString & macAddr 00638 ); 00639 00641 virtual void PrintOn( 00642 ostream &strm // Stream to print the object into. 00643 ) const; 00644 00646 const PString & GetName() const { return name; } 00647 00649 Address GetAddress() const { return ipAddr; } 00650 00652 Address GetNetMask() const { return netMask; } 00653 00655 const PString & GetMACAddress() const { return macAddr; } 00656 00657 protected: 00658 PString name; 00659 Address ipAddr; 00660 Address netMask; 00661 PString macAddr; 00662 00663 friend class PIPSocket; 00664 }; 00665 00666 PARRAY(InterfaceTable, InterfaceEntry); 00667 00672 static PBoolean GetInterfaceTable( 00673 InterfaceTable & table, 00674 PBoolean includeDown = false 00675 ); 00676 00681 static PBoolean GetNetworkInterface(PIPSocket::Address & addr); 00682 00683 #if P_HAS_RECVMSG 00684 00689 PBoolean SetCaptureReceiveToAddress() 00690 { if (!SetOption(IP_PKTINFO, 1, SOL_IP)) return false; catchReceiveToAddr = true; return true; } 00691 00694 PIPSocket::Address GetLastReceiveToAddress() const 00695 { return lastReceiveToAddr; } 00696 00697 protected: 00698 void SetLastReceiveAddr(void * addr, int addrLen) 00699 { if (addrLen == sizeof(in_addr)) lastReceiveToAddr = *(in_addr *)addr; } 00700 00701 PIPSocket::Address lastReceiveToAddr; 00702 00703 #else 00704 00709 PBoolean SetCaptureReceiveToAddress() 00710 { return false; } 00711 00714 PIPSocket::Address GetLastReceiveToAddress() const 00715 { return PIPSocket::Address(); } 00716 00717 #endif 00718 00719 // Include platform dependent part of class 00720 #ifdef _WIN32 00721 #include "msos/ptlib/ipsock.h" 00722 #else 00723 #include "unix/ptlib/ipsock.h" 00724 #endif 00725 }; 00726 00727 class PIPSocketAddressAndPort 00728 { 00729 public: 00730 PIPSocketAddressAndPort() 00731 : m_port(0), m_separator(':') 00732 { } 00733 00734 PIPSocketAddressAndPort(char separator) 00735 : m_port(0), m_separator(separator) 00736 { } 00737 00738 PIPSocketAddressAndPort(const PString & str, WORD defaultPort = 0, char separator = ':') 00739 : m_port(defaultPort), m_separator(separator) 00740 { Parse(str, defaultPort, m_separator); } 00741 00742 PBoolean Parse(const PString & str, WORD defaultPort = 0, char separator = ':'); 00743 00744 PString AsString(char separator = 0) const 00745 { return m_address.AsString() + (separator ? separator : m_separator) + PString(PString::Unsigned, m_port); } 00746 00747 void SetAddress( 00748 const PIPSocket::Address & addr, 00749 WORD port = 0 00750 ); 00751 const PIPSocket::Address & GetAddress() const { return m_address; } 00752 WORD GetPort() const { return m_port; } 00753 void SetPort( 00754 WORD port 00755 ) { m_port = port; } 00756 00757 bool IsValid() const { return m_address.IsValid() && m_port != 0; } 00758 00759 friend ostream & operator<<(ostream & strm, const PIPSocketAddressAndPort & ap) 00760 { 00761 return strm << ap.m_address << ap.m_separator << ap.m_port; 00762 } 00763 00764 protected: 00765 PIPSocket::Address m_address; 00766 WORD m_port; 00767 char m_separator; 00768 }; 00769 00770 typedef std::vector<PIPSocketAddressAndPort> PIPSocketAddressAndPortVector; 00771 00772 00773 #endif // PTLIB_IPSOCKET_H 00774 00775 00776 // End Of File ///////////////////////////////////////////////////////////////