4 * Internet Protocol socket I/O channel class.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
30 * Revision 1.65 2004/04/18 04:33:36 rjongbloed
31 * Changed all operators that return BOOL to return standard type bool. This is primarily
32 * for improved compatibility with std STL usage removing many warnings.
34 * Revision 1.64 2004/04/07 05:29:50 csoutheren
35 * Added function to detect RFC 1918 addresses
37 * Revision 1.63 2004/02/23 17:27:19 ykiryanov
38 * Added == and != operators for in_addr_t on BeOS as suggested by Craig Southeren to please compiler
40 * Revision 1.62 2003/09/17 05:41:58 csoutheren
41 * Removed recursive includes
43 * Revision 1.61 2003/09/17 01:18:02 csoutheren
44 * Removed recursive include file system and removed all references
45 * to deprecated coooperative threading support
47 * Revision 1.60 2003/05/21 09:34:43 rjongbloed
48 * Name lookup support for IPv6, thanks again Sébastien Josset
50 * Revision 1.59 2003/04/28 02:55:08 robertj
51 * Added function to see at run time if IPv6 available, thanks Sebastien Josset
53 * Revision 1.58 2003/04/03 08:43:23 robertj
54 * Added IPv4 mapping into IPv6, thanks Sebastien Josset
56 * Revision 1.57 2003/03/26 05:36:37 robertj
57 * More IPv6 support (INADDR_ANY handling), thanks Sébastien Josset
59 * Revision 1.56 2003/02/03 11:23:32 robertj
60 * Added function to get pointer to IP address data.
62 * Revision 1.55 2003/02/03 08:51:44 robertj
63 * Fixed compatibility with old code so taking address of PIPSocket::Address
64 * gets address of 4 or 16 byte IP address.
66 * Revision 1.54 2002/12/02 03:57:18 robertj
67 * More RTEMS support patches, thank you Vladimir Nesic.
69 * Revision 1.53 2002/11/02 00:32:21 robertj
70 * Further fixes to VxWorks (Tornado) port, thanks Andreas Sikkema.
72 * Revision 1.52 2002/10/29 07:59:45 robertj
73 * Changed in_addr6 to more universally used in6_addr.
75 * Revision 1.51 2002/10/08 14:31:43 robertj
76 * Changed for IPv6 support, thanks Sébastien Josset.
78 * Revision 1.50 2002/10/08 12:41:51 robertj
79 * Changed for IPv6 support, thanks Sébastien Josset.
81 * Revision 1.49 2002/09/16 01:08:59 robertj
82 * Added #define so can select if #pragma interface/implementation is used on
83 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
85 * Revision 1.48 2001/12/13 09:17:01 robertj
86 * Added function to convert PString to IP address with error checking that can
87 * distinguish between 0.0.0.0 or 255.255.255.255 and illegal address.
89 * Revision 1.47 2001/09/14 08:00:38 robertj
90 * Added new versions of Conenct() to allow binding to a specific local interface.
92 * Revision 1.46 2001/05/22 12:49:32 robertj
93 * Did some seriously wierd rewrite of platform headers to eliminate the
94 * stupid GNU compiler warning about braces not matching.
96 * Revision 1.45 2001/03/05 04:18:27 robertj
97 * Added net mask to interface info returned by GetInterfaceTable()
99 * Revision 1.44 2001/01/29 06:41:18 robertj
100 * Added printing of entry of interface table.
102 * Revision 1.43 2000/06/26 11:17:19 robertj
103 * Nucleus++ port (incomplete).
105 * Revision 1.42 1999/09/10 04:35:42 robertj
106 * Added Windows version of PIPSocket::GetInterfaceTable() function.
108 * Revision 1.41 1999/09/10 02:31:42 craigs
109 * Added interface table routines
111 * Revision 1.40 1999/08/30 02:21:03 robertj
112 * Added ability to listen to specific interfaces for IP sockets.
114 * Revision 1.39 1999/08/08 09:04:01 robertj
115 * Added operator>> for PIPSocket::Address class.
117 * Revision 1.38 1999/03/09 02:59:50 robertj
118 * Changed comments to doc++ compatible documentation.
120 * Revision 1.37 1999/02/23 07:19:22 robertj
121 * Added [] operator PIPSocket::Address to get the bytes out of an IP address.
123 * Revision 1.36 1999/02/16 08:12:00 robertj
124 * MSVC 6.0 compatibility changes.
126 * Revision 1.35 1998/12/21 07:22:50 robertj
127 * Virtualised functions for SOCKS support.
129 * Revision 1.34 1998/12/18 04:34:14 robertj
130 * PPC Linux GNU C compatibility.
132 * Revision 1.33 1998/11/30 08:57:32 robertj
133 * New directory structure
135 * Revision 1.32 1998/11/22 11:30:08 robertj
136 * Check route table function to get a list
138 * Revision 1.31 1998/11/19 05:18:22 robertj
139 * Added route table manipulation functions to PIPSocket class.
141 * Revision 1.30 1998/09/23 06:20:45 robertj
142 * Added open source copyright license.
144 * Revision 1.29 1997/12/11 10:28:57 robertj
145 * Added operators for IP address to DWORD conversions.
147 * Revision 1.28 1996/12/17 11:08:05 robertj
148 * Added DNS name cache clear command.
150 * Revision 1.27 1996/11/30 12:10:00 robertj
151 * Added Connect() variant so can set the local port number on link.
153 * Revision 1.26 1996/11/16 10:48:49 robertj
154 * Fixed missing const in PIPSocket::Address stream output operator..
156 * Revision 1.25 1996/11/04 03:40:54 robertj
157 * Moved address printer from inline to source.
159 * Revision 1.24 1996/09/14 13:09:21 robertj
161 * rearranged sockets to help support IPX.
162 * added indirect channel class and moved all protocols to descend from it,
163 * separating the protocol from the low level byte transport.
165 * Revision 1.23 1996/08/25 09:33:55 robertj
166 * Added function to detect "local" host name.
168 * Revision 1.22 1996/03/26 00:51:13 robertj
169 * Added GetLocalAddress() variant that returns port number as well.
171 * Revision 1.21 1996/03/16 04:41:30 robertj
172 * Changed all the get host name and get host address functions to be more consistent.
174 * Revision 1.20 1996/03/03 07:37:56 robertj
175 * Added Reusability clause to the Listen() function on sockets.
177 * Revision 1.19 1996/02/25 03:00:31 robertj
178 * Added operator<< to PIPSocket::Address.
179 * Moved some socket functions to platform dependent code.
181 * Revision 1.18 1996/02/08 12:11:19 robertj
182 * Added GetPeerAddress that returns a port.
184 * Revision 1.17 1996/01/28 14:07:31 robertj
185 * Changed service parameter to PString for ease of use in GetPortByService function
188 * Revision 1.16 1995/12/23 03:44:59 robertj
189 * Fixed unix portability issues.
191 * Revision 1.15 1995/12/10 11:32:11 robertj
192 * Numerous fixes for sockets.
194 * Revision 1.14 1995/10/14 14:57:26 robertj
195 * Added internet address to string conversion functionality.
197 * Revision 1.13 1995/07/02 01:18:19 robertj
198 * Added static functions to get the current host name/address.
200 * Revision 1.12 1995/06/17 00:41:40 robertj
201 * More logical design of port numbers and service names.
203 * Revision 1.11 1995/03/18 06:26:44 robertj
204 * Changed IP address variable for GNU compatibility.
206 * Revision 1.10 1995/03/14 12:41:38 robertj
207 * Updated documentation to use HTML codes.
209 * Revision 1.9 1995/03/12 04:38:41 robertj
210 * Added more functionality.
212 * Revision 1.8 1995/01/02 12:28:24 robertj
214 * Added more socket functions.
216 * Revision 1.7 1995/01/01 01:07:33 robertj
217 * More implementation.
219 * Revision 1.6 1994/12/15 12:47:14 robertj
222 * Revision 1.5 1994/08/23 11:32:52 robertj
225 * Revision 1.4 1994/08/22 00:46:48 robertj
226 * Added pragma fro GNU C++ compiler.
228 * Revision 1.3 1994/08/21 23:43:02 robertj
229 * Spelt Berkeley correctly.
231 * Revision 1.2 1994/07/25 03:36:03 robertj
232 * Added sockets to common, normalising to same comment standard.
243 #include <ptlib/socket.h>
245 /** This class describes a type of socket that will communicate using the
247 If P_USE_IPV6 is not set, IPv4 only is supported.
248 If P_USE_IPV6 is set, both IPv4 and IPv6 adresses are supported, with
249 IPv4 as default. This allows to transparently use IPv4, IPv6 or Dual
250 stack operating systems.
252 class PIPSocket
: public PSocket
254 PCLASSINFO(PIPSocket
, PSocket
);
256 /* Create a new Internet Protocol socket based on the port number
263 A class describing an IP address
265 class Address
: public PObject
{
268 /**@name Address constructors */
270 /// Create an IPv4 address with the default address: 127.0.0.1 (loopback)
273 /** Create an IP address from string notation.
274 eg dot notation x.x.x.x. for IPv4, or colon notation x:x:x::xxx for IPv6
276 Address(const PString
& dotNotation
);
278 /// Create an IPv4 or IPv6 address from 4 or 16 byte values
279 Address(PINDEX len
, const BYTE
* bytes
);
281 /// Create an IP address from four byte values
282 Address(BYTE b1
, BYTE b2
, BYTE b3
, BYTE b4
);
284 /// Create an IPv4 address from a four byte value in network byte order
287 /// Create an IPv4 address from an in_addr structure
288 Address(const in_addr
& addr
);
291 /// Create an IPv6 address from an in_addr structure
292 Address(const in6_addr
& addr
);
294 /// Create an IP (v4 or v6) address from a sockaddr (sockaddr_in,
295 /// sockaddr_in6 or sockaddr_in6_old) structure
296 Address(const int ai_family
, const int ai_addrlen
,struct sockaddr
*ai_addr
);
299 #ifdef __NUCLEUS_NET__
300 Address(const struct id_struct
& addr
);
301 Address
& operator=(const struct id_struct
& addr
);
304 /// Copy an address from another IP v4 address
305 Address
& operator=(const in_addr
& addr
);
308 /// Copy an address from another IPv6 address
309 Address
& operator=(const in6_addr
& addr
);
312 /// Copy an address from a string
313 Address
& operator=(const PString
& dotNotation
);
315 /// Copy an address from a four byte value in network order
316 Address
& operator=(DWORD dw
);
319 /// Compare two adresses
320 Comparison
Compare(const PObject
& obj
) const;
321 bool operator==(const Address
& addr
) const { return Compare(addr
) == EqualTo
; }
322 bool operator!=(const Address
& addr
) const { return Compare(addr
) != EqualTo
; }
324 bool operator==(in6_addr
& addr
) const;
325 bool operator!=(in6_addr
& addr
) const { return !operator==(addr
); }
327 bool operator==(in_addr
& addr
) const;
328 bool operator!=(in_addr
& addr
) const { return !operator==(addr
); }
329 bool operator==(DWORD dw
) const;
330 bool operator!=(DWORD dw
) const { return !operator==(dw
); }
332 bool operator==(long unsigned int u
) const { return operator==((DWORD
)u
); }
333 bool operator!=(long unsigned int u
) const { return !operator==((DWORD
)u
); }
336 bool operator==(unsigned u
) const { return operator==((DWORD
)u
); }
337 bool operator!=(unsigned u
) const { return !operator==((DWORD
)u
); }
340 bool operator==(u_long u
) const { return operator==((DWORD
)u
); }
341 bool operator!=(u_long u
) const { return !operator==((DWORD
)u
); }
344 bool operator==(in_addr_t a
) const { return operator==((DWORD
)a
); }
345 bool operator!=(in_addr_t a
) const { return !operator==((DWORD
)a
); }
347 bool operator==(int i
) const { return operator==((DWORD
)i
); }
348 bool operator!=(int i
) const { return !operator==((DWORD
)i
); }
350 /// Format an address as a string
351 PString
AsString() const;
353 /// Convert string to IP address. Returns TRUE if was a valid address.
358 /// Format an address as a string
359 operator PString() const;
361 /// Return IPv4 address in network order
362 operator in_addr() const;
365 /// Return IPv4 address in network order
366 operator in6_addr() const;
369 /// Return IPv4 address in network order
370 operator DWORD() const;
372 /// Return first byte of IPv4 address
375 /// Return second byte of IPv4 address
378 /// Return third byte of IPv4 address
381 /// Return fourth byte of IPv4 address
384 /// return specified byte of IPv4 or IPv6 address
385 BYTE
operator[](PINDEX idx
) const;
387 /// Get the address length (will be either 4 or 16)
388 PINDEX
GetSize() const;
390 /// Get the pointer to IP address data
391 const char * GetPointer() const { return (const char *)&v
; }
393 /// Get the version of the IP address being used
394 unsigned GetVersion() const { return version
; }
396 /// Check address 0.0.0.0 or ::
397 BOOL
IsValid() const;
400 /// Check address 127.0.0.1 or ::1
401 BOOL
IsLoopback() const;
403 /// Check for Broadcast address 255.255.255.255
404 BOOL
IsBroadcast() const;
406 // Check if the remote address is private address as specified
407 // by RFC 1918 address
408 // 10.0.0.0 - 10.255.255.255.255
409 // 172.16.0.0 - 172.31.255.255
410 // 192.168.0.0 - 192.168.255.255
411 BOOL
IsRFC1918() const
412 { return (Byte1() == 10)
417 (Byte2() >= 16) && (Byte2() <= 31)
428 /// Check for v4 mapped i nv6 address ::ffff:a.b.c.d
429 BOOL
IsV4Mapped() const;
432 static const Address
& GetLoopback();
434 static const Address
& GetLoopback6();
435 static const Address
& GetAny6();
437 static const Address
& GetBroadcast();
440 /// Runtime test of IP addresse type
449 /// output IPv6 & IPv4 address as a string to the specified string
450 friend ostream
& operator<<(ostream
& s
, const Address
& a
);
452 /// input IPv4 (not IPv6 yet!) address as a string from the specified string
453 friend istream
& operator>>(istream
& s
, Address
& a
);
456 // Overrides from class PChannel
457 /** Get the platform and I/O channel type name of the channel. For an IP
458 socket this returns the host name of the peer the socket is connected
459 to, followed by the socket number it is connected to.
462 the name of the channel.
464 virtual PString
GetName() const;
466 // Set the default IP address familly.
467 // Needed as lot of IPv6 stack are not able to receive IPv4 packets in IPv6 sockets
468 // They are not RFC 2553, chapter 7.3, compliant.
469 // As a concequence, when opening a socket to listen to port 1720 (for exemple) from any remot host
470 // one must decide whether this an IPv4 or an IPv6 socket...
471 static int GetDefaultIpAddressFamily();
472 static void SetDefaultIpAddressFamily(int ipAdressFamily
); // PF_INET, PF_INET6
473 static void SetDefaultIpAddressFamilyV4(); // PF_INET
475 static void SetDefaultIpAddressFamilyV6(); // PF_INET6
476 static BOOL
IsIpAddressFamilyV6Supported();
478 static PIPSocket::Address
GetDefaultIpAny();
480 // Open an IPv4 or IPv6 socket
481 virtual BOOL
OpenSocket(
482 int ipAdressFamily
=PF_INET
486 // Overrides from class PSocket.
487 /** Connect a socket to a remote host on the specified port number. This is
488 typically used by the client or initiator of a communications channel.
489 This connects to a "listening" socket at the other end of the
490 communications channel.
492 The port number as defined by the object instance construction or the
493 #PIPSocket::SetPort()# function.
496 TRUE if the channel was successfully connected to the remote host.
498 virtual BOOL
Connect(
499 const PString
& address
/// Address of remote machine to connect to.
501 virtual BOOL
Connect(
502 const Address
& addr
/// Address of remote machine to connect to.
504 virtual BOOL
Connect(
505 WORD localPort
, /// Local port number for connection
506 const Address
& addr
/// Address of remote machine to connect to.
508 virtual BOOL
Connect(
509 const Address
& iface
, /// Address of local interface to us.
510 const Address
& addr
/// Address of remote machine to connect to.
512 virtual BOOL
Connect(
513 const Address
& iface
, /// Address of local interface to us.
514 WORD localPort
, /// Local port number for connection
515 const Address
& addr
/// Address of remote machine to connect to.
518 /** Listen on a socket for a remote host on the specified port number. This
519 may be used for server based applications. A "connecting" socket begins
520 a connection by initiating a connection to this socket. An active socket
521 of this type is then used to generate other "accepting" sockets which
522 establish a two way communications channel with the "connecting" socket.
524 If the #port# parameter is zero then the port number as
525 defined by the object instance construction or the
526 #PIPSocket::SetPort()# function.
528 For the UDP protocol, the #queueSize# parameter is ignored.
531 TRUE if the channel was successfully opened.
534 unsigned queueSize
= 5, /// Number of pending accepts that may be queued.
535 WORD port
= 0, /// Port number to use for the connection.
536 Reusability reuse
= AddressIsExclusive
/// Can/Cant listen more than once.
539 const Address
& bind
, /// Local interface address to bind to.
540 unsigned queueSize
= 5, /// Number of pending accepts that may be queued.
541 WORD port
= 0, /// Port number to use for the connection.
542 Reusability reuse
= AddressIsExclusive
/// Can/Can't listen more than once.
546 // New functions for class
547 /** Get the "official" host name for the host specified or if none, the host
548 this process is running on. The host may be specified as an IP number
549 or a hostname alias and is resolved to the canonical form.
552 Name of the host or IP number of host.
554 static PString
GetHostName();
555 static PString
GetHostName(
556 const PString
& hostname
/// Hosts IP address to get name for
558 static PString
GetHostName(
559 const Address
& addr
/// Hosts IP address to get name for
562 /** Get the Internet Protocol address for the specified host, or if none
563 specified, for the host this process is running on.
566 TRUE if the IP number was returned.
568 static BOOL
GetHostAddress(
569 Address
& addr
/// Variable to receive hosts IP address
571 static BOOL
GetHostAddress(
572 const PString
& hostname
,
573 /* Name of host to get address for. This may be either a domain name or
574 an IP number in "dot" format.
576 Address
& addr
/// Variable to receive hosts IP address
579 /** Get the alias host names for the specified host. This includes all DNS
580 names, CNAMEs, names in the local hosts file and IP numbers (as "dot"
581 format strings) for the host.
584 array of strings for each alias for the host.
586 static PStringArray
GetHostAliases(
587 const PString
& hostname
588 /* Name of host to get address for. This may be either a domain name or
589 an IP number in "dot" format.
592 static PStringArray
GetHostAliases(
593 const Address
& addr
/// Hosts IP address
594 /* Name of host to get address for. This may be either a domain name or
595 an IP number in "dot" format.
599 /** Determine if the specified host is actually the local machine. This
600 can be any of the host aliases or multi-homed IP numbers or even
601 the special number 127.0.0.1 for the loopback device.
604 TRUE if the host is the local machine.
606 static BOOL
IsLocalHost(
607 const PString
& hostname
608 /* Name of host to get address for. This may be either a domain name or
609 an IP number in "dot" format.
613 /** Get the Internet Protocol address for the local host.
616 TRUE if the IP number was returned.
618 virtual BOOL
GetLocalAddress(
619 Address
& addr
/// Variable to receive hosts IP address
621 virtual BOOL
GetLocalAddress(
622 Address
& addr
, /// Variable to receive peer hosts IP address
623 WORD
& port
/// Variable to receive peer hosts port number
626 /** Get the Internet Protocol address for the peer host the socket is
630 TRUE if the IP number was returned.
632 virtual BOOL
GetPeerAddress(
633 Address
& addr
/// Variable to receive hosts IP address
635 virtual BOOL
GetPeerAddress(
636 Address
& addr
, /// Variable to receive peer hosts IP address
637 WORD
& port
/// Variable to receive peer hosts port number
640 /** Get the host name for the local host.
643 Name of the host, or an empty string if an error occurs.
645 PString
GetLocalHostName();
647 /** Get the host name for the peer host the socket is connected to.
650 Name of the host, or an empty string if an error occurs.
652 PString
GetPeerHostName();
654 /** Clear the name (DNS) cache.
656 static void ClearNameCache();
658 /** Get the IP address that is being used as the gateway, that is, the
659 computer that packets on the default route will be sent.
661 The string returned may be used in the Connect() function to open that
664 Note that the driver does not need to be open for this function to work.
667 TRUE if there was a gateway.
669 static BOOL
GetGatewayAddress(
670 Address
& addr
/// Variable to receive the IP address.
673 /** Get the name for the interface that is being used as the gateway,
674 that is, the interface that packets on the default route will be sent.
676 The string returned may be used in the Connect() function to open that
679 Note that the driver does not need to be open for this function to work.
683 String name of the gateway device, or empty string if there is none.
685 static PString
GetGatewayInterface();
688 Describes a route table entry
690 class RouteEntry
: public PObject
692 PCLASSINFO(RouteEntry
, PObject
);
694 /// create a route table entry from an IP address
695 RouteEntry(const Address
& addr
) : network(addr
) { }
697 /// Get the network address associated with the route table entry
698 Address
GetNetwork() const { return network
; }
700 /// Get the network address mask associated with the route table entry
701 Address
GetNetMask() const { return net_mask
; }
703 /// Get the default gateway address associated with the route table entry
704 Address
GetDestination() const { return destination
; }
706 /// Get the network address name associated with the route table entry
707 const PString
& GetInterface() const { return interfaceName
; }
709 /// Get the network metric associated with the route table entry
710 long GetMetric() const { return metric
; }
716 PString interfaceName
;
719 friend class PIPSocket
;
722 PLIST(RouteTable
, RouteEntry
);
724 /** Get the systems route table.
727 TRUE if the route table is returned, FALSE if an error occurs.
729 static BOOL
GetRouteTable(
730 RouteTable
& table
/// Route table
735 Describes an interface table entry
737 class InterfaceEntry
: public PObject
739 PCLASSINFO(InterfaceEntry
, PObject
)
742 /// create an interface entry from a name, IP addr and MAC addr
744 const PString
& _name
,
745 const Address
& _addr
,
746 const Address
& _mask
,
747 const PString
& _macAddr
750 /// Print to specified stream
751 virtual void PrintOn(
752 ostream
&strm
// Stream to print the object into.
755 /// Get the name of the interface
756 const PString
& GetName() const { return name
; }
758 /// Get the address associated with the interface
759 Address
GetAddress() const { return ipAddr
; }
761 /// Get the net mask associated with the interface
762 Address
GetNetMask() const { return netMask
; }
764 /// Get the MAC address associate with the interface
765 const PString
& GetMACAddress() const { return macAddr
; }
774 PLIST(InterfaceTable
, InterfaceEntry
);
776 /** Get a list of all interfaces
779 TRUE if the interface table is returned, FALSE if an error occurs.
781 static BOOL
GetInterfaceTable(
782 InterfaceTable
& table
/// interface table
786 // Include platform dependent part of class
788 #include "msos/ptlib/ipsock.h"
790 #include "unix/ptlib/ipsock.h"
797 // End Of File ///////////////////////////////////////////////////////////////