00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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 #endif
00243
00244 static const Address & GetLoopback(int version = 4);
00245 static const Address & GetAny(int version = 4);
00246 static const Address GetBroadcast(int version = 4);
00247
00248 protected:
00250 union {
00251 in_addr four;
00252 #if P_HAS_IPV6
00253 in6_addr six;
00254 #endif
00255 } v;
00256 unsigned version;
00257
00259 friend ostream & operator<<(ostream & s, const Address & a);
00260
00262 friend istream & operator>>(istream & s, Address & a);
00263 };
00264
00265
00267
00274 virtual PString GetName() const;
00275
00282 static int GetDefaultIpAddressFamily();
00283 static void SetDefaultIpAddressFamily(int ipAdressFamily);
00284 static void SetDefaultIpAddressFamilyV4();
00285 #if P_HAS_IPV6
00286 static void SetDefaultIpAddressFamilyV6();
00287 static PBoolean IsIpAddressFamilyV6Supported();
00288
00289 static void SetDefaultV6ScopeId(int scopeId);
00290 static int GetDefaultV6ScopeId();
00291 #endif
00292 static PIPSocket::Address GetDefaultIpAny();
00293
00296 virtual PBoolean OpenSocket(
00297 int ipAdressFamily=PF_INET
00298 ) = 0;
00300
00314 virtual PBoolean Connect(
00315 const PString & address
00316 );
00317 virtual PBoolean Connect(
00318 const Address & addr
00319 );
00320 virtual PBoolean Connect(
00321 WORD localPort,
00322 const Address & addr
00323 );
00324 virtual PBoolean Connect(
00325 const Address & iface,
00326 const Address & addr
00327 );
00328 virtual PBoolean Connect(
00329 const Address & iface,
00330 WORD localPort,
00331 const Address & addr
00332 );
00333
00349 virtual PBoolean Listen(
00350 unsigned queueSize = 5,
00351 WORD port = 0,
00352 Reusability reuse = AddressIsExclusive
00353 );
00354 virtual PBoolean Listen(
00355 const Address & bind,
00356 unsigned queueSize = 5,
00357 WORD port = 0,
00358 Reusability reuse = AddressIsExclusive
00359 );
00361
00371 static PString GetHostName();
00372 static PString GetHostName(
00373 const PString & hostname
00374 );
00375 static PString GetHostName(
00376 const Address & addr
00377 );
00378
00385 static PBoolean GetHostAddress(
00386 Address & addr
00387 );
00388 static PBoolean GetHostAddress(
00389 const PString & hostname,
00393 Address & addr
00394 );
00395
00403 static PStringArray GetHostAliases(
00407 const PString & hostname
00408 );
00409 static PStringArray GetHostAliases(
00410 const Address & addr
00411
00412
00413
00414 );
00415
00423 static PBoolean IsLocalHost(
00427 const PString & hostname
00428 );
00429
00435 virtual PString GetLocalAddress();
00436 virtual PBoolean GetLocalAddress(
00437 Address & addr
00438 );
00439 virtual PBoolean GetLocalAddress(
00440 PIPSocketAddressAndPort & addr
00441 );
00442 virtual PBoolean GetLocalAddress(
00443 Address & addr,
00444 WORD & port
00445 );
00446
00453 virtual PString GetPeerAddress();
00454 virtual PBoolean GetPeerAddress(
00455 Address & addr
00456 );
00457 virtual PBoolean GetPeerAddress(
00458 PIPSocketAddressAndPort & addr
00459 );
00460 virtual PBoolean GetPeerAddress(
00461 Address & addr,
00462 WORD & port
00463 );
00464
00470 PString GetLocalHostName();
00471
00477 PString GetPeerHostName();
00478
00481 static void ClearNameCache();
00482
00494 static PBoolean GetGatewayAddress(
00495 Address & addr,
00496 int version = 4
00497 );
00498
00510 static PString GetGatewayInterface(int version = 4);
00511
00519 static PIPSocket::Address GetRouteInterfaceAddress(PIPSocket::Address remoteAddress);
00520
00521 #ifdef _WIN32
00522
00533 static PIPSocket::Address GetGatewayInterfaceAddress(int version = 4);
00534
00538 static PIPSocket::Address GetRouteAddress(PIPSocket::Address RemoteAddress);
00539
00542 static unsigned AsNumeric(Address addr);
00543
00546 static PBoolean IsAddressReachable(PIPSocket::Address LocalIP,
00547 PIPSocket::Address LocalMask,
00548 PIPSocket::Address RemoteIP);
00549
00552 static PString GetInterface(PIPSocket::Address addr);
00554 #endif
00555
00557 class RouteEntry : public PObject
00558 {
00559 PCLASSINFO(RouteEntry, PObject);
00560 public:
00562 RouteEntry(const Address & addr) : network(addr) { }
00563
00565 Address GetNetwork() const { return network; }
00566
00568 Address GetNetMask() const { return net_mask; }
00569
00571 Address GetDestination() const { return destination; }
00572
00574 const PString & GetInterface() const { return interfaceName; }
00575
00577 long GetMetric() const { return metric; }
00578
00579 protected:
00580 Address network;
00581 Address net_mask;
00582 Address destination;
00583 PString interfaceName;
00584 long metric;
00585
00586 friend class PIPSocket;
00587 };
00588
00589 PARRAY(RouteTable, RouteEntry);
00590
00596 static PBoolean GetRouteTable(
00597 RouteTable & table
00598 );
00599
00601 class RouteTableDetector
00602 {
00603 public:
00604 virtual ~RouteTableDetector() { }
00605 virtual bool Wait(
00606 const PTimeInterval & timeout
00607 ) = 0;
00608 virtual void Cancel() = 0;
00609 };
00610
00619 static RouteTableDetector * CreateRouteTableDetector();
00620
00623 class InterfaceEntry : public PObject
00624 {
00625 PCLASSINFO(InterfaceEntry, PObject)
00626
00627 public:
00629 InterfaceEntry();
00630 InterfaceEntry(
00631 const PString & name,
00632 const Address & addr,
00633 const Address & mask,
00634 const PString & macAddr
00635 #if P_HAS_IPV6
00636 , const PString & ip6Addr = PString::Empty()
00637 #endif
00638 );
00639
00641 virtual void PrintOn(
00642 ostream &strm
00643 ) const;
00644
00646 const PString & GetName() const { return name; }
00647
00649 Address GetAddress() const { return ipAddr; }
00650
00651 PBoolean HasIP6Address() const
00652 #if ! P_HAS_IPV6
00653 { return false;}
00654 #else
00655 { return !ip6Addr.IsEmpty();}
00656
00658 Address GetIP6Address() const { return ip6Addr; }
00659 #endif
00660
00662 Address GetNetMask() const { return netMask; }
00663
00665 const PString & GetMACAddress() const { return macAddr; }
00666
00667 protected:
00668 PString name;
00669 Address ipAddr;
00670 Address netMask;
00671 PString macAddr;
00672 #if P_HAS_IPV6
00673 PString ip6Addr;
00674 #endif
00675 };
00676
00677 PARRAY(InterfaceTable, InterfaceEntry);
00678
00683 static PBoolean GetInterfaceTable(
00684 InterfaceTable & table,
00685 PBoolean includeDown = false
00686 );
00687
00692 static PBoolean GetNetworkInterface(PIPSocket::Address & addr);
00693
00694 #if P_HAS_RECVMSG
00695
00700 PBoolean SetCaptureReceiveToAddress()
00701 { if (!SetOption(IP_PKTINFO, 1, SOL_IP)) return false; catchReceiveToAddr = true; return true; }
00702
00705 PIPSocket::Address GetLastReceiveToAddress() const
00706 { return lastReceiveToAddr; }
00707
00708 protected:
00709 void SetLastReceiveAddr(void * addr, int addrLen)
00710 { if (addrLen == sizeof(in_addr)) lastReceiveToAddr = *(in_addr *)addr; }
00711
00712 PIPSocket::Address lastReceiveToAddr;
00713
00714 #else
00715
00720 PBoolean SetCaptureReceiveToAddress()
00721 { return false; }
00722
00725 PIPSocket::Address GetLastReceiveToAddress() const
00726 { return PIPSocket::Address(); }
00727
00728 #endif
00729
00730
00731 #ifdef _WIN32
00732 #include "msos/ptlib/ipsock.h"
00733 #else
00734 #include "unix/ptlib/ipsock.h"
00735 #endif
00736 };
00737
00738 class PIPSocketAddressAndPort
00739 {
00740 public:
00741 PIPSocketAddressAndPort()
00742 : m_port(0), m_separator(':')
00743 { }
00744
00745 PIPSocketAddressAndPort(char separator)
00746 : m_port(0), m_separator(separator)
00747 { }
00748
00749 PIPSocketAddressAndPort(const PString & str, WORD defaultPort = 0, char separator = ':')
00750 : m_port(defaultPort), m_separator(separator)
00751 { Parse(str, defaultPort, m_separator); }
00752
00753 PBoolean Parse(const PString & str, WORD defaultPort = 0, char separator = ':');
00754
00755 PString AsString(char separator = 0) const
00756 { return m_address.AsString() + (separator ? separator : m_separator) + PString(PString::Unsigned, m_port); }
00757
00758 void SetAddress(
00759 const PIPSocket::Address & addr,
00760 WORD port = 0
00761 );
00762 const PIPSocket::Address & GetAddress() const { return m_address; }
00763 WORD GetPort() const { return m_port; }
00764 void SetPort(
00765 WORD port
00766 ) { m_port = port; }
00767
00768 protected:
00769 PIPSocket::Address m_address;
00770 WORD m_port;
00771 char m_separator;
00772 };
00773
00774 typedef std::vector<PIPSocketAddressAndPort> PIPSocketAddressAndPortVector;
00775
00776
00777 #endif // PTLIB_IPSOCKET_H
00778
00779
00780