ReactOS  0.4.13-dev-101-g0ca4b50
bindresvport.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  * contributors may be used to endorse or promote products derived
14  * from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 //#include <sys/cdefs.h>
30 
31 /*
32  * Copyright (c) 1987 by Sun Microsystems, Inc.
33  *
34  * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
35  */
36 
37 #include <wintirpc.h>
38 #include <sys/types.h>
39 //#include <sys/socket.h>
40 
41 //#include <netinet/in.h>
42 
43 #include <errno.h>
44 #include <string.h>
45 //#include <unistd.h>
46 
47 #include <rpc/rpc.h>
48 
49 /*
50  * Bind a socket to a privileged IP port
51  */
52 int
54  SOCKET sd;
55  struct sockaddr_in *sin;
56 {
57  return bindresvport_sa(sd, (struct sockaddr *)sin);
58 }
59 
60 #ifdef __linux__
61 
62 #define STARTPORT 600
63 #define LOWPORT 512
64 #define ENDPORT (IPPORT_RESERVED - 1)
65 #define NPORTS (ENDPORT - STARTPORT + 1)
66 
67 int
69  int sd;
70  struct sockaddr *sa;
71 {
72  int res, af;
73  struct sockaddr_storage myaddr;
74  struct sockaddr_in *sin;
75 #ifdef INET6
76  struct sockaddr_in6 *sin6;
77 #endif
78  u_int16_t *portp;
79  static u_int16_t port;
80  static short startport = STARTPORT;
81  socklen_t salen;
82  int nports = ENDPORT - startport + 1;
83  int endport = ENDPORT;
84  int i;
85 
86  if (sa == NULL) {
87  salen = sizeof(myaddr);
88  sa = (struct sockaddr *)&myaddr;
89 
90  if (getsockname(sd, (struct sockaddr *)&myaddr, &salen) == -1)
91  return -1; /* errno is correctly set */
92 
93  af = myaddr.ss_family;
94  } else
95  af = sa->sa_family;
96 
97  switch (af) {
98  case AF_INET:
99  sin = (struct sockaddr_in *)sa;
100  salen = sizeof(struct sockaddr_in);
101  port = ntohs(sin->sin_port);
102  portp = &sin->sin_port;
103  break;
104 #ifdef INET6
105  case AF_INET6:
106  sin6 = (struct sockaddr_in6 *)sa;
107  salen = sizeof(struct sockaddr_in6);
108  port = ntohs(sin6->sin6_port);
109  portp = &sin6->sin6_port;
110  break;
111 #endif
112  default:
114  return (-1);
115  }
116  sa->sa_family = af;
117 
118  if (port == 0) {
119  port = (getpid() % NPORTS) + STARTPORT;
120  }
121  res = -1;
122  errno = EADDRINUSE;
123  again:
124  for (i = 0; i < nports; ++i) {
125  *portp = htons(port++);
126  if (port > endport)
127  port = startport;
128  res = bind(sd, sa, salen);
129  if (res >= 0 || errno != EADDRINUSE)
130  break;
131  }
132  if (i == nports && startport != LOWPORT) {
133  startport = LOWPORT;
134  endport = STARTPORT - 1;
135  nports = STARTPORT - LOWPORT;
136  port = LOWPORT + port % (STARTPORT - LOWPORT);
137  goto again;
138  }
139  return (res);
140 }
141 
142 #else
143 /*----------------------
144 #if defined(_WIN32)
145 
146 int
147 bindresvport_sa(SOCKET sd, struct sockaddr *sa)
148 {
149  fprintf(stderr, "Do-nothing bindresvport_sa!\n");
150  return 0;
151 }
152 #else
153 -------------------------*/
154 #define IP_PORTRANGE 19
155 #define IP_PORTRANGE_LOW 2
156 
157 /*
158  * Bind a socket to a privileged IP port
159  */
160 int
162  SOCKET sd;
163  struct sockaddr *sa;
164 {
165 #ifdef IPV6_PORTRANGE
166  int old;
167 #endif
168  int error, af;
169  struct sockaddr_storage myaddr;
170  struct sockaddr_in *sin;
171 #ifdef INET6
172  struct sockaddr_in6 *sin6;
173 #endif
174  int proto, portrange, portlow;
175  u_int16_t *portp;
176  socklen_t salen;
177 #ifdef _WIN32
178  WSAPROTOCOL_INFO proto_info;
179  int proto_info_size = sizeof(proto_info);
180 #endif
181 
182  if (sa == NULL) {
183  salen = sizeof(myaddr);
184  sa = (struct sockaddr *)&myaddr;
185 
186 #ifdef _WIN32
187  memset(sa, 0, salen);
188  if (error = getsockopt(sd, SOL_SOCKET, SO_PROTOCOL_INFO, (char *)&proto_info, &proto_info_size) == SOCKET_ERROR) {
189 #ifndef __REACTOS__
190  int sockerr = WSAGetLastError();
191 #endif
192  return -1;
193  }
194  af = proto_info.iAddressFamily;
195 #else
196  if (getsockname(sd, sa, &salen) == -1)
197  return -1; /* errno is correctly set */
198 
199  af = sa->sa_family;
200  memset(sa, 0, salen);
201 #endif
202  } else
203  af = sa->sa_family;
204 
205  switch (af) {
206  case AF_INET:
207  proto = IPPROTO_IP;
208  portrange = IP_PORTRANGE;
209  portlow = IP_PORTRANGE_LOW;
210  sin = (struct sockaddr_in *)sa;
211  salen = sizeof(struct sockaddr_in);
212  portp = &sin->sin_port;
213  break;
214 #ifdef INET6
215  case AF_INET6:
216  proto = IPPROTO_IPV6;
217 #ifdef IPV6_PORTRANGE
218  portrange = IPV6_PORTRANGE;
219  portlow = IPV6_PORTRANGE_LOW;
220 #endif
221  sin6 = (struct sockaddr_in6 *)sa;
222  salen = sizeof(struct sockaddr_in6);
223  portp = &sin6->sin6_port;
224  break;
225 #endif /* INET6 */
226  default:
228  return (-1);
229  }
230  sa->sa_family = (ADDRESS_FAMILY) af;
231 
232 #ifdef IPV6_PORTRANGE
233  if (*portp == 0) {
234  socklen_t oldlen = sizeof(old);
235 
236  error = getsockopt(sd, proto, portrange, &old, &oldlen);
237  if (error < 0)
238  return (error);
239 
240  error = setsockopt(sd, proto, portrange, &portlow,
241  sizeof(portlow));
242  if (error < 0)
243  return (error);
244  }
245 #endif
246 
247  error = bind(sd, sa, salen);
248  if (error) {
249 #ifndef __REACTOS__
250  int err = WSAGetLastError();
251 #endif
252  }
253 
254 #ifdef IPV6_PORTRANGE
255  if (*portp == 0) {
256  int saved_errno = errno;
257 
258  if (error < 0) {
259  if (setsockopt(sd, proto, portrange, &old,
260  sizeof(old)) < 0)
261  errno = saved_errno;
262  return (error);
263  }
264 
265  if (sa != (struct sockaddr *)&myaddr) {
266  /* Hmm, what did the kernel assign? */
267  if (getsockname(sd, sa, &salen) < 0)
268  errno = saved_errno;
269  return (error);
270  }
271  }
272 #endif
273  return (error);
274 }
275 /*
276 #endif
277 */
278 #endif
#define SOCKET_ERROR
Definition: winsock.h:333
#define error(str)
Definition: mkdosfs.c:1605
USHORT sin6_port
Definition: ws2ipdef.h:180
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define WSAEPFNOSUPPORT
Definition: winerror.h:1959
int errno
#define SOL_SOCKET
Definition: winsock.h:398
#define ntohs(x)
Definition: module.h:208
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
int bindresvport(SOCKET sd, struct sockaddr_in *sin)
Definition: bindresvport.c:53
smooth NULL
Definition: ftsmooth.c:416
#define AF_INET6
Definition: winsock.h:369
#define IPPROTO_IP
Definition: winsock.h:255
_CRTIMP int __cdecl getpid(void)
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define IP_PORTRANGE
Definition: bindresvport.c:154
int socklen_t
Definition: tcp.c:35
#define SO_PROTOCOL_INFO
Definition: winsock2.h:253
USHORT ADDRESS_FAMILY
Definition: ws2def.h:25
unsigned short u_int16_t
Definition: rosdhcp.h:34
static const WCHAR sd[]
Definition: suminfo.c:287
#define EPFNOSUPPORT
Definition: errno.h:106
#define err(...)
#define EADDRINUSE
Definition: errno.h:109
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
#define IP_PORTRANGE_LOW
Definition: bindresvport.c:155
GLuint res
Definition: glext.h:9613
#define AF_INET
Definition: tcpip.h:117
UINT_PTR SOCKET
Definition: winsock.h:47
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
#define htons(x)
Definition: module.h:213
int bindresvport_sa(SOCKET sd, struct sockaddr *sa)
Definition: bindresvport.c:161
USHORT port
Definition: uri.c:227
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
static struct sockaddr_in sa
Definition: adnsresfilter.c:69