# 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 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: 28179 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2012-08-10 06:23:27 -0500 (Fri, 10 Aug 2012) $
    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
    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
    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
    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
    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
    00303     static void SetSuppressCanonicalName(bool suppress);
    00304
    00311     static bool GetSuppressCanonicalName();
    00312
    00315     virtual PBoolean OpenSocket(
    00316       int ipAdressFamily=PF_INET
    00317     ) = 0;
    00319
    00333     virtual PBoolean Connect(
    00334       const PString & address
    00335     );
    00336     virtual PBoolean Connect(
    00337       const Address & addr
    00338     );
    00339     virtual PBoolean Connect(
    00340       WORD localPort,
    00341       const Address & addr
    00342     );
    00343     virtual PBoolean Connect(
    00344       const Address & iface,
    00345       const Address & addr
    00346     );
    00347     virtual PBoolean Connect(
    00348       const Address & iface,
    00349       WORD localPort,
    00350       const Address & addr
    00351     );
    00352
    00368     virtual PBoolean Listen(
    00369       unsigned queueSize = 5,
    00370       WORD port = 0,
    00371       Reusability reuse = AddressIsExclusive
    00372     );
    00373     virtual PBoolean Listen(
    00374       const Address & bind,
    00375       unsigned queueSize = 5,
    00376       WORD port = 0,
    00377       Reusability reuse = AddressIsExclusive
    00378     );
    00380
    00390     static PString GetHostName();
    00391     static PString GetHostName(
    00392       const PString & hostname
    00393     );
    00394     static PString GetHostName(
    00395       const Address & addr
    00396     );
    00397
    00404     static PBoolean GetHostAddress(
    00405       Address & addr
    00406     );
    00407     static PBoolean GetHostAddress(
    00408       const PString & hostname,
    00412       Address & addr
    00413     );
    00414
    00422     static PStringArray GetHostAliases(
    00426       const PString & hostname
    00427     );
    00428     static PStringArray GetHostAliases(
    00429       const Address & addr
    00430       /* Name of host to get address for. This may be either a domain name or
    00431          an IP number in "dot" format.
    00432        */
    00433     );
    00434
    00442     static PBoolean IsLocalHost(
    00446       const PString & hostname
    00447     );
    00448
    00454     virtual PString GetLocalAddress();
    00455     virtual PBoolean GetLocalAddress(
    00456       Address & addr
    00457     );
    00458     virtual PBoolean GetLocalAddress(
    00459       PIPSocketAddressAndPort & addr
    00460     );
    00461     virtual PBoolean GetLocalAddress(
    00462       Address & addr,
    00463       WORD & port
    00464     );
    00465
    00472     virtual PString GetPeerAddress();
    00473     virtual PBoolean GetPeerAddress(
    00474       Address & addr
    00475     );
    00476     virtual PBoolean GetPeerAddress(
    00477       PIPSocketAddressAndPort & addr
    00478     );
    00479     virtual PBoolean GetPeerAddress(
    00480       Address & addr,
    00481       WORD & port
    00482     );
    00483
    00489     PString GetLocalHostName();
    00490
    00496     PString GetPeerHostName();
    00497
    00500     static void ClearNameCache();
    00501
    00513     static PBoolean GetGatewayAddress(
    00514       Address & addr,
    00515           int version = 4
    00516     );
    00517
    00529     static PString GetGatewayInterface(int version = 4);
    00530
    00538     static PIPSocket::Address GetRouteInterfaceAddress(PIPSocket::Address remoteAddress);
    00539
    00540 #ifdef _WIN32
    00541
    00552     static PIPSocket::Address GetGatewayInterfaceAddress(int version = 4);
    00553
    00557     static PIPSocket::Address GetRouteAddress(PIPSocket::Address RemoteAddress);
    00558
    00561     static unsigned AsNumeric(Address addr);
    00562
    00565     static PBoolean IsAddressReachable(PIPSocket::Address LocalIP,
    00566                                    PIPSocket::Address LocalMask,
    00567                                    PIPSocket::Address RemoteIP);
    00568
    00571     static PString GetInterface(PIPSocket::Address addr);
    00573  #endif
    00574
    00576     class RouteEntry : public PObject
    00577     {
    00578       PCLASSINFO(RouteEntry, PObject);
    00579       public:
    00581         RouteEntry(const Address & addr) : network(addr) { }
    00582
    00584         Address GetNetwork() const { return network; }
    00585
    00587         Address GetNetMask() const { return net_mask; }
    00588
    00590         Address GetDestination() const { return destination; }
    00591
    00593         const PString & GetInterface() const { return interfaceName; }
    00594
    00596         long GetMetric() const { return metric; }
    00597
    00598       protected:
    00599         Address network;
    00600         Address net_mask;
    00601         Address destination;
    00602         PString interfaceName;
    00603         long    metric;
    00604
    00605       friend class PIPSocket;
    00606     };
    00607
    00608     PARRAY(RouteTable, RouteEntry);
    00609
    00615     static PBoolean GetRouteTable(
    00616       RouteTable & table
    00617         );
    00618
    00620     class RouteTableDetector
    00621     {
    00622       public:
    00623         virtual ~RouteTableDetector() { }
    00624         virtual bool Wait(
    00625           const PTimeInterval & timeout
    00626         ) = 0;
    00627         virtual void Cancel() = 0;
    00628     };
    00629
    00638     static RouteTableDetector * CreateRouteTableDetector();
    00639
    00642     class InterfaceEntry : public PObject
    00643     {
    00644       PCLASSINFO(InterfaceEntry, PObject)
    00645
    00646       public:
    00648         InterfaceEntry();
    00649         InterfaceEntry(
    00650           const PString & name,
    00651           const Address & addr,
    00652           const Address & mask,
    00653           const PString & macAddr
    00654         );
    00655
    00657         virtual void PrintOn(
    00658           ostream &strm   // Stream to print the object into.
    00659         ) const;
    00660
    00669         const PString & GetName() const { return m_name; }
    00670
    00672         Address GetAddress() const { return m_ipAddress; }
    00673
    00675         Address GetNetMask() const { return m_netMask; }
    00676
    00678         const PString & GetMACAddress() const { return m_macAddress; }
    00679
    00681         static void SanitiseName(PString & name);
    00682
    00683       protected:
    00684         PString m_name;
    00685         Address m_ipAddress;
    00686         Address m_netMask;
    00687         PString m_macAddress;
    00688
    00689       friend class PIPSocket;
    00690     };
    00691
    00692     PARRAY(InterfaceTable, InterfaceEntry);
    00693
    00698     static PBoolean GetInterfaceTable(
    00699       InterfaceTable & table,
    00700       PBoolean includeDown = false
    00701     );
    00702
    00707     static PBoolean GetNetworkInterface(PIPSocket::Address & addr);
    00708
    00709 #if P_HAS_RECVMSG
    00710
    00715     PBoolean SetCaptureReceiveToAddress()
    00716     { if (!SetOption(IP_PKTINFO, 1, SOL_IP)) return false; catchReceiveToAddr = true; return true; }
    00717
    00720     PIPSocket::Address GetLastReceiveToAddress() const
    00721     { return lastReceiveToAddr; }
    00722
    00723   protected:
    00724     void SetLastReceiveAddr(void * addr, int addrLen)
    00725     { if (addrLen == sizeof(in_addr)) lastReceiveToAddr = *(in_addr *)addr; }
    00726
    00727     PIPSocket::Address lastReceiveToAddr;
    00728
    00729 #else
    00730
    00735     PBoolean SetCaptureReceiveToAddress()
    00736     { return false; }
    00737
    00740     PIPSocket::Address GetLastReceiveToAddress() const
    00741     { return PIPSocket::Address(); }
    00742
    00743 #endif
    00744
    00745 // Include platform dependent part of class
    00746 #ifdef _WIN32
    00747 #include "msos/ptlib/ipsock.h"
    00748 #else
    00749 #include "unix/ptlib/ipsock.h"
    00750 #endif
    00751 };
    00752
    00753 class PIPSocketAddressAndPort
    00754 {
    00755   public:
    00756     PIPSocketAddressAndPort()
    00757       : m_port(0), m_separator(':')
    00758       { }
    00759
    00760     PIPSocketAddressAndPort(char separator)
    00761       : m_port(0), m_separator(separator)
    00762       { }
    00763
    00764     PIPSocketAddressAndPort(const PString & str, WORD defaultPort = 0, char separator = ':')
    00765       : m_port(defaultPort), m_separator(separator)
    00766       { Parse(str, defaultPort, m_separator); }
    00767
    00768     PBoolean Parse(const PString & str, WORD defaultPort = 0, char separator = ':');
    00769
    00770     PString AsString(char separator = 0) const
    00771       { return m_address.AsString() + (separator ? separator : m_separator) + PString(PString::Unsigned, m_port); }
    00772
    00773     void SetAddress(
    00774       const PIPSocket::Address & addr,
    00775       WORD port = 0
    00776     );
    00777     const PIPSocket::Address & GetAddress() const { return m_address; }
    00778     WORD GetPort() const { return m_port; }
    00779     void SetPort(
    00780       WORD port
    00781     ) { m_port = port; }
    00782
    00783     bool IsValid() const { return m_address.IsValid() && m_port != 0; }
    00784
    00785     friend ostream & operator<<(ostream & strm, const PIPSocketAddressAndPort & ap)
    00786     {
    00787       return strm << ap.m_address << ap.m_separator << ap.m_port;
    00788     }
    00789
    00790   protected:
    00791     PIPSocket::Address m_address;
    00792     WORD               m_port;
    00793     char               m_separator;
    00794 };
    00795
    00796 typedef std::vector<PIPSocketAddressAndPort> PIPSocketAddressAndPortVector;
    00797
    00798
    00799 #endif // PTLIB_IPSOCKET_H
    00800
    00801
    00802 // End Of File ///////////////////////////////////////////////////////////////