]>
git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/ip++.h
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // ip++ - C++ layer for IP socket and address management
23 // HBO = host byte order, NBO = network byte order
25 // Rules for byte ordering: C++ objects store addresses and ports in NBO.
26 // Struct in_addr arguments are in NBO. Integer type arguments are in HBO.
27 // Stick with the conversion methods and you win. Cast around and you lose.
29 // @@@ Which namespace should we be in?
36 #include <sys/types.h>
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
45 using namespace UnixPlusPlus
;
49 namespace IPPlusPlus
{
55 // For now, ports are simply a short unsigned integer type, in HBO.
57 typedef uint16 IPPort
;
61 // An IP host address.
63 class IPAddress
: public in_addr
{
65 IPAddress() { s_addr
= htonl(INADDR_ANY
); }
66 IPAddress(const struct in_addr
&addr
) { s_addr
= addr
.s_addr
; }
67 explicit IPAddress(uint32 addr
) { s_addr
= htonl(addr
); }
68 IPAddress(const char *s
); // ONLY dotted-quad form - use hosts.h for name resolution
70 operator uint32 () const { return ntohl(s_addr
); }
71 operator string () const; // "n.n.n.n" (no name resolution)
74 bool operator == (const IPAddress
&other
) const { return s_addr
== other
.s_addr
; }
75 bool operator != (const IPAddress
&other
) const { return s_addr
!= other
.s_addr
; }
76 bool operator < (const IPAddress
&other
) const { return s_addr
< other
.s_addr
; }
78 operator bool () const { return s_addr
!= htonl(INADDR_ANY
); }
79 bool operator ! () const { return s_addr
== htonl(INADDR_ANY
); }
82 static const IPAddress
&any
;
87 // An IP "socket address", i.e. a combined host address and port.
89 class IPSockAddress
: public sockaddr_in
{
92 IPSockAddress(const struct sockaddr_in
&sockaddr
) { *(sockaddr_in
*)this = sockaddr
; }
93 IPSockAddress(const IPAddress
&addr
, IPPort port
);
95 IPAddress
address() const { return sin_addr
; }
96 void address(IPAddress addr
) { sin_addr
= addr
; }
97 IPPort
port() const { return ntohs(sin_port
); }
98 void port(IPPort p
) { sin_port
= htons(p
); }
100 operator string () const; // "n.n.n.n:p" (no name resolution)
102 // automatically convert to struct sockaddr * for use in system calls
103 operator struct sockaddr
* ()
104 { return reinterpret_cast<struct sockaddr
*>(this); }
105 operator const struct sockaddr
* () const
106 { return reinterpret_cast<const struct sockaddr
*>(this); }
109 IPSockAddress
defaults(const IPSockAddress
&defaultAddr
) const;
110 IPSockAddress
defaults(const IPAddress
&defaultAddr
, IPPort defaultPort
= 0) const;
111 IPSockAddress
defaults(IPPort defaultPort
) const;
117 // This inherits all functionality of a FileDesc, so I/O is fun and easy.
118 // Socket is "passive"; it doesn't own any resources and does nothing on destruction.
119 // On the upside, you can assign Sockets freely.
120 // If you want self-managing sockets that clean up after themselves,
121 // use the subclasses below.
123 class Socket
: public FileDesc
{
126 explicit Socket(int type
, int protocol
= 0);
128 Socket
&operator = (int fd
) { setFd(fd
); return *this; }
130 // basic open (socket system call)
131 void open(int type
, int protocol
= 0);
133 // standard socket operations
134 void bind(const IPSockAddress
&addr
); // to this socket address
135 void bind(const IPAddress
&addr
= IPAddress::any
, IPPort port
= 0);
136 void listen(int backlog
= 1);
137 void accept(Socket
&s
);
138 void accept(Socket
&s
, IPSockAddress
&peer
);
139 bool connect(const IPSockAddress
&peer
);
140 bool connect(const IPAddress
&addr
, IPPort port
);
141 void connect(const Host
&host
, IPPort port
); // any address of this host
142 void shutdown(int type
);
143 enum { shutdownRead
= 0, shutdownWrite
= 1, shutdownBoth
= 2 };
145 // get endpoint addresses
146 IPSockAddress
localAddress() const;
147 IPSockAddress
peerAddress() const;
150 void setOption(const void *value
, int length
, int name
, int level
= SOL_SOCKET
) const;
151 void getOption(void *value
, int &length
, int name
, int level
= SOL_SOCKET
) const;
153 template <class T
> void setOption(const T
&value
, int name
, int level
= SOL_SOCKET
) const
154 { setOption(&value
, sizeof(value
), name
, level
); }
156 template <class T
> T
getOption(int name
, int level
= SOL_SOCKET
) const
158 T value
; int length
= sizeof(value
);
159 getOption(&value
, length
, name
, level
);
160 assert(length
== sizeof(value
));
164 // some specific useful options
165 int type() const { return getOption
<int>(SO_TYPE
); }
166 int error() const { return getOption
<int>(SO_ERROR
); }
169 #if defined(SOMAXCONN)
170 static const int listenMaxQueue
= SOMAXCONN
;
172 static const int listenMaxQueue
= 5; // the traditional BSD UNIX value
176 void prepare(int fdFlags
, int type
, int protocol
= 0);
181 // A TCPClientSocket is a self-connecting TCP socket that connects (actively) to a server.
182 // Since TCP, once established, is symmetric, it can also be used for the server side
183 // of a TCP pipe. You can think of it as the least complex embodiment of a TCP connection.
185 class TCPClientSocket
: public Socket
{
186 NOCOPY(TCPClientSocket
)
188 TCPClientSocket() { }
189 ~TCPClientSocket(); // closes connection
192 void open(int type
, int protocol
= 0) { Socket::open(type
, protocol
); }
197 void open(const IPSockAddress
&peer
, int fdFlags
= 0);
198 void open(const IPAddress
&addr
, IPPort port
, int fdFlags
= 0);
199 void open(const Host
&host
, IPPort port
, int fdFlags
= 0);
201 TCPClientSocket(const IPSockAddress
&peer
, int fdFlags
= 0)
202 { open(peer
, fdFlags
); }
203 TCPClientSocket(const IPAddress
&addr
, IPPort port
, int fdFlags
= 0)
204 { open(addr
, port
, fdFlags
); }
205 TCPClientSocket(const Host
&host
, IPPort port
, int fdFlags
= 0)
206 { open(host
, port
, fdFlags
); }
208 protected: // for serverSocket/clientSocket footsy play
209 void setFd(int fd
) { Socket::setFd(fd
); }
212 TCPClientSocket(int sockfd
);
217 // A TCPServerSocket is a self-initializing listener socket for incoming TCP requests
218 // (usually to a server). Its function operator yields the next incoming connection request
219 // as a TCPClientSocket (see above). For one-shot receivers, the receive() method will
220 // create the client and close the listener atomically (which is sometimes faster).
222 class TCPServerSocket
: public Socket
{
223 NOCOPY(TCPServerSocket
)
225 TCPServerSocket() { }
226 ~TCPServerSocket(); // closes listener; existing connections unaffected
228 void open(const IPSockAddress
&local
, int depth
= 1);
229 void open(IPPort port
= 0, int depth
= 1)
230 { open(IPSockAddress(IPAddress::any
, port
), depth
); }
232 TCPServerSocket(const IPSockAddress
&local
, int depth
= 1) { open(local
, depth
); }
233 TCPServerSocket(IPPort port
, int depth
= 1) { open(port
, depth
); }
235 void operator () (TCPClientSocket
&newClient
); // retrieve next connection
236 void receive(TCPClientSocket
&client
); // accept once, then close listener
240 } // end namespace IPPlusPlus
241 } // end namespace Security
244 #endif //_H_IPPLUSPLUS