ipsock.h

Go to the documentation of this file.
00001 /*
00002  * ipsock.h
00003  *
00004  * Internet Protocol socket I/O channel class.
00005  *
00006  * Portable Windows 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: 21467 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-11-07 02:15:07 +0000 (Fri, 07 Nov 2008) $
00032  */
00033 
00034 #ifndef _PIPSOCKET
00035 #define _PIPSOCKET
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 
00058 class PIPSocket : public PSocket
00059 {
00060   PCLASSINFO(PIPSocket, PSocket);
00061   protected:
00062     /* Create a new Internet Protocol socket based on the port number
00063        specified.
00064      */
00065     PIPSocket();
00066 
00067   public:
00071     class Address : public PObject {
00072       public:
00073 
00076 
00077         Address();
00078 
00082         Address(const PString & dotNotation);
00083 
00085         Address(PINDEX len, const BYTE * bytes);
00086 
00088         Address(BYTE b1, BYTE b2, BYTE b3, BYTE b4);
00089 
00091         Address(DWORD dw);
00092 
00094         Address(const in_addr & addr);
00095 
00096 #if P_HAS_IPV6
00098         Address(const in6_addr & addr);
00099 #endif
00100 
00103         Address(const int ai_family, const int ai_addrlen,struct sockaddr *ai_addr);
00104 
00105 #ifdef __NUCLEUS_NET__
00106         Address(const struct id_struct & addr);
00107         Address & operator=(const struct id_struct & addr);
00108 #endif
00109 
00111         Address & operator=(const in_addr & addr);
00112 
00113 #if P_HAS_IPV6
00115         Address & operator=(const in6_addr & addr);
00116 #endif
00117 
00119         Address & operator=(const PString & dotNotation);
00120 
00122         Address & operator=(DWORD dw);
00124 
00126         Comparison Compare(const PObject & obj) const;
00127         bool operator==(const Address & addr) const { return Compare(addr) == EqualTo; }
00128         bool operator!=(const Address & addr) const { return Compare(addr) != EqualTo; }
00129 #if P_HAS_IPV6
00130         bool operator==(in6_addr & addr) const;
00131         bool operator!=(in6_addr & addr) const { return !operator==(addr); }
00132 #endif
00133         bool operator==(in_addr & addr) const;
00134         bool operator!=(in_addr & addr) const { return !operator==(addr); }
00135         bool operator==(DWORD dw) const;
00136         bool operator!=(DWORD dw) const   { return !operator==(dw); }
00137 #ifdef P_VXWORKS 
00138         bool operator==(long unsigned int u) const { return  operator==((DWORD)u); }
00139         bool operator!=(long unsigned int u) const { return !operator==((DWORD)u); }
00140 #endif
00141 #ifdef _WIN32
00142         bool operator==(unsigned u) const { return  operator==((DWORD)u); }
00143         bool operator!=(unsigned u) const { return !operator==((DWORD)u); }
00144 #endif
00145 #ifdef P_RTEMS
00146         bool operator==(u_long u) const { return  operator==((DWORD)u); }
00147         bool operator!=(u_long u) const { return !operator==((DWORD)u); }
00148 #endif
00149 #ifdef P_BEOS
00150         bool operator==(in_addr_t a) const { return  operator==((DWORD)a); }
00151         bool operator!=(in_addr_t a) const { return !operator==((DWORD)a); }
00152 #endif
00153         bool operator==(int i) const      { return  operator==((DWORD)i); }
00154         bool operator!=(int i) const      { return !operator==((DWORD)i); }
00155 
00158 #if P_HAS_IPV6
00159         bool operator*=(const Address & addr) const;
00160 #else
00161         bool operator*=(const Address & addr) const { return operator==(addr); }
00162 #endif
00163 
00165         PString AsString() const;
00166 
00168         PBoolean FromString(
00169           const PString & str
00170         );
00171 
00173         operator PString() const;
00174 
00176         operator in_addr() const;
00177 
00178 #if P_HAS_IPV6
00180         operator in6_addr() const;
00181 #endif
00182 
00184         operator DWORD() const;
00185 
00187         BYTE Byte1() const;
00188 
00190         BYTE Byte2() const;
00191 
00193         BYTE Byte3() const;
00194 
00196         BYTE Byte4() const;
00197 
00199         BYTE operator[](PINDEX idx) const;
00200 
00202         PINDEX GetSize() const;
00203 
00205         const char * GetPointer() const { return (const char *)&v; }
00206 
00208         unsigned GetVersion() const { return version; }
00209 
00211         PBoolean IsValid() const;
00212         PBoolean IsAny() const;
00213 
00215         PBoolean IsLoopback() const;
00216 
00218         PBoolean IsBroadcast() const;
00219 
00220         // Check if the remote address is a private address.
00221         // For IPV4 this is specified RFC 1918 as the following ranges:
00222         //    10.0.0.0    - 10.255.255.255.255
00223         //    172.16.0.0  - 172.31.255.255
00224         //    192.168.0.0 - 192.168.255.255
00225         // For IPV6 this is specified as any address having "1111 1110 1” for the first nine bits
00226         PBoolean IsRFC1918() const ;
00227 
00228 #if P_HAS_IPV6
00230         PBoolean IsV4Mapped() const;
00231 #endif
00232         
00233         static const Address & GetLoopback();
00234 #if P_HAS_IPV6
00235         static const Address & GetLoopback6();
00236         static const Address & GetAny6();
00237 #endif
00238         static const Address & GetBroadcast();
00239 
00240       protected:
00242         union {
00243           in_addr four;
00244 #if P_HAS_IPV6
00245           in6_addr six;
00246 #endif
00247         } v;
00248         unsigned version;
00249 
00251       friend ostream & operator<<(ostream & s, const Address & a);
00252 
00254       friend istream & operator>>(istream & s, Address & a);
00255     };
00256 
00257   // Overrides from class PChannel
00265     virtual PString GetName() const;
00266 
00267     // Set the default IP address familly.
00268     // Needed as lot of IPv6 stack are not able to receive IPv4 packets in IPv6 sockets
00269     // They are not RFC 2553, chapter 7.3, compliant.
00270     // As a concequence, when opening a socket to listen to port 1720 (for exemple) from any remot host
00271     // one must decide whether this an IPv4 or an IPv6 socket...
00272     static int GetDefaultIpAddressFamily();
00273     static void SetDefaultIpAddressFamily(int ipAdressFamily); // PF_INET, PF_INET6
00274     static void SetDefaultIpAddressFamilyV4(); // PF_INET
00275 #if P_HAS_IPV6
00276     static void SetDefaultIpAddressFamilyV6(); // PF_INET6
00277     static PBoolean IsIpAddressFamilyV6Supported();
00278 #endif
00279     static PIPSocket::Address GetDefaultIpAny();
00280 
00281     // Open an IPv4 or IPv6 socket
00282     virtual PBoolean OpenSocket(
00283       int ipAdressFamily=PF_INET
00284     ) = 0;
00285 
00286 
00287   // Overrides from class PSocket.
00299     virtual PBoolean Connect(
00300       const PString & address   
00301     );
00302     virtual PBoolean Connect(
00303       const Address & addr      
00304     );
00305     virtual PBoolean Connect(
00306       WORD localPort,           
00307       const Address & addr      
00308     );
00309     virtual PBoolean Connect(
00310       const Address & iface,    
00311       const Address & addr      
00312     );
00313     virtual PBoolean Connect(
00314       const Address & iface,    
00315       WORD localPort,           
00316       const Address & addr      
00317     );
00318 
00334     virtual PBoolean Listen(
00335       unsigned queueSize = 5,  
00336       WORD port = 0,           
00337       Reusability reuse = AddressIsExclusive 
00338     );
00339     virtual PBoolean Listen(
00340       const Address & bind,     
00341       unsigned queueSize = 5,   
00342       WORD port = 0,            
00343       Reusability reuse = AddressIsExclusive 
00344     );
00345 
00346 
00347   // New functions for class
00355     static PString GetHostName();
00356     static PString GetHostName(
00357       const PString & hostname  
00358     );
00359     static PString GetHostName(
00360       const Address & addr    
00361     );
00362 
00369     static PBoolean GetHostAddress(
00370       Address & addr    
00371     );
00372     static PBoolean GetHostAddress(
00373       const PString & hostname,
00374       /* Name of host to get address for. This may be either a domain name or
00375          an IP number in "dot" format.
00376        */
00377       Address & addr    
00378     );
00379 
00387     static PStringArray GetHostAliases(
00388       const PString & hostname
00389       /* Name of host to get address for. This may be either a domain name or
00390          an IP number in "dot" format.
00391        */
00392     );
00393     static PStringArray GetHostAliases(
00394       const Address & addr    
00395       /* Name of host to get address for. This may be either a domain name or
00396          an IP number in "dot" format.
00397        */
00398     );
00399 
00407     static PBoolean IsLocalHost(
00408       const PString & hostname
00409       /* Name of host to get address for. This may be either a domain name or
00410          an IP number in "dot" format.
00411        */
00412     );
00413 
00419     virtual PString GetLocalAddress();
00420     virtual PBoolean GetLocalAddress(
00421       Address & addr    
00422     );
00423     virtual PBoolean GetLocalAddress(
00424       Address & addr,    
00425       WORD & port        
00426     );
00427 
00434     virtual PString GetPeerAddress();
00435     virtual PBoolean GetPeerAddress(
00436       Address & addr    
00437     );
00438     virtual PBoolean GetPeerAddress(
00439       Address & addr,    
00440       WORD & port        
00441     );
00442 
00448     PString GetLocalHostName();
00449 
00455     PString GetPeerHostName();
00456 
00459     static void ClearNameCache();
00460 
00472     static PBoolean GetGatewayAddress(
00473       Address & addr     
00474     );
00475 
00488     static PString GetGatewayInterface();
00489 
00497     static PIPSocket::Address GetRouteInterfaceAddress(PIPSocket::Address remoteAddress);
00498 
00499 #ifdef _WIN32
00500 
00511     static PIPSocket::Address GetGatewayInterfaceAddress();
00512 
00516     static PIPSocket::Address GetRouteAddress(PIPSocket::Address RemoteAddress);
00517 
00520     static unsigned AsNumeric(Address addr);
00521 
00524     static PBoolean IsAddressReachable(PIPSocket::Address LocalIP,
00525                                    PIPSocket::Address LocalMask, 
00526                                    PIPSocket::Address RemoteIP);
00527 
00530     static PString GetInterface(PIPSocket::Address addr);
00531  #endif
00532 
00535     class RouteEntry : public PObject
00536     {
00537       PCLASSINFO(RouteEntry, PObject);
00538       public:
00540         RouteEntry(const Address & addr) : network(addr) { }
00541 
00543         Address GetNetwork() const { return network; }
00544 
00546         Address GetNetMask() const { return net_mask; }
00547 
00549         Address GetDestination() const { return destination; }
00550 
00552         const PString & GetInterface() const { return interfaceName; }
00553 
00555         long GetMetric() const { return metric; }
00556 
00557       protected:
00558         Address network;
00559         Address net_mask;
00560         Address destination;
00561         PString interfaceName;
00562         long    metric;
00563 
00564       friend class PIPSocket;
00565     };
00566 
00567     PARRAY(RouteTable, RouteEntry);
00568 
00574     static PBoolean GetRouteTable(
00575       RouteTable & table      
00576     );
00577 
00582     static bool WaitForRouteTableChange(
00583       const PTimeInterval & timeout,    
00584       PSyncPoint * cancellation = NULL  
00585     );
00586 
00590     class InterfaceEntry : public PObject
00591     {
00592       PCLASSINFO(InterfaceEntry, PObject)
00593 
00594       public:
00596         InterfaceEntry();
00597         InterfaceEntry(
00598           const PString & _name,
00599           const Address & _addr,
00600           const Address & _mask,
00601           const PString & _macAddr
00602 #if P_HAS_IPV6
00603           , const PString & _ip6Addr = PString::Empty()
00604 #endif
00605         );
00606 
00608         virtual void PrintOn(
00609           ostream &strm   // Stream to print the object into.
00610         ) const;
00611 
00613         const PString & GetName() const { return name; }
00614 
00616         Address GetAddress() const { return ipAddr; }
00617 
00618         PBoolean HasIP6Address() const
00619 #if ! P_HAS_IPV6
00620         { return PFalse;}
00621 #else
00622         { return !ip6Addr.IsEmpty();}
00623 
00625         Address GetIP6Address() const { return ip6Addr; }
00626 #endif
00627 
00629         Address GetNetMask() const { return netMask; }
00630 
00632         const PString & GetMACAddress() const { return macAddr; }
00633 
00634       protected:
00635         PString name;
00636         Address ipAddr;
00637         Address netMask;
00638         PString macAddr;
00639 #if P_HAS_IPV6
00640         PString ip6Addr;
00641 #endif
00642     };
00643 
00644     PARRAY(InterfaceTable, InterfaceEntry);
00645 
00650     static PBoolean GetInterfaceTable(
00651       InterfaceTable & table,      
00652       PBoolean includeDown = PFalse     
00653     );
00654 
00659     static PBoolean GetNetworkInterface(PIPSocket::Address & addr);
00660 
00661 #if P_HAS_RECVMSG
00662 
00668     PBoolean SetCaptureReceiveToAddress()
00669     { if (!SetOption(IP_PKTINFO, 1, SOL_IP)) return PFalse; catchReceiveToAddr = PTrue; return PTrue; }
00670 
00674     PIPSocket::Address GetLastReceiveToAddress() const
00675     { return lastReceiveToAddr; }
00676 
00677   protected:
00678     void SetLastReceiveAddr(void * addr, int addrLen)
00679     { if (addrLen == sizeof(in_addr)) lastReceiveToAddr = *(in_addr *)addr; }
00680 
00681     PIPSocket::Address lastReceiveToAddr;
00682 
00683 #else
00684 
00690     PBoolean SetCaptureReceiveToAddress()
00691     { return PFalse; }
00692 
00696     PIPSocket::Address GetLastReceiveToAddress() const
00697     { return PIPSocket::Address(); }
00698 
00699 #endif
00700 
00701 // Include platform dependent part of class
00702 #ifdef _WIN32
00703 #include "msos/ptlib/ipsock.h"
00704 #else
00705 #include "unix/ptlib/ipsock.h"
00706 #endif
00707 };
00708 
00709 class PIPSocketAddressAndPort
00710 {
00711   public:
00712     PIPSocketAddressAndPort()
00713       : port(0), sep(':')
00714     { }
00715 
00716     PIPSocketAddressAndPort(char _sep)
00717       : port(0), sep(_sep)
00718     { }
00719 
00720     PIPSocketAddressAndPort(const PString & str, WORD defaultPort = 0, char _sep = ':')
00721       : port(defaultPort), sep(_sep)
00722     { Parse(str, defaultPort, sep); }
00723 
00724     PBoolean Parse(const PString & str, WORD defaultPort = 0, char sep = ':');
00725 
00726     PString AsString(char _sep = 0) const
00727     { return address.AsString() + (_sep ? _sep : sep) + PString(PString::Unsigned, port); }
00728 
00729     PIPSocket::Address address;
00730     WORD port;
00731     char sep;
00732 };
00733 
00734 typedef std::vector<PIPSocketAddressAndPort> PIPSocketAddressAndPortVector;
00735 
00736 #endif
00737 
00738 
00739 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Feb 23 01:57:54 2009 for PTLib by  doxygen 1.5.1