1 /* $NetBSD: bindresvport.c,v 1.25 2013/03/11 20:19:28 tron Exp $ */
4 * Copyright (c) 2010, Oracle America, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 * * Neither the name of the "Oracle America, Inc." nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 #if defined(LIBC_SCCS) && !defined(lint)
37 static char *sccsid
= "@(#)bindresvport.c 1.8 88/02/08 SMI";
38 static char *sccsid
= "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";
40 __RCSID("$NetBSD: bindresvport.c,v 1.25 2013/03/11 20:19:28 tron Exp $");
45 * Copyright (c) 1987 by Sun Microsystems, Inc.
48 #include "namespace.h"
50 #include <sys/types.h>
51 #include <sys/socket.h>
53 #include <netinet/in.h>
60 #include "svc_fdset.h"
63 __weak_alias(bindresvport
,_bindresvport
)
64 __weak_alias(bindresvport_sa
,_bindresvport_sa
)
68 * Bind a socket to a privileged IP port
71 bindresvport(int sd
, struct sockaddr_in
*brsin
)
73 return bindresvport_sa(sd
, (struct sockaddr
*)(void *)brsin
);
77 * Bind a socket to a privileged IP port
80 bindresvport_sa(int sd
, struct sockaddr
*sa
)
83 struct sockaddr_storage myaddr
;
84 struct sockaddr_in
*brsin
;
86 struct sockaddr_in6
*brsin6
;
88 int proto
, portrange
, portlow
;
94 salen
= sizeof(myaddr
);
95 sa
= (struct sockaddr
*)(void *)&myaddr
;
97 if (getsockname(sd
, sa
, &salen
) == -1)
98 return -1; /* errno is correctly set */
101 memset(sa
, 0, salen
);
108 portrange
= IP_PORTRANGE
;
109 portlow
= IP_PORTRANGE_LOW
;
110 brsin
= (struct sockaddr_in
*)(void *)sa
;
111 salen
= sizeof(struct sockaddr_in
);
112 portp
= &brsin
->sin_port
;
116 proto
= IPPROTO_IPV6
;
117 portrange
= IPV6_PORTRANGE
;
118 portlow
= IPV6_PORTRANGE_LOW
;
119 brsin6
= (struct sockaddr_in6
*)(void *)sa
;
120 salen
= sizeof(struct sockaddr_in6
);
121 portp
= &brsin6
->sin6_port
;
125 errno
= EPFNOSUPPORT
;
132 socklen_t oldlen
= sizeof(old
);
134 error
= getsockopt(sd
, proto
, portrange
, &old
, &oldlen
);
137 error
= setsockopt(sd
, proto
, portrange
, &portlow
,
138 (socklen_t
)sizeof(portlow
));
143 error
= bind(sd
, sa
, salen
);
146 int saved_errno
= errno
;
149 if (setsockopt(sd
, proto
, portrange
, &old
,
150 (socklen_t
)sizeof(old
)) < 0)
155 if (sa
!= (struct sockaddr
*)(void *)&myaddr
) {
156 /* What did the kernel assign? */
157 if (getsockname(sd
, sa
, &salen
) < 0)